• Vue学习之基础大全


    1 导入vue:
    2     <script src="vue.min.js"></script>
    3 创建vm实例
    4 var vm=new Vue({
    5         el:'#app',//指定要控制的元素
    6         data:{},
    7         methods:{}
    8 })
    9 在id为app的div里

    一、指令学习

    1.v-cloak、v-text、v-bind、v-html、v-on

     1 <div id="app">
     2     <h2>1.v-cloak、-text、-bind、-HTML、-on指令</h2>
     3     <p>{{msg}}</p>
     4     <!--使用 v-cloak 能够解决 插值表达式闪烁的问题 ,还能对值拼接-->
     5     <p v-cloak>v-cloak:+++++++++++{{msg}}----------</p>
     6     <!--使用v-text没有闪烁问题,覆盖元素中的原本内容,-->
     7     <p v-text="msg">v-text:======================</p>
     8 
     9     <!--使用v-html:将msg解析为HTML格式,也会覆盖原本内容-->
    10     <div>{{msg2}}</div>
    11     <div v-text="msg2"></div>
    12     <div v-html="msg2">111111</div>
    13 
    14     <!--使用v-bind:vue提供的用于绑定属性的指令 简写为:,还可以拼接字符-->
    15     <input type="button" value="v-bind指令" v-bind:title="mytitle +',我是拼接的'">
    16 
    17     <!--使用v-on:绑定事件机制  简写为@-->
    18     <input type="button" value="v-on指令" v-on:click="show">
    19     <input type="button" value="v-on指令:mouseover" @mouseover="show2">
    20     <br><br><br>
    21 </div>

     2.事件修饰符 :.stop   .prevent  .capture  .self  .once

     1 <h2>2.事件修饰符</h2>
     2     <div class="inner" @click="divHandler">
     3 
     4         <input type="button" value="戳它" @click.once="btnHandler"><br>
     5         <!--默认:先btn的后div的-->
     6         <!-- 内层加入.stop后,没有触发外层div -->
     7         
     8         <a href="http://www.baidu.com" @click.prevent="linkclick">百度一下,你就知道</a>
     9         <!-- 链接加入.prevent,阻止默认行为 -->
    10 
    11         <!-- 外层使用.capture, 捕获机制->顺序为:先div后btn   .capture加在外层-->
    12 
    13         <!-- 外层使用.self,实现只有点击当前元素才会触发事件处理函数 -->
    14 
    15         <!-- 使用.once,当前元素只触发一次 -->
    16 
    17     </div>
    18     <div class="outer" @click="div2Handler">
    19         <div class="inner" @click.self="divHandler">
    20             <input type="button" value="戳一下" @click="btnHandler">
    21             <!-- 默认顺序:btn inner outer -->
    22             <!-- .self只会阻止自己身上的冒泡,btn outer -->
    23         </div>
    24     </div>

     3.v-model实现数据双向绑定

    1  <h2>3.v-model实现表单数据双向绑定</h3>
    2     <!-- v-bind:只能实现数据的单向绑定,从M自动绑定到V -->
    3     <!-- <input type="text" v-bind:value="msg3"> -->
    4      <input type="text" v-bind:value="msg3" v-model:value="msg3">
    5      <!-- v-model :实现表单元素和model中数据的双向绑定,只能运用在表单元素中
    6     input(radio,text,address,email...)select、CheckBox、textarea等
    7     -->

     4.v-for 循环遍历与迭代数字

     1 <h2>4.v-for循环遍历普通数组与对象</h3>
     2     <!-- <p>{{list[0]}}</p><p>{{list[2]}}</p><p>{{list[3]}}</p> -->
     3     <!-- <p v-for="item in list">{{item}}</p> -->
     4     <!-- 注意:空格 -->
     5     <p v-for="(user,i) in list">Id:{{user.id}} --- 名字:{{user.name}} --- 索引:{{i}}</p>
     6     <p v-for="(val,key) in user">值:{{val}} --- 键:{{key}} </p>
     7     <p v-for="(val,key,i) in user">值:{{val}} --- 键:{{key}} --- 索引:{{i}}</p>
     8 
     9     <h3>4.1 v-for迭代数字</h3>
    10     <!-- 从1开始迭代 -->
    11     <p v-for="count in 4">这是第{{count}}次循环</p>
    12     <!-- 2.20+以后, -->
    13     <h4>魔道祖师</h4>
    14     <div>
    15         <label>
    16             Id:
    17             <input type="text" v-model="id">
    18         </label>
    19         <label >
    20             Name:
    22             <input type="text" v-model="name">
    23         </label>
    24 
    25         <input type="button" value="添加" @click="add">
    26         
    27     </div>
    28     <!-- 注意:v-for循环的时候,key属性只能使用number获取string -->
    29     <!-- 注意:key 使用时,必须使用v-bind属性绑定的的形式 -->
    30     <!-- 在组件中,使用v-for循环时,或者在一些特殊情况中,如果v-for有问题,得为它指定唯一的字符串/数字 类型 :key值 -->
    31     <p v-for="item in list1" :key="item.id">
    32         <input type="checkbox" >
    33        {{item.id}} --- {{item.name}}
    34     </p>

     5.v-show与v-if

    1 <h2>5. v-show与v-if</h3>
    2 
    3     <input type="button" @click="flag=!flag" value="toggle">
    4     <!-- v-if:每次都会重新删除或创建元素 ,
    5         有较高的切换性能消耗,频繁切换情况不要用,用v-show-->
    6     <h3 v-if="flag">这是v-if控制的元素</h3>
    7     <!-- v-show:每次不会重新进行DOM的删除和创建操作,只是切换了元素的display:none样式 ,
    8         有较高的初始渲染消耗,如果元素可能永远不会被显示出来被用户看到,用v-if-->
    9     <h3 v-show="flag">这是v-show控制的元素</h3>

    6.键盘修饰符

     1 <h2>6. 键值修饰符</h2>
     2     <!-- 使用时为:@keyup.xxx="function" -->
     3     <li>.enter</li>
     4     <li>.tab</li>
     5     <li>.delete</li>
     6     <li>.esc</li>
     7     <li>.space</li>
     8     <li>.up</li>
     9     <li>.down</li>
    10     <li>.right</li>
    11     <li>.left</li>
    12     <li>.keycode(数字)</li>
      <!-- 测试自定义键盘修饰符 -->
      <input type="text" v-model="name" @keyup.f2="add"> 
      // 自定义全局修饰符
      Vue.config.keyCodes.f2=113;
    
    

     二、vue中的样式

    1.内联样式-style

     1 <div id="app">
     2         <!-- 对象就是无序的键值对的集合,        对象中有横线的不能省略单引号 -->
     3         <h1 :style="{color:'red','font-weight':'200'}">这是一个h1</h1>
     4         <h1 :style="styleObj">这是一个h1</h1>
     5         <h1 :style=[styleObj,styleObj2]>这是一个h1</h1>
     6         
     7     </div>
     8     
     9     <script>
    10         var vm=new Vue({
    11             el:'#app',
    12             data:{
    13                 styleObj:{color:'red','font-weight':'200'},
    14                 styleObj2:{'font-style':'italic'}
    15             },
    16             methods:{}
    17         })
    18     </script>

     2.class样式

     1 <head><style>
     2         .red{
     3             color: red;
     4         }
     5         .thin{
     6             font-weight: 200;
     7         }
     8         .italic{
     9             font-style: italic;
    10         }
    11         .active{
    12             letter-spacing: 0.5em;
    13         }
    14         .change{
    15             color:green;
    16         }
    17     </style>
    18 </head>
    19 <body>
    20     <div id="app">
    21         <!-- 以前的使用方式 -->
    22         <h1 class="red thin">大大无法想象</h1>
    23         <!-- 第一种使用方式,直接传递一个数组,注意:这里的class得用v-bind绑定 -->
    24        <h1 :class="['thin','italic']">很大,无法想象!!!</h1> 
    25         <!-- 在数组中使用三元表达式 -->
    26         <h1 :class="['thin','italic',!flag?'active':'']">很大!!!</h1>
    27         <!-- 在数组中使用对象来代替三元表达式提高可读性 -->
    28         <h1 :class="['thin','italic',{'change':flag}]">很大!!!</h1>
    29         <!-- 对象的属性是类名,可带引号也可不带,属性的值是一个标识符 -->
    30         <!-- <h1 :class="{ red:true,thin:true,italic:false}">很大!!!</h1> -->
    31         <h1 :class="classObj">很大!!!</h1>
    32         
    33     </div>
    34 
    35     <script>
    36         var vm=new Vue({
    37             el:'#app',
    38             data:{
    39                 flag:true,
    40                 classObj:{ red:false,thin:true,italic:false,change:true}
    41             },
    42             methds:{}
    43         })
    44     </script>

     三、过滤器filter

     过滤器的定义语法:
           Vue.filter('过滤器的名称',function(){});// 过滤器中的function第一个参数,永远都是过滤器(管道符前面)传递过来的数据

     1   <div id="app">          
     4             <p v-html='msg'></p>
     5 
     6             <!-- <p>{{ msg | msgFormat }}</p> -->
     7             <!-- <p>{{ msg | msgFormat(' *****') }}</p> -->
     8             <p>{{ msg | msgFormat('夷陵老祖',' *****','魏无羡') }}</p>
     9     </div>
    10      <script>
    11 
    12          //定义一个全局过滤器:msgFormat
    13             Vue.filter('msgFormat',function(msg,arg,arg2,arg3){
    14                 //字符串的 replace方法,第一个参数,除了可写一个字符串外,还可以定义正则
    15                 return msg.replace(/<br>/g,arg+arg2+arg3);//将换行符换成三个参数相连的样子
    16             });
    17 
    18          var vm=new Vue({
    19              el:'#app',
    20              data:{
    21                  msg:'魔道祖师:'+'<br>'+'<br>'        
    22              },
    23              methods:{},
    24          })
    25      </script>             

     四、vue-resource

     1 <head>
     2     <meta charset="UTF-8">
     3     <title>Document</title>
     4     <script src="../lib/vue.js"></script>
     5     <!--1. 注意:vue-resource依赖于Vue,注意先后顺序 -->
     6     <!-- this.$http. -->
     7     <script src="../lib/vue-resource.js"></script>
     8 </head>
     9 <body>
    10     <div id="app">
    11         <input type="button" value="Get请求" @click="getInfo">
    12         <input type="button" value="Post请求" @click="postInfo">
    13         <input type="button" value="Jsonp请求" @click="jsonpInfo">
    14     </div>
    15     <script>
    16     var vm=new Vue({
    17         el:'#app',
    18         data:{
    19 
    20         },
    21         methods:{
    22             getInfo(){//发起get请求
    23                 // 当发起get请求之后,通过 .then来设置成功的回调函数
    24                 this.$http.get('http://www.liulongbin.top:3005/api/getlunbo').then(function(result){
    25                     console.log(result)
    26                     // 通过 result.body 拿到服务器返回的数据
    27                 });
    28                 // this.$http.jsonp("http://vue.studyit.io/api/getlunbo").then(result => {
    29                 //         console.log(result.body);
    30                 //     });
    31             },
    32             postInfo(){
    33                 // 手动发起的表单请求默认没有表单格式,有的服务器处理不了
    34                 // 通过post的第三个参数,设置,提交内容为普通表单数据格式
    35                 this.$http.post('http://www.liulongbin.top:3005/api/post',{},{emulateJSON:true}).then(result=>{
    36                     console.log(result.body)
    37                 })
    38             },
    39             jsonpInfo(){//发起jsonp请求
    40                 this.$http.jsonp('http://www.liulongbin.top:3005/api/jsonp').then(result=>{
    41                     console.log(result.body)
    42                 })
    43             }
    44         }
    45     })
    46     </script>

     六、生命周期函数

    beforeCreate()、created()、beforeMount()、mounted()、beforeUpdate()

     1 <div id="app">
     2         <input type="button" value="修改msg" @click="msg='NO'">
     3         <h3 id="h3">{{msg}}</h3>
     4     </div>
     5     
     6     <script>
     7     
     8     var vm=new Vue({
     9         el:'#app',
    10         data:{
    11             msg:'----ok',
    12         },
    13         methods:{
    14             show(){
    15                 console.log('执行了show方法')
    16             }
    17         },
    18         beforeCreate() {//遇到第一个生命周期函数,表示示例被完全创建出来之前会执行它
    19             console.log('beforeCreate:'+this.msg)
    20             // this.show() is not a function
    21             // 在beforeCreate()生命周期函数执行的时候,data 和 methods 中的数据都还没有被初始化
    22         },
    23         created() {//遇到的第二个生命周期函数
    24             console.log('created:'+this.msg),
    25             this.show()
    26         // 在created函数中,data 和 methods都已被初始化好了
    27         // 如果要调用methods里的方法,最早在created里执行
    28             
    29         },
    30         beforeMount() {//遇到的第三个生命周期函数,表示模板已经在内存中编辑完成了,但尚未把 模板 渲染到页面中
    31           var a=  document.getElementById("h3").innerText
    32             console.log('beforeMount:'+a)
    33             // 在beforeMount函数执行的时候,页面中的元素还没有被真正替换过来,只有之前写的一些模板字符串
    34         },
    35         mounted() {//遇到的第四个生命周期函数,表示内存中的模板已经真实的挂载到页面中,用户已经可以看到 渲染好的页面了
    36             var a=  document.getElementById("h3").innerText
    37             console.log('mounted:'+a)
    38             // 注意:mounted 是实例创建期间最后一个生命周期函数,当执行完mounted就表示,实例已经完全被创建好了,
    39             // 此时如果没有其他操作的话 这个实例静静的躺在内存中
    40         },
    41         // 接下来是运行中的两个事件
    42         beforeUpdate() {//这时候 表示 我们的界面还没被更新 
    43             console.log('beforeUpdate:界面上元素的内容'+document.getElementById('h3').innerText)//无效果,
    44             //加button试试 --可以看出来了
    45             console.log('data 中的 msg是'+this.msg)
    46         // 结论:
    47         // 当执行beforeUpdate的时候,页面中显示的数据还是旧的,此时 data数据是最新的,页面尚未和data保持同步
    48         },
    49     })
    50      //结果:beforeCreate:undefined
            created:----ok
            执行了show方法
            beforeMount:{{msg}}
            mounted:----ok
         点击按钮之后打印新增:
            beforeUpdate:界面上元素的内容----ok
            data 中的 msg是NO 51 </script>

     七、动画

    1.不使用动画

     1 <div id="app">
     2         <input type="button"value="toogle" @click="flag=!flag">
     3     <!-- 需求:点击按钮,让h3显示,再次点击,隐藏 -->
     4     <h3 v-if="flag">春风吹不倒,我的杨柳腰</h3>
     5     </div>
     6     <script>
     7     var vm=new Vue({
     8         el:'#app',
     9         data:{flag:false},
    10     }) 
    11     </script>

    2.使用过渡类名实现

     1 <!-- 自定义两组样式,来控制transition内部的元素实现动画 -->
     2     <style>
     3         .v-enter,
     4             /* .vue-enter【这是一个时间点】是进入之前元素的起始状态,此时还没有开始进入 */
     5         .v-leave-to{
     6             /* 是动画离开之后,离开的终止状态,此时,元素动画已经结束了 */
     7             opacity: 0;
     8             transform: translateX(80px);
     9         }
    10  
    11         .v-enter-active,
    12         /*  [入场动画的时间段]*/
    13         .v-leave-active{
    14             /* [离场动画的时间段] */
    15             transition: all 0.4s ease;
    16         }
    17     </style>
    18 </head>
    19 <body>
    20     <div id="app">
    21         <input type="button"value="toogle" @click="flag=!flag">
    22     <!-- 需求:点击按钮,让h3显示,再次点击,隐藏 -->
    23     <transition>
    24             <h3 v-if="flag">春风吹不倒,我的杨柳腰</h3>
    25     </transition>
    26    
    27     <!-- 1.使用transition元素,把需要被动控制的元素,包裹起来 -->
    28     <!-- transition 是Vue官方提供的 -->
    29 </div>

     3.使用第三方类:animate.css

     1  <link rel="stylesheet" href="../lib/animate.css">
     2     <!-- 入场用bounceIn 离场bounceOut -->
     3 </head>
     4 <body>
     5     <div id="app">
     6         <input type="button"value="toogle" @click="flag=!flag">
     7 
     8     <!-- 使用:duration="毫秒值"来设置入场离场时的动画时长 -->
     9     <transition enter-active-class="bounceIn" leave-active-class="bounceOut":duration="400">
    10             <h3 v-if="flag">春风吹不倒,我的杨柳腰</h3>
    11     </transition>
    12 
    13     <hr>
    14     <input type="button"value="toogle1" @click="flag1=!flag1">
    15     <!-- 使用:duration="{enter:,leave:}"设置出入场时间 -->
    16     <transition 
    17     enter-active-class="bounceIn" 
    18     leave-active-class="bounceOut"
    19     :duration="{enter:00,leave:400}">
    20             <h3 v-if="flag1">春风吹不倒,我的杨柳腰</h3>
    21     </transition>

     4.修改v-前缀

     1   <style>
     2         .my-enter,
     3         .my-leave-to{
     4             opacity: 0;
     5             transform: translatey(80px);
     6         }       
     7         .my-enter-active,
     8         .my-leave-active{
     9             transition: all 0.4s ease;
    10         }
    11     </style>
    12 </head>
    13 <body>
    14     <div id="app">
    15        <input type="button"value="toogle2" @click="flag2=!flag2">
    16        <transition name="my">
    17             <h4 v-if="flag2">月儿在手中开呀怀儿笑,云儿在那眼前睡得早</h4>
    18        </transition>
    19    </div>

     5.使用钩子函数模拟小球动画

     1 <style>
     2         .ball{
     3             width:15px;
     4             height:15px;
     5             border-radius: 50%;
     6             background-color:red;
     7         }
     8     </style>
     9 </head>
    10 <body>
    11     <div id="app">
    12         <input type="button" value="快到碗里来" @click="flag=!flag">
    13 
    14         <transition
    15            @before-enter="beforeEnter"
    16            @enter="enter"
    17            @after-enter="afterEnter"> 
    18             <div class="ball" v-show="flag"></div>
    19         </transition>
    20        
    21     </div>
    22     <script>
    23         
    24         var vm=new Vue({
    25             el:'#app',
    26             data:{
    27                 flag:false,
    28             },
    29             methods:{
    30                 // 注意:动画钩子函数的第一个参数:el表示 要执行的动画的那个DOM元素,是个原生JS DOM对象
    31                 // el是通过docum.getElementByID(''),方法获取到的原生JS对象
    32                 beforeEnter(el){//表示动画入场之前,此时动画尚未开始,
    33                     // 可以在这里设置元素开始动画开始之前的起始样式
    34                     el.style.transform="translate(0,0)"//设置小球开始动画之前的起始位置
    35                 },
    36                 enter(el,done){
    37                     //这句话没有实际作用,不写没动画效果
    38                     el.offsetWidth//强制动画刷新
    39                     // 表示动画开始之后的样式,这里可以设置小球完成动画之后的结束状态
    40                     el.style.transform="translate(150px,450px)"
    41                     el.style.transition='all 1s ease'
    42 
    43                     // 立马消失?这里的done就是afterEnter函数,即,done为afterEnter函数的引用
    44                    done()
    45                 },
    46                 afterEnter(el){//动画完成之后
    47                     // el.style.transform="translate()"
    48                     // console.log("执行完毕!")
    49                     this.flag=!this.flag
    50                 }
    51             },
    52         })
    53     </script>

     6.列表的动画

     1  <script src="../lib/vue.js"></script>
     2     <link rel="stylesheet" href="../lib/animate.css">
     3     <style>
     4     li{
     5         border:1px solid #999;
     6         margin: 5px;
     7         line-height: 35px;
     8         padding-left: 5px;
     9         font-size: 12px;
    10 
    11         width:100% 
    12         /* 解决设置absolute后,宽度的变化 */
    13     }
    14     li:hover{
    15         background-color:pink;
    16         transition: all 0.4s ease;
    17         /* 悬停时,背景过渡 */
    18     }
    19     /* 固定组合,4个,实现进入时渐变,离开时渐变 */
    20     .v-enter,
    21     .v-leave-to{
    22         opacity: 0;
    23         transform: translateY(80px);
    24     }
    25     .v-enter-active,
    26     .v-leave-active{
    27         transition: all 1s ease;
    28     }
    29 
    30 /* 自编样式 前一个元素离开时,让剩下的渐变移动 ,与.v-leave-active:position为absolute一起使用*/
    31     .v-move{
    32         transition:all 1s ease;
    33     }
    34     /* absolute弊端:元素离开时宽度后发生变化,
    35     解决:设置其宽为100%即可 */
    36     .v-leave-active{
    37         position: absolute;
    38     }
    39     </style>
    40 </head>
    41 <body>
    42     <div id="app">
    43         <div>
    44             <label for="">
    45                 Id:
    46                 <input type="text" v-model="id">
    47             </label>
    48             <label for="">
    49                 Name:
    50                 <input type="text" v-model="name">
    51             </label>
    52 
    53             <input type="button" value="添加" @click="add">
    54         </div>
    55         <!-- <ul> -->
    56             <!-- 在使用列表过渡的时候,如果需要过渡的元素,是通过v-for循环渲染出来的,不能使用transition包裹
    57             需要使用transitionGroup -->
    58             <!-- 给 transition-group添加appear,实现页面刚展示出来的时候的入场动画 -->
    59             <!-- tag标签,指明将transition渲染为什么标签,不指定默认渲染为span -->
    60             <transition-group appear tag="ul">
    61                 <!-- 要为v-for循环创建的元素设置动画,必须为每个元素设置 :key属性 -->
    62                     <!-- <li v-for="item in list" :key="item.id" @click="del(i)"> -->
    63                     <li v-for="(item,i) in list" :key="item.id" @click="del(i)">
    64                         <!-- 移除:@click 增加i元素-->
    65                             {{item.id}} ---{{item.name}}
    66                         </li>
    67             </transition-group>
    68         <!-- </ul> -->
    69     </div>
    70     
    71     <script>
    72         var vm=new Vue({
    73             el:'#app',
    74             data:{
    75                 id:'',
    76                 name:'',
    77                 list:[
    78                     {id:1,name:'魏无羡'},
    79                     {id:2,name:'蓝忘机'},
    80                     {id:3,name:'江澄'},
    81                     {id:4,name:'金子轩'}, 
    83                 ]
    84             },
    85             methods:{
    86                 add(){
    87                     this.list.push({id:this.id,name:this.name})
    88                 },
    89                 del(i){
    90                     this.list.splice(i,1)
    91                 }
    92             }
    94         })
    95     </script>

    八、组件

    1,组件之data和method

     1 <div id="app">
     2         <mycom1></mycom1>
     3     </div>
     4     
     5     <script>
     6         // 1.组件可以有自己的data数据
     7         // 2.组件的 data 和实例的 data 有点不一样,实例中的data可以为一个对象,但是组件中的必须是一个方法
     8         // 3.组件中的 data 除了必须为一个方法外,这个方法内部,还必须返回一个对象才行
     9         // 4.组件中的 data 数据,使用方式和实例中的 data 使用方式完全一样
    10         Vue.component('mycom1',{
    11             template:'<h3>这是全局组件</h3>',
    12             data:function(){
    13                 return{
    14                     msg:'这是组件中的data定义的数据'
    15                 }
    16             }
    17         })
     1 //组件的data必须是一个function
     2 <div id="app">
     3        <count></count>
     4        <hr>
     5        <count></count>
     6        <hr>
     7        <count></count>
     8     </div>
     9     <template id="tmpl">
    10         <div>
    11             <input type="button" @click="increment" value="加">
    12             <h3>{{count}}</h3>
    13         </div>
    14     </template>
    15     
    16     <script>
    17         var dataObj={count:0}
    18         //计数器组件,身上有个按钮,每当点击按钮,让 data 中的 count 值 + 1
    19         Vue.component('count',{
    20             template:'#tmpl',
    21             // data:function(){  //data是一个function
    22              data(){
    23             //   return dataObj  //使用多个组件时,数据一样
    24             return {count:0}  //使用多个组件时,不关联
    25             },
    26             methods:{  //methods是一个对象
    27                 increment(){
    28                     this.count+=1
    29                 }
    30             }
    31         })
          </script>

     2.组件之创建组件的方式 - 前4个外部定义

    1)使用Vue.extend:

     1 <div id="app">
     2     <!-- 如果要使用组件,直接把组件名称,以HTML标签的形式引入页面即可 -->
     3         <!-- <myCom1></myCom1>  错误的-->
     5         <my-com1></my-com1> //1
     6         <mycom1></mycom1>   //2
     7 </div> 
     8 // 1.分两步
     9         //1.1 使用vue.extend来创建全局vue组件
    10        var com1= Vue.extend({
    11             template:'<h3>这是使用Vue.extend 创建的组件</h3>'//通过template属性,指定了组件要展示的HTML结构
    12         })
    13         // 1.2 使用Vue.components('组件的名称',创建出来的组件模板对象)
    14         Vue.component('myCom1',com1)
    15         // 使用Vue.component定义全局组件时,若使用驼峰,则引用时大写改小写两单词之间用“——”链接
    16         // 否则,直接写
    17 
    18         // 2.一步解决
    19         Vue.component('mycom1',Vue.extend({
    20             template:'<h3>外部定义一:这是Vue.component里Vue.extend创建的组件</h3>'
    21         }))
    定义组件的时候,全局:Vue.component('组件名称',{})
        组件模板几种方式的创建,通过Vue.component吧组件模板电对象,注册为一个全局的vue组件,同时为这个组件起来一个名称,
        在页面以标签显示 引入组件
    2)Vue.component('组件名称',{})
    1  // 第二种
    2         Vue.component('mycom2',{
    3             // 注意:不论是哪种方式创建出来的组件,组件的template属性的模板内容,必须有且只有一个唯一的根元素
    4             template:'<div><h3>外部定义二、这是使用Vue.component 创建的组件</h3> <span> 我是第二种方式里的其他标签</span></div>'
    5         })

    3)Vue.component('组件名称',{tamplate:'#tmpl'})

     1  <!-- 在被控制的#App外面 使用template元素定义组件的模板结构 依旧遵循唯一根元素-->
     2      <template id="temp1">
     3         <div>
     4             <h3>外部定义三:这是通过 template 元素,在外部定义的组件结构,这个方式,有代码的只能提示和高亮</h3>
     5             <h4>好用,不错</h4>
     6         </div>
     7     </template>
     8 
     9 // 第三种
    10         Vue.component('mycom3',{
    11             template:'#temp1'
    12         })

     4) Vue.component('组件名称',对象)

    1  // 第四种
    2         var abc={ //通过对象 字面量的形式,定义了一个组件模板对象
    3             template:'<h3>外包定义四、这是用对象承接了template组件,</h3>'
    4         }
    5         Vue.component('mycom4',abc)

     5)内部定义

     1 // 内部定义第二种
     2     var register={
     3         template:'<h3>内部定义二:这是用对象承接的template</h3>'
     4     }
     5     var vm2=new Vue({
     6         el:'#app2',
     7         data:{},
     8         methods:{},
     9         filters:{},
    10         directives:{},
    11         components:{//定义内部私有组件
    12 //1.内部定义第一种
    13             login:{
    14                 // template:'<h3>这是私有的 login 组件</h3>'
    15                 template:'#templ2'
    16             },
    17             // '组件名称':组件模板
    18             // 2.1内部定义第二种
    19             // register  
    20             // 2.2内部定义第二种
    21             'register':register//同上一个作用
    22         },
    23     })
    24     </script>

    3.组件之ref获取DOM元素和组件引用

     1 <div id="app">
     2         <input type="button" value="获取元素" @click="getElement" ref="mybtn">
     3         <h3 id="myh3" ref="myh3">纵然与世无争 道不同义在心中,怎奈侠肝义胆,却成一场空</h3>
     4         <hr>
     5         <login ref="mylogin"></login>
     6     </div>
     7     <script>
     8         // 登录组件
     9         var login={
    10             template:'<input type="button" value="登录组件">',
    11             data(){
    12                 return{
    13                     msg:'son msg'
    14                 }
    15             },
    16             methods: {
    17                 show(){
    18                     console.log("调用了子组件的方法")
    19                 }
    20             },
    21         }
    22     var vm=new Vue({
    23         el:'#app',
    24         methods:{
    25             getElement(){
    26                 // console.log(document.getElementById('myh3')) //值为h3
    27                 // console.log(document.getElementById('myh3').innerHTML)//值为h3的内容   
                // console.log(document.getElementById('myh3').innerText)//值为h3的内容
    28 // ref :reference引用 获取DOM结点 29 console.log(this.$refs.myh3.innerText) //myh3的内容 30 console.log(this.$refs.mybtn.innerHTML+'我是button的') //我是button的 31 console.log(this.$refs.mylogin.msg) //son msg 32 console.log(this.$refs.mylogin.show()) //结果:调用了子组件的方法->执行了show方法 33 // 结果 undefined -> 打印语句里调用的方法没返回值 34 } 35 }, 36 components:{ 37 login 38 } 39 }) 40 </script>

     4.组件之组件切换

    1     <h3>第一种切换方式</h3>
    2         <a href="" @click.prevent="flag=true">登录</a>
    3         <a href="" @click.prevent="flag=false">注册</a>
    4 
    5         <login v-if="flag"></login>
    6         <register v-else="flag"></register>
    7         <hr>
     1    <h3>第二种切换方式</h3>
     2         <a href="" @click.prevent="comName='login'">登录</a>
     3         <a href="" @click.prevent="comName='register'">注册</a>
     4 
     5         <!-- vue提供了component,来展示对应名称的组件 -->
     6         <!-- component是一个占位符,:is属性,指定要展示的组件的名称 -->
     7         <!-- <component :is="componentId"></component> -->
     8         <component :is="comName"></component>
     9         
    10         <!-- 总结:当前学习的vue提供的标签:
    11         component、template、transition、transition-group -->
    12         <hr>
       var vm=new Vue({
            el:'#app',
            data:{
                flag:false,
                comName:'register',//当前 component 中的 :is 绑定的组件的名称
            },
            methods:{}
       })
    1     <h3>实现切换动画</h3>
    2         <a href="" @click.prevent="comName='login'">登录</a>
    3         <a href="" @click.prevent="comName='register'">注册</a>
    4 
    5         <!--通过 mode属性:out-in 设置组件切换时候的模式-->
    6         <transition mode="out-in"> 
    7             <component :is="comName"></component>
    8         </transition>

     5.组件之父组件向子组件传值

    1 <div id="app">
    2         <!-- 值:消息,props与data -->
    3         <!--父组件可以在引用子组件的时候,通过属性绑定的形式(v-bind)的形式,把需要传递给子组件的数据,传过去 -->
    4             <com1 v-bind:parentmsg="msg"></com1>
    5 <div>
     1 var vm=new Vue({
     2         el:'#app',
     3         data:{
     4             msg:'123 - 父组件中的数据',
     5             datamsgFromson:null,
     6         },
     7         methods:{
     8             show(data){
     9                 console.log('调用了父组件身上的show方法 --- '+data)
    10                 this.datamsgFromson=data
    11             },
    12         },
    13         components:{
    14             com1:{ // 子组件中默认无法访问父组件中,data 上的数据、methods 里的方法,如下
    15                 // template:'<h3>这是子组件 ---{{msg}}</h3>' //获取不到msg
    16                 template:'<h3 @click="change">这是子组件 ---{{parentmsg}}</h3>',//获取不到parentmsg
    17 
    18                 props:['parentmsg'],//把父组件传递过来的parentmsg属性,现在props数组中,定义一下,才能使用
    19                 // 注意:组件中的所有 props 中的数据,都是通过父组件传递给了子组件
    20                 // props中的数据都是只读的,
    21 
    22                 data(){ //子组件中的data数据并不是通过父组件传递的,而是自己私有的
    23                     // data里的数据都是可读可写的
    24                     return {
    25                         title:'666',
    26                         content:'qqq',
    27                     }
    28                 },
    29                 filters:{},
    30                 directives:{},
    31                 components:{},
    32                 methods: {
    33                     change(){ //给template里的标签添加绑定事件
    34                         this.parentmsg="被修改了"
    35                     }
    36                 },
    37             },
                      com2:com2  //传递方法
    38         }
    39     })
    40     </script>
    1 <div id="app">
    2         <!-- 值:methods -->
    3             <!-- 父组件向子组件传递方法,使用的是事件绑定机制(v-on)当自定义了一个事件属性之后,子组件就能够通过某些方式来调用 方法 -->
    4             <!-- <com2 v-on:fun="show"></com2> -->
    5             <!-- 传参1 -->
    6             <!-- <com2 @fun="show('哈哈')"></com2>   -->
    7             <!-- 未传参1 -->
    8             <com2 @fun="show"></com2>
    9     </div>
     1 <template id="tmpl2">
     2        <div>
     3            <h3>这是 子组件2</h3>
     4            <input type="button"value="子组件中的按钮,点击触发父组件传递过来的方法" @click="myclick">
     5        </div>
     6    </template>
     7 
     8 
     9     <script>
    10         //另一种
    11         var com2={
    12             template:'#tmpl2',
    13             data(){
    14                 return{
    15                     sonmsg:{name:'小头儿子',age:6}
    16                 }
    17             },
    18 
    19             methods: {
    20                 myclick(){
    21                     // console.log('1111')
    22                     // 当点击子组件按钮时,如何拿到父组件传递过来的func方法,并调用
    23                     //未传参2
    24                 //    this.$emit('fun')
    25                     // 传参2
    26                     this.$emit('fun','哈哈')
    27                     // emit:英文原义- 触发、调用、发射
    28                     this.$emit('fun',this.sonmsg)
    29                 }
    30             },
    31         }

     九、路由

    1.路由的基本使用 

    <!-- 1.安装路由模块 -->
        <script src="../lib/vue-router.js"></script>
     1 // 2. 创建一路由对象,当导入vue-router包后,在window全局对象中,就有了一个路由的构造函数,叫做VueRouter
     2         //在new 路由对象时,可以为构造函数,传递一个配置对象
     3         var routerObj=new VueRouter({
     4             // route //这个配置对象中的route表示 【路由配置规则】
     5             routes:[ //路由配置规则
     6             // 每个路由规则都是一个对象,这个对象身上有两个必须的属性,
     7               // 属性1:path - 监听那个路由连接地址
     8               // 属性2:component - 表示,如果路由是前面匹配到的path,则展示component属性对应的那个组件,
     9                 //    值为组件模板对象,不是引用名称
    10             {path:'/',redirect:'/login'}, //这里的 redirect 完全是两码事
    11             {path:'/login',component:login},
    12             {path:'/register',component:register}
    14             ], 
      })
          // 此处login为组件的模板对象
            var login={
                template:'<h3>登录组件</h3>'
            }
            //此处login为组件名称,不是对象,不能放到路由里,应选择上面的
             Vue.component('login',{
             template:'<h3>登录组件yaya</h3>'
             });
           var register={
               template:'<h3>注册组件</h3>'
           }
    <div id="app">
            <!-- router-link:默认渲染为a标签 -->
            <router-link to="/login">登录</router-link>
            <router-link to="/register">注册</router-link>

            <!-- 这是vue-router 提供的元素,专门用来当做占位符的,将来路由规则、匹配到的组件,就会展示到这个router-view中
            可视router-view为占位符 -->
     
                    <router-view></router-view>       
     
        </div>
    1  var vm=new Vue({
    2         el:'#app',
    3         data:{},
    4         methods:{},
    5         router:routerObj //将路由规则对象注册到vm实例上,用来监听URL变化,然后展示组件
    6 
    7     })

     2.路由之修改样式:

    1 <transition mode="out-in">
    2                 <router-view></router-view>        
    3  </transition>
    一般样式如下:
        .v-enter,
        .v-leave-to{
            opacity: 0;
            transform:translateX(150px);
        }
        .v-enter-active,
        .v-leave-active{
            transition: all 0.5s ease;
        }
    /* 修改样式第一种:修改自带的类样式  */
        .router-link-active{
            color:red;
            font-weight: 800;
            /* font-style: italic; */
            font-size: 20px;
            text-decoration: underline;
            background-color: green;
        }
    /* 修改样式第二种,自定义样式,传给linkActiveClass */
        .myactive{
            color:green;
            font-weight: 400;
            background-color: pink;
        }
    //增加linkActiveClass如下:
       var routerObj=new VueRouter({
     
                routes:[ //路由配置规则
     
                {path:'/',redirect:'/login'}, //这里的 redirect 完全是两码事
                {path:'/login',component:login},
                {path:'/register',component:register}
                ],
                // 修改样式第二种:通过linkActiveClass设置样式
                linkActiveClass:'myactive'
            })

     3.路由的嵌套

     1     <div id="app">
     2         <router-link to="/account">Account</router-link>
     3         <router-view></router-view>
     4     </div>
     5 
     6     <template id="tmpl">
     7         <div>
     8             <h3>这是Account组件</h3>
     9             <router-link to="/account/login">登录</router-link>
    10             <router-link to="/account/register">注册</router-link>
    11 
    12             <!-- 放置子路由组件的位置 -->
    13             <router-view></router-view>
    14         </div>
    15     </template>
    16   
    17     <script>
    18         // 组件的模板对象
    19         var account={
    20             template:'#tmpl'
    21         }
    22         var register={
    23             template:'<h4>注册组件</h4>'
    24         }
    25         var login={
    26             template:'<h4>登录组件</h4>'
    27         }
    28         var router=new VueRouter({
    29             routes:[
    30                 {   path:'/account',
    31                     component: account,
    32                     children:[  //children:子路由,子路由的path前面不用带斜线,否则永远以根路径开始请求,不方便用户立即URL地址
    33                          {path:'login',component:login},
    34                          {path:'register',component:register}
    35                     ],
    36                 },
    37             ]
    38         })
    39 
    40     var vm=new Vue({
    41         el:'#app',
    42         data:{},
    43         methods:{},
    44         router,
    45     })
    46     </script>

     4.路由之使用命名规则实现经典布局

     1 <style>
     2         .header{
     3             background-color: orange;
     4             height:80px;
     5         }
     6         .left{
     7             background-color:lightgreen;
     8             flex:2
     9         }
    10         .main{
    11             background-color: lightpink;
    12             flex:8;
    13         }
    14         .container{
    15             display: flex;
    16             height: 600px;            
    17         }
    18         h2{
    19             margin:0;
    20             /* padding:0; */
    21             font-size: 16px;
    22         }
    23         html,body{
    24             margin:0;
    25             padding:0;
    26         }
    27     </style>
    28 </head>
    29 <body>
    30     <div id="app">
    31         <router-view></router-view>
    32         <div class="container">
    33             <router-view name='left'></router-view>
    34             <router-view name="main"></router-view>
    35         </div>
    36     </div>
    37 
    38     <script>
    39         // 模板
    40         var header={
    41             template:'<h2 class="header">Header头部区</h2>'
    42         }
    43         var leftBox={
    44             template:'<h2 class="left">侧边栏区域</h2>'
    45         }
    46         var mainBox={
    47             template:'<h2 class="main">主题、体区域</h2>'
    48         }
    49 
    50     // 创建路由对象
    51     var router = new VueRouter({
    52         routes:[
    53             {
    54                 // {path:'/left',component:leftBox},
    55                 // {path:'/main',component:mainBox}
    56                 path:'/',components:{
    57                     'default':header,
    58                     'left':leftBox,
    59                     'main':mainBox
    60                 }
    61             },           
    62         ]
    63     })
    64     var vm=new Vue({
    65         el:'#app',
    66         data:{},
    67         methods:{},
    68         router
    69     })
    70     </script>   

     十、vuex

     1 //项目入口     ---main.js文件
     2 
     3 // console.log('ok')
     4 import Vue from '../node_modules/vue/dist/vue.js'
     5 // 1.运行cnpm i vue-x -S
     6 // 2。导入vuex
     7 import Vuex from "vuex"
     8 // 3.注册vuex到vue中
     9 Vue.use(Vuex)
    10 // 4.new Vuex.Store()实例,得到一个数据仓储对象
    11 var store=new Vuex.Store({
    12     state:{
    13         count:0
    14         // 如果在组件中想要访问,store中的数据,只能通过this.$store.state.名称
    15         // 
    16     },
    17     // 注意:操作store中的state值,通过调用mutations提供的方法,
    18     // 子组件想要调用mutation中的方法,只能使用this.$store.commit('方法名')
    19     // mutations的参数列表中,最多支持两个参数,参数1:state状态,参数2:通过commit传递过来的值
    20     mutations:{
    21         increment(state){
    22             state.count++;
    23         },
    24         subtract(state,obj){
    25             // console.log(obj);
    26             state.count-=(obj.c+obj.d);
    27         },
    28        
    29     },
    30     getters:{
    31         // 注意:这里的getters,只负责对外提供数据,不负责修改数据,修改state中的数据,找mutations
    32         optCount:function(state){
    33             return  '当前最新的count值是:'+state.count
    34         }
    35     }
    36 }) 
    37 
    38 
    39 import app from './app.vue'
    40 
    41 var vm=new Vue({
    42     el:'#app',
    43     render:c=>c(app),
    44     //5.将vuex创建的store挂载到vm实例上
    45     store:store
    46     // 只要挂载到了vm上,可以全局使用了
    47 })

    组件一使用:

     1 <template>
     2     <div>
     3         <input type="button" value="减少" @click="del">
     4         <input type="button" value="增加" @click="add">
     5         <input type="text" v-model="this.$store.state.count">
     6     </div>
     7 </template>
     8 <script>
     9 export default {
    10     methods:{
    11         add(){
    12             // this.$store.state.count++;
    13             // 不符合vuex的设计概念
    14             this.$store.commit('increment');
    15         },
    16         del(){
    17             // this.$store.state.count--;
    18             this.$store.commit('subtract',{c:3,d:4});
    19         }
    20     }
    21 }
    22 </script>

    组件二使用:

     1 <template>
     2     <div>
     3         <!-- <h3>当前数量为:{{this.$store.state.count}}</h3> -->
     4         <h3>{{this.$store.getters.optCount}}</h3>
     5 
     6     </div>
     7 </template>
     8 <script>
     9 export default {
    10     
    11 }
    12 </script>
  • 相关阅读:
    webpack入门
    react中的this.setState()
    Echarts学习之路3(在react中使用)
    Echarts学习之路2(基本配置项)
    react+mobx脚手架搭建多页面开发
    解决使用插件带来的页面弹框滚动穿透问题
    屏蔽微信内置底部前进后退按钮(很迫切的需求)
    input框输入金额处理的解决办法
    git仓库的创建以及本地代码上传
    又发现了一个git clone代码失败时的解决办法
  • 原文地址:https://www.cnblogs.com/Dummer/p/11492067.html
Copyright © 2020-2023  润新知