• vue学习记录


    vue中常用的指令
     v-model
    双向数据绑定,一般用于表单元素

     v-for
    对数组或对象进行循环操作,使用的是v-for

    <!-- 普通循环 -->
    <li v-for="value in arr">{{value}}</li>

    <!-- 键值循环 -->
    <li v-for="(v,k) in arr">{{k}}={{v}}</li> 

    <!-- 可以直接循环包含重复数据的集合,可以通过指定:key属性绑定唯一key,当更新元素时可重用元素,提高效率 ,变化的替换,不变的不替换

           官方解释:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在                           特定索引下显示已被渲染过的每个元素。

    -->

    <li v-for="(v,k) in arr2" :key="k">{{v}}</li> 

    <li v-for="(user,index) in users">
    {{index+1}},{{user.id}},{{user.name}},{{user.age}}
    </li>

    v-on
    用来绑定事件,用法:v-on:事件="函数"        v-on:click="" 简写方式 @click=""         vue方法里的this表示当前vue实例  vue方法访问vue方法或数据都要用this,不能直接访问

    v-show/v-if
    用来显示或隐藏元素,v-show是通过display实现,v-if是每次删除后再重新创建

    指令能直接访问vue实例中的数据

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <script src="js/vue.js"></script>
        <link rel="stylesheet" href="">
    </head>
    <body>
    
        <div id="app">
            <button @click="flag=!flag">显示或隐藏</button>
    
            <div style=" 100px;height: 100px;background: red;" v-if="flag"></div>
        </div>
    
    
        <script type="text/javascript">
            window.onload=function(){
                new Vue({
                    el:"#app",
                    data:{
                        flag:false
                    }
                });
            }
        </script>
    
    </body>
    </html>

    用户管理例子

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <link rel="stylesheet" href="">
        <script src="js/vue.js"></script>
        <link rel="stylesheet" href="bootstrap/bootstrap.min.css">
        <script src="bootstrap/jquery.min.js"></script>
        <script src="bootstrap/bootstrap.min.js"></script>
    </head>
    <body>
        <div class="container">
            <h2 class="text-center">添加用户</h2>
            <form class="form-horizontal">
                <div class="form-group">
                    <label for="userName" class="control-label col-lg-2 col-md-offset-2">姓名:</label>
                    <div class="col-md-6">
                        <input type="text" id="userName" class="form-control" v-model="user.name" placeholder="请输入姓名"></input>
                    </div>
                </div>
                <div class="form-group">
                    <label for="userAge" class="control-label col-lg-2 col-md-offset-2">年龄:</label>
                    <div class="col-md-6">
                        <input type="text" id="userAge" class="form-control" v-model="user.age" placeholder="请输入年龄"></input>
                    </div>
                </div>
                <div class="form-group">
                    <label for="userEmail" class="control-label col-lg-2 col-md-offset-2">邮箱:</label>
                    <div class="col-md-6">
                        <input type="text" id="userEmail" class="form-control" v-model="user.email" placeholder="请输入邮箱"></input>
                    </div>
                </div>
                 <div class="form-group text-center">
                    <input type="button" value="添加" class="btn btn-primary" @click="addUser">
                    <input type="reset" value="重置" class="btn btn-primary">
                 </div>
            </form><!-- form-horizontal -->
    
            <hr>
            <table class="table table-bordered table-hover" >
                <caption class="h3 text-center text-info"> 用户列表</caption>
                <thead>
                    <tr >
                        <th class="text-center">序号</th>
                        <th class="text-center">姓名</th>
                        <th class="text-center">年龄</th>
                        <th class="text-center">邮箱</th>
                        <th class="text-center">操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(user,index) in users" class="text-center">
                        <td >{{index+1}} </td>
                        <td >{{user.name}} </td>
                        <td >{{user.age}} </td>
                        <td >{{user.email}} </td>
                        <td > <button class="btn btn-danger btn-sm"  data-toggle="modal" data-target="#del" @click="nowIndex=index">删除</button> </td>
                    </tr>
                    <tr >
                        <td colspan="5" class="text-right"> <button class="btn btn-danger " data-toggle="modal" data-target="#del"  @click="nowIndex=-1">删除所有</button></td>
                    </tr>
                </tbody>
            </table>
            <!-- 模态框,弹出框 -->
            <div class="modal fade" id="del">
                 <div class="modal-dialog">
                     <div class="modal-content">
                         <div class="modal-header">
                           <button class="close" data-dismiss="modal"> 
                               <span>&times;</span>
                           </button>
                           <div class="modat-titile" v-show="nowIndex!==-1">确定要删除{{users[nowIndex]?users[nowIndex].name:''}}吗?</div>
                           <div class="modat-titile" v-show="nowIndex===-1">确定要删除所有用户吗?</div>
                         </div>
                         <div class="modal-body text-center">
                             <button class="btn btn-primary" data-dismiss="modal">取消</button>
                             <button class="btn btn-primary" data-dismiss="modal" @click="deletUser">确定</button>
                         </div>
                     </div>
                 </div>
            </div>
        </div>
         
    
    
    
        <script type="text/javascript">
            new Vue({
                el:".container",
                data:{
                    users:[
                      {name:'蜡笔小新',age:'5',email:'110@110.com'},
                      {name:'樱桃小丸子',age:'3',email:'120@120.com'}
                    ],
                    user:{},
                    nowIndex:-1
                },
                methods:{
                    addUser:function(){
                       this.users.push(this.user);
                       this.user={};
                    },
    
                    deletUser:function(){
                        if (this.nowIndex===-1) {
                            this.users=[];
                        }else{
                            this.users.splice(this.nowIndex,1);
                        }
                        
                    }
    
                }
            }); 
        </script>
    </body>
    </html>

    {{msg}} <!-- 两对大括号{{}}称为模板,用来进行数据的绑定显示在页面中 -->

    //配置是否允许vue-devtools检查代码,方便调试,默认为true,生产环境中需要设置为false
    Vue.config.devtools=false;

     //阻止vue启动时生成生产消息(提示消息)
    Vue.config.productionTip=false;

    事件对象$event 

    包含事件相关信息,如事件源、事件类型、偏移量
    target、type、offsetx

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件简写和事件对象$event</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <button @click="print($event)" >点我</button>
        </div>
    
    
        <script type="text/javascript">
            new Vue({
                el:"#app",
                methods:{
                    print:function(e){
                       console.log(e.target.innerHTML); //点我
                    }
                }
    
            });
        </script>
    </body>
    </html>

    阻止事件冒泡:
    a)原生js方式,依赖于事件对象 e.stopPropagation();

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡和默认行为</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
         <div class="app">
              <div @click="show3()">
                  <p @click="show2()">
                      <button @click="show1($event)">点我</button>
                  </p>
              </div>
         </div>
    
         <script type="text/javascript">
             new Vue({
                 el:".app",
                 methods:{
                    show1:function(e){
                          e.stopPropagation();
                      console.log("11111");
                    },
                    show2:function(){
                      console.log("22222");
                    },
                    show3:function(){
                      console.log("33333");
                    },
                 }
             });
         </script>
    
    </body>
    </html>


    b)vue方式,不依赖于事件对象e.preventDefault();
    @click.stop

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡和默认行为</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
         <div class="app">
              <div @click="show3()">
                  <p @click="show2()">
                      <button @click.stop="show1()">点我</button>
                  </p>
              </div>
         </div>
    
         <script type="text/javascript">
             new Vue({
                 el:".app",
                 methods:{
                    show1:function(){
                          
                      console.log("11111");
                    },
                    show2:function(){
                      console.log("22222");
                    },
                    show3:function(){
                      console.log("33333");
                    },
                 }
             });
         </script>
    
    </body>
    </html>

    阻止默认行为:
    a)原生js方式,依赖于事件对象

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡和默认行为</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
         <div class="app">
             <a href="https://www.baidu.com" title="" @click="change($event)">默认跳转到百度</a>
         </div>
    
         <script type="text/javascript">
             new Vue({
                 el:".app",
                 methods:{
                   change:function(e){
                      e.preventDefault();
                   }
                 }
             });
         </script>
    
    </body>
    </html>

    vue方式  @click.prevent 

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡和默认行为</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
         <div class="app">
             <a href="https://www.baidu.com" title="" @click.prevent="change()">默认跳转到百度</a>
         </div>
    
         <script type="text/javascript">
             new Vue({
                 el:".app",
                 methods:{
                   change:function(){
                     console.log('不跳转');
                   }
                 }
             });
         </script>
    
    </body>
    </html>

    键盘事件<!-- 键盘事件:@keydown、@keypress、@keyup -->

    原生js 按键的判断(回车)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>键盘事件</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <input type="text" @keydown="show($event)">
        </div>
    
        <script type="text/javascript">
            new Vue({
                el:".app",
                methods:{
                   show:function(e){
                      if(e.keyCode==13){
                          console.log('你按了回车键');
                      }
                   }
                }
            });
        </script>
    </body>
    </html>

    vue方式按键的判断(回车) 简化按键的判断

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>键盘事件</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <input type="text" @keydown.13="show()">
        </div>
    
        <script type="text/javascript">
            new Vue({
                el:".app",
                methods:{
                   show:function(){
                      
                          console.log('你按了回车键');
                      
                   }
                }
            });
        </script>
    </body>
    </html>


    回车:@keydown.13 或@keydown.enter
    上:@keydown.38 或@keydown.up

    默认没有@keydown.a/b/c...事件,可以自定义键盘事件,也称为自定义键码或自定义键位别名

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>键盘事件</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <input type="text" @keydown.a="show()">
            <input type="text" @keydown.f1.prevent="show1()">
        </div>
        <script type="text/javascript">
           Vue.config.keyCodes={
                a:65,
                f1:112
            }
    
            new Vue({
                el:".app",
                methods:{
                   show:function(){
                      
                          console.log('你按了a键');
                      
                   },
                   show1:function(){
                      
                          console.log('你按了f1键');
                      
                   }
                }
            });
        </script>
    </body>
    </html>

    事件修饰符
    .stop - 调用 event.stopPropagation()。
    .prevent - 调用 event.preventDefault()。
    .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
    .native - 监听组件根元素的原生事件。
    .once - 只触发一次回调。

    input的修饰符

    v-model.lazy.number.trim

    属性绑定和属性的简写
    v-bind 用于属性绑定, v-bind:属性=""

    属性的简写:
    v-bind:src="" 简写为 :src=""

    vue实例的属性和方法

    ### 1. 属性    

    vm.$el     vm.$data     vm.$options     vm.$refs

    ### 2. 方法    

    vm.$mount()     vm.$destroy()     vm.$nextTick(callback)

     vm.$set(object,key,value)     vm.$delete(object,key)     vm.$watch(data,callback[,options])

    能在vue之外通过vue实例的属性vm.$data直接访问vue内的数据等属性

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue实例的属性和方法</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            
        </div>
        
        <script>
          var vm = new Vue({
                el:'.app',
                data:{
                    msg:'彭彭'
                }
            });
            
            console.log(vm.$data.msg);
            console.log(vm.msg);
    
        </script>
        
    </body>
    </html>

      //vm.$el 获取vue实例关联的元素
      // console.log(vm.$el); //DOM对象
      // vm.$el.style.color='red';

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue实例的属性和方法</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            ddd
        </div>
        
        <script>
          var vm = new Vue({
                el:'.app',
                data:{
                    msg:'彭彭'
                }
            });
            
            console.log(vm.$el);
            vm.$el.style.color='red';
    
        </script>
        
    </body>
    </html>

     //vm.$options //获取自定义属性
      // console.log(vm.$options.name);
      // console.log(vm.$options.age);
      // vm.$options.show();

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue实例的属性和方法</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            ddd
        </div>
        
        <script>
          var vm = new Vue({
                el:'.app',
                data:{
                    msg:'彭彭'
                },
                name:'peng',
                age:18,
                show:function(){
                     console.log("show");
                }
          });
            
          console.log(vm.$options.name);
          console.log(vm.$options.age);
          console.log(vm.$options.show);
        </script>
        
    </body>
    </html>

    //vm.$refs 获取所有添加ref属性的元素
      // console.log(vm.$refs);
      // console.log(vm.$refs.hello); //DOM对象
      // vm.$refs.hello.style.color='blue';

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue实例的属性和方法</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <div ref="hello1">hello</div>
            <div ref="hello2"></div>
        </div>
        
        <script>
          var vm = new Vue({
                el:'.app',
                data:{
                    msg:'彭彭'
                }
            
          });
         
         console.log(vm.$refs);  
         console.log(vm.$refs.hello1); 
         vm.$refs.hello1.style.color="red";
         
        </script>
        
    </body>
    </html>

    2. 方法     vm.$mount()     vm.$destroy()     vm.$nextTick(callback)

        vm.$set(object,key,value)     vm.$delete(object,key)     vm.$watch(data,callback[,options])

    /**
       * 方法
       */
      //vm.$mount()  手动挂载vue实例
      // vm.$mount('#itany');

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue实例的方法</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            {{msg}}
        </div>
        
        <script>
          var vm = new Vue({
                
                data:{
                    msg:'彭彭'
                }
            
          });
         
         vm.$mount('.app');
         
        </script>
        
    </body>
    </html> 

    //vm.$destroy() 销毁实例  数据还在
      // vm.$destroy();

    // vm.$nextTick(callback) 在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便获取更新后的DOM

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue实例的方法</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <h1 ref="title">标题{{msg}}</h1>
            
        </div>
        
        <script>
          var vm = new Vue({
                el:'.app',
                data:{
                    msg:'彭彭'
                }
            
          });
         vm.msg='语文';
         //DOM还没更新完,Vue实现响应式并不是数据发生改变之后DOM立即变化,需要按一定的策略进行DOM更新,需要时间!!
         console.log(vm.$refs.title.textContent);
    
         vm.$nextTick(function(){
             //DOM更新完成,更新完成后再执行此代码
             console.log(vm.$refs.title.textContent);
         });
         
        </script>
        
    </body>
    </html>

     vm.$set(object,key,value) 增加属性

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加和删除属性:$set、$delete</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
          <div class="app">
               <button @click="upData()">更新name</button>
               <button @click="addData()">增加属性</button>
              <h2>{{user.name}}</h2>    
              <h1>{{user.age}}</h1>       
          </div>
    
        <script>
          var vm = new Vue({
              el:'.app',
              data:{
                  user:{
                    id:1110,
                      name:'peng',
                  }
              },
              methods:{
                upData:function(){
                    this.user.name="cai";
                },
                addData:function(){
                    //通过普通方式为对象添加属性时vue无法实时监视到
                    // this.user.age=18;
                    // console.log(this.user.age);
    
                    //通过vue实例的$set方法为对象添加属性,可以实时监视,显示在{{}}里
                    // this.$set(this.user,'age',18);
                    // console.log(this.user.age);
    
                    if(this.user.age){
                            this.user.age++;
                        }else{
                            //全局
                            Vue.set(this.user,'age',1);
                    }
                }
              }
          });
    
        </script>
        
    </body>
    </html>

    vm.$delete(object,key)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加和删除属性:$set、$delete</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
          <div class="app">
               <button @click="delData()">删除属性</button>
              <h2>{{user.name}}</h2>    
              <h1>{{user.age}}</h1>       
          </div>
    
        <script>
          var vm = new Vue({
              el:'.app',
              data:{
                  user:{
                    id:1110,
                      name:'peng',
                      age:18
                  }
              },
              methods:{
                delData:function(){
                    if(this.user.age){
                        vm.$delete(this.user,'age');
                    }
                      
                }
              }
          });
    
        </script>
        
    </body>
    </html>


    监视数据的变化使用vm.$watch(data,callback[,options])

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>监视数据的变化:$watch</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <input type="text" v-model="msg">
    
            <h1>{{msg}}</h1>
    
            <input type="text" v-model="msg2">
    
            <h1>{{msg2}}</h1>
    
    
            <input type="text" v-model="user.name">
            <h3>{{user.name}}</h3>
        </div>
    
        <script>
            vm = new Vue({
               el:".app",
               data:{
                   msg:'',
                   msg2:'msg2',
                   user:{
                       name:'peng',
                       age:18
                   }
               },
               watch:{
                     //方式2:使用vue实例提供的watch选项
                  msg2:function(newValue,oldValue){
                      console.log("msg被修改了,原值:"+oldValue+" 新值:"+newValue);
                  },
                  //深度监视,当对象中的属性发生变化时也会监视
                  user:{
                        handler:function(newValue,oldValue){
                            console.log("msg被修改了,原值:"+oldValue.name+" 新值:"+newValue.name);
                        },
                        deep:true
                  }
               }
            });
           //方式1:使用vue实例提供的$watch()方法
            vm.$watch('msg',function(newValue,oldValue){
               console.log("msg被修改了,原值:"+oldValue+" 新值:"+newValue);
            });
    
        
    
        </script>
        
    </body>
    </html>

    自定义指令     分类:全局指令、局部指令

    ### 1. 自定义全局指令     使用全局方法Vue.directive(指令ID,定义对象)

       

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自定义指令</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <p  v-peng:wbs110.heh.hah="msg">{{msg}}</p>
            <button @click="change">更新数据</button>
        </div>
    
        <script>
            Vue.directive('peng',{
                bind:function(el,binding){
                    console.log(el); //指令所绑定的元素,DOM对象
                    el.style.color="red";
                    console.log(binding);
                    console.log('这是通过指令传经来的vue里的数据:'+binding.value);
                    console.log('这是通过指令传经来的参数:'+binding.arg);
                    console.log('这是通过指令传经来的修饰符:'+binding.modifiers.heh);
                   alert('指令第一次绑定到元素上,且只执行一次,一般用于初始化!');
                },
                inserted:function(){
                    alert('被绑定元素插入到DOM时执行');
                },
                update:function(){
                    alert('被绑定元素所在的模板更新时执行');
                },
                componentUpdated:function(){
                    alert('被绑定元素所在的模板完成一次更新周期时执行');
                },
                unbind(){
                    alert('指令与元素解绑时调用,只调用一次');
                }
            });
            //传入一个简单的函数,bind和update时调用
            Vue.directive('wbs',function(){
                alert('wbs17022');
            });
    
            var vm=new Vue({
                el:".app",
                data:{
                    msg:"彭彭"
                },
                methods:{
                    change:function(){
                        this.msg="peng";
                    }
                }
            });
        </script>
        
    </body>
    </html>

    ### 2. 自定义局部指令

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自定义指令</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <input type="text" v-model="msg" v-focus>
            
        </div>
    
        <script>
    
            var vm=new Vue({
                el:".app",
                data:{
                    msg:"彭彭"
                },
                methods:{
                    change:function(){
                        this.msg="peng";
                    }
                },
                directives:{ //自定义局部指令
                    focus:{
                        //当被绑定元素插入到DOM中时获取焦点
                        inserted:function(el){
                            el.focus();
                        }
                    }
                }
            });
        </script>
        
    </body>
    </html>

    ### 3. 练习     拖动页面中的元素     onmouseover onmouseout     onmousedown onmousemove  onmouseup

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自定指令实现拖拽</title>
        <script src="js/vue.js"></script>
        <style type="text/css">
            .aa{
                
                width:100px;
                height: 100px;
                background: red;
                position:absolute;
            }
        </style>
    </head>
    <body>
        <div class="app">
            <div :class="{aa:true}" v-drag >
            
            </div>
        </div>
    
        <script>
    
            Vue.directive('drag',function(el){
                 el.onmousedown=function(e){
                     var disX=e.clientX-el.offsetLeft;
                     var disY=e.clientY-el.offsetTop;
                     
                     document.onmousemove=function(e){
                         el.style.left=(e.clientX-disX)+'px';
                         el.style.top=(e.clientY-disY)+'px';
                     }
        
                     document.onmouseup=function(e){
                        document.onmousemove=null;
                        document.onmouseup=null;
                     }
    
                 }
                
            });
            
            new Vue({
                el:".app",
    
            });
        </script>
        
    </body>
    </html>

    过渡(动画)

    ### 1. 简介
    Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果
    本质上还是使用CSS3动画:transition、animation

    ### 2. 基本用法
    使用transition组件,将要执行动画的元素包含在该组件内
    <transition>
    运动的元素
    </transition>

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动画</title>
        <script src="js/vue.js"></script>    
    </head>
    <style type="text/css">
        p{
            width: 300px;
            height: 300px;
            background: red;
        }
        .fade-enter-active,.fade-leave-active{
            transition: all 1s ease;        
        }
    
        .fade-enter-active{
            opacity: 1;
            width: 300px;
            height: 300px;
        }
        .fade-leave-active{
            opacity: 1;
            width: 100px;
            height: 100px;
        }
        .fade-enter{
            opacity: 0;
            height: 50px;
            width: 50px;
        }
    </style>
    <body>
         
         <div class="app">
             
             <button @click="flag=!flag">切换</button>
             
             <transition name="fade"
              @before-enter="beforeEnter"
                @enter="enter"
                @after-enter="afterEnter"
                @before-leave="beforeLeave"
                @leave="leave"
                @after-leave="afterLeave"
             > 
                <p  v-show="flag"></p>
            </transition>
    
         </div>
    
        <script>
            new Vue({
                el:".app",
                data:{
                    flag:false     
                },
                methods:{
                    beforeEnter(el){
                        alert('动画进入之前');
                    },
                    enter(){
                        // alert('动画进入');
                    },
                    afterEnter(el){
                        // alert('动画进入之后');
                        el.style.background='blue';
                    },
                    beforeLeave(){
                        // alert('动画即将之前');
                    },
                    leave(){
                        // alert('动画离开');
                    },
                    afterLeave(el){
                        // alert('动画离开之后');
                        el.style.background='red';
                    }
                }   
            });
        </script>
        
    </body>
    </html>


    过滤的CSS类名:6个

    ### 3. 钩子函数
    8个

    ### 4. 结合第三方动画库animate..css一起使用
    <transition enter-active-class="animated fadeInLeft" leave-active-class="animated fadeOutRight">
    <p v-show="flag">网博</p>
    </transition>

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动画</title>
        <link rel="stylesheet" href="css/animate.css">
        <script src="js/vue.js"></script>
        <style>
          p{
              width: 100px;
              height: 100px;
              background: red;
              margin: 20px auto;
          }
            
        </style>
    </head>
    <body>
          
          <div class="app">
               <button @click="flag=!flag">切换</button>
               
               <transition enter-active-class='animated hinge' leave-active-class='animated fadeOutRight'>
                   <p v-show="flag"></p>
               </transition>
          </div>
          
    
        <script>
            new Vue({
                el:".app",
                data:{
                    flag:false
                }
            });
        </script>
        
    </body>
    </html>

    ### 5. 多元素动画
    <transition-group>

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动画</title>
        <link rel="stylesheet" href="css/animate.css">
        <script src="js/vue.js"></script>
        <style>
          p{
              width: 100px;
              height: 100px;
              background: red;
              margin: 20px auto;
          }
            
        </style>
    </head>
    <body>
          
          <div class="app">
               <button @click="flag=!flag">切换</button>
               
               <transition-group enter-active-class='animated hinge' leave-active-class='animated fadeOutRight'>
                   <p v-show="flag" :key="1"></p>
                   <p v-show="flag" :key="2"></p>
               </transition-group>
          </div>
          
    
        <script>
            new Vue({
                el:".app",
                data:{
                    flag:false
                }
            });
        </script>
        
    </body>
    </html>

    ### 6. 练习
    多元素动画

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>练习:多元素动画</title>
        <link rel="stylesheet" href="css/animate.css">
        <script src="js/vue.js"></script>
        <style>
            p{
                width: 100px;
                height: 100px;
                background-color:red;
                margin:20px auto;
            }
        </style>
    </head>
    <body>
        <div id="itany">
            <input type="text" v-model="name">
            
            <transition-group enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight">
                <p v-for="(v,k) in arr2" :key="k">
                    {{v}}
                </p>
            </transition-group>
        </div>
    
        <script>
            var vm=new Vue({
                el:'#itany',
                data:{
                    flag:true,
                    arr:['tom','jack','mike','alice','alex','mark'],
                    name:''
                },
                computed:{
                    arr2:function(){
                        var temp=[];
                        this.arr.forEach(val => {
                            if(val.includes(this.name)){
                                temp.push(val);
                            }
                        });
                        return temp;
                    }
                }
            });
        </script>
        
    </body>
    </html>


    ## 一、 组件component

    ### 1. 什么是组件?
    组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码
    组件是自定义元素(对象)

    ### 2. 定义组件的方式
    方式1:先创建组件构造器,然后由组件构造器创建组件
    方式2:直接创建组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>定义组件的两种方式</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="itany">
            <hello></hello>
            <my-world></my-world>
        </div>
    
        <script>
            /**
             * 方式1:先创建组件构造器,然后由组件构造器创建组件
             */
            //1.使用Vue.extend()创建一个组件构造器
            var MyComponent=Vue.extend({
                template:'<h3>Hello World</h3>'
            });
            //2.使用Vue.component(标签名,组件构造器),根据组件构造器来创建组件
            Vue.component('hello',MyComponent);
            
            /**
             * 方式2:直接创建组件(推荐)
             */
            // Vue.component('world',{
            Vue.component('my-world',{
                template:'<h1>你好,世界</h1>'
            });
    
            var vm=new Vue({ //这里的vm也是一个组件,称为根组件Root
                el:'#itany',
                data:{
                    msg:'网博'
                }
            });    
        </script>
    </body>
    </html>

    ### 3. 组件的分类
    分类:全局组件、局部组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件的分类</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="itany">
            <my-hello></my-hello>
            <my-world></my-world>
        </div>
    
        <script>
            /**
             * 全局组件,可以在所有vue实例中使用
             */
            Vue.component('my-hello',{
                template:'<h3>{{name}}</h3>',
                data:function(){ //在组件中存储数据时,必须以函数形式,函数返回一个对象
                    return {
                        name:'alice'
                    }
                }
            });
    
            /**
             * 局部组件,只能在当前vue实例中使用
             */
            var vm=new Vue({
                el:'#itany',
                data:{
                    name:'tom'
                },
                components:{ //局部组件
                    'my-world':{
                        template:'<h3>{{age}}</h3>',
                        data(){
                            return {
                                age:25
                            }
                        }
                    }
                }
            });    
        </script>
    </body>
    </html>

    ### 4. 引用模板
    将组件内容放到模板<template>中并引用

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>引用模板</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div class="app">
            <my-comp></my-comp>
            <my-comp></my-comp>
        </div>
        <template id="tem">
            <div>
                <h3>{{msg}}</h3>
                <ul>
                    <li v-for="value in arr">{{value}}</li>
                </ul>
            </div>        
        </template>
    
        <script>
            new Vue({
                el:".app",
                components:{
                    'my-comp':{
                        template:'#tem',
                        name:'wbs17022',  //指定组件的名称,默认为标签名,可以不设置
                        data:function(){
                            return {
                                msg:'我的组件',
                                arr:['aa','bb','cc']
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

    ### 5. 动态组件
    <component :is="">组件
    多个组件使用同一个挂载点,然后动态的在它们之间切换

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动态组件</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
          <div class="app">
               <button @click="flag='my-comp1'">组件1显示</button>
               <button @click="flag='my-comp2'">组件2显示</button>
    
               <div>
                   <component :is="flag"></component>
               </div>
          </div>
    
        <script>
            new Vue({
                el:'.app',
                data:{
                    flag:'my-comp1'
                },
                components:{
                    "my-comp1":{
                        template:"<h3>组件1</h3>"
                    },
                    "my-comp2":{
                        template:"<h1>组件2</h1>"
                    }
    
    
                }
            });
            
        </script>
    </body>
    </html>


    <keep-alive>组件 <!-- 使用keep-alive组件缓存非活动组件,可以保留状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建 -->

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动态组件</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
          <div class="app">
               <button @click="flag='my-comp1'">组件1显示</button>
               <button @click="flag='my-comp2'">组件2显示</button>
    
               <div>
                   <keep-alive>
                      <component :is="flag"></component>
                  </keep-alive>
               </div>
          </div>
    
        <script>
            new Vue({
                el:'.app',
                data:{
                    flag:'my-comp1'
                },
                components:{
                    "my-comp1":{
                        template:"<h3>组件1 {{x}}</h3>",
                        data:function(){
                            return {
                                x:Math.random()
                            }
                        }
                    },
                    "my-comp2":{
                        template:"<h1>组件2 {{y}}</h1>",
                        data:function(){
                            return {
                                y:Math.random()
                            }
                        }
                    }
    
    
                }
            });
            
        </script>
    </body>
    </html>

    组件间数据传递

    ### 1. 父子组件
    在一个组件内部定义另一个组件,称为父子组件
    子组件只能在父组件内部使用
    默认情况下,子组件无法访问父组件中的数据,父组件也无法访问子组件的数据,每个组件实例的作用域是独立的

    ### 2. 组件间数据传递 (通信)

    #### 2.1 子组件访问父组件的数据
    a)在调用子组件时,绑定想要获取的父组件中的数据
    b)在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据
    总结:父组件通过props向下传递数据给子组件
    注:组件中的数据共有三种形式:data、props、computed

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>父子组件及组件间数据传递</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div class="app">
            <far-comp></far-comp>
        </div>    
        
        <template id="far">
            <div>
                <h3>我是父组件,访问自己的数据:{{farmsg}}</h3>
                <son-comp :message="farmsg"></son-comp>
            </div>
        </template>
        <template id="son">
            <div>
                <h3>我是子组件,访问自己的数据:{{sonmsg}}</h3>
                <h3>我是子组件,访问父组件的数据:{{message}}</h3>
            </div>
        </template>
        <script>
            new Vue({
                el:'.app',
                components:{
                    "far-comp":{
                        template:"#far",
                        data:function(){
                            return {
                                farmsg:'数据farmsg'
                            }
                        },
                        components:{
                            "son-comp":{
                                template:"#son",
                                props:{
                                   message:String
                                },
                                data:function(){
                                    return{
                                        sonmsg:'数据sonmsg'
                                    }
                                }
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

    #### 2.2 父组件访问子组件的数据
    a)在子组件中使用vm.$emit(事件名,数据)触发一个自定义事件,事件名自定义
    b)父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法,用来获取数据
    总结:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>父子组件及组件间数据传递</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div class="app">
            <far-comp></far-comp>
        </div>    
        
        <template id="far">
            <div>
                <h3>我是父组件,访问自己的数据:{{farmsg}}</h3>
                <h3>我是父组件,访问子组件的数据:{{sonmsg}}</h3>
                <son-comp  @my-emit="getData" ></son-comp>
            </div>
        </template>
        <template id="son">
            <div>
                <h3>我是子组件,访问自己的数据:{{sonmsg}}</h3>
                <button @click="send()">触发自定义事件发送子组件数据</button>
            </div>
        </template>
        <script>
            new Vue({
                el:'.app',
                components:{
                    "far-comp":{
                        template:"#far",
                        data:function(){
                            return {
                                farmsg:'数据farmsg',
                                sonmsg:''
                            }
                        },
                        methods:{
                            getData:function(sonmsg){
                                console.log(sonmsg);
                                 this.sonmsg=sonmsg;
                            }
                        },
                        components:{
                            "son-comp":{
                                template:"#son",
                                data:function(){
                                    return{
                                        sonmsg:'数据sonmsg'
                                    }
                                },
                                methods:{
                                    send:function(){
                                        console.log(this.sonmsg); //此处的this表示当前子组件实例
                                        console.log("执行了send()函数");
                                        this.$emit('my-emit',this.sonmsg);//使用$emit()触发一个事件,发送数据
                                    }
                                }
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

    ### 3. 单向数据流

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>单向数据流</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div class="app">
            <h3>我是父组件,我的数据是{{msg}}</h3>
            <son-comp :msg="msg"></son-comp>
        </div>
        
        <template id="son">
            <div>
                <h1>我是子组件,我的数据是:{{sonmsg}}</h1>
                <h1>我是子组件,我接收父组件数据是:{{msg}}</h1>
            </div>
        </template>
    
        <script>
        var vm = new Vue({
                el:".app",
                data:{
                    msg:'父数据msg'
                },
                components:{
                    'son-comp':{
                        template:"#son",
                        props:{
                            msg:String
                        },
                        data:function(){
                            return {
                                sonmsg:"子数据sonmsg",
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

    props是单向绑定的,当父组件的属性变化时,将传导给子组件,但是不会反过来
    而且不允许子组件直接修改父组件中的数据,报错
    解决方式:
    方式1:如果子组件想把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>子组件想把从父组件得到的数据作为局部数据来使用</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div class="app">
            <h3>我是父组件,我的数据是{{msg}}</h3>
            <son-comp :msg="msg"></son-comp>
        </div>
        
        <template id="son">
            <div>
                <h1>我是子组件,我的数据是:{{sonmsg}}</h1>
                <h1>我是子组件,我接收父组件数据是:{{msg}}</h1>
                <h1>我是子组件,我接收父组件数据存到自己的data里:{{sonFar}}</h1>
                <input type="text" v-model="sonFar">
            </div>
        </template>
    
        <script>
        var vm = new Vue({
                el:".app",
                data:{
                    msg:'父数据msg'
                },
                components:{
                    'son-comp':{
                        template:"#son",
                        props:{
                            msg:String
                        },
                        data:function(){
                            return {
                                sonmsg:"子数据sonmsg",
                                sonFar:this.msg
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>


    方式2:如果子组件想修改数据并且同步更新到父组件,两个方法:
    a.使用.sync(1.0版本中支持,2.0版本中不支持,2.3版本又开始支持)
    需要显式地触发一个更新事件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>子组件想修改数据并且同步更新到父组件</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div class="app">
            <h3>我是父组件,我的数据是{{msg}}</h3>
            <son-comp :msg.sync="msg"></son-comp>
        </div>
        
        <template id="son">
            <div>
                <h1>我是子组件,我的数据是:{{sonmsg}}</h1>
                <h1>我是子组件,我接收父组件数据是:{{msg}}</h1>
                <button @click="change()">子组件修改接收到父组件数据</button>
            </div>
        </template>
    
        <script>
        var vm = new Vue({
                el:".app",
                data:{
                    msg:'父数据msg'
                },
                components:{
                    'son-comp':{
                        template:"#son",
                        props:{
                            msg:String
                        },
                        data:function(){
                            return {
                                sonmsg:"子数据sonmsg",
                            }
                        },
                        methods:{
                            change:function(){
                                this.$emit('update:msg','子组件修改接收到父组件数据msg');
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>


    b.可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(因为对象是引用类型,指向同一个内存空间),推荐

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>子组件想修改数据并且同步更新到父组件(推荐)</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div class="app">
            <h3>我是父组件,我的数据是{{user.msg}}</h3>
            <son-comp :user="user"></son-comp>
        </div>
        
        <template id="son">
            <div>
                <h1>我是子组件,我的数据是:{{sonmsg}}</h1>
                <h1>我是子组件,我接收父组件数据是:{{user.msg}}</h1>
                <button @click="change()">子组件修改接收到父组件数据</button>
            </div>
        </template>
    
        <script>
        var vm = new Vue({
                el:".app",
                data:{
                    user:{
                      msg:'父数据msg'
                    }                
                },
                components:{
                    'son-comp':{
                        template:"#son",
                        props:['user'],
                        data:function(){
                            return {
                                sonmsg:"子数据sonmsg",
                            }
                        },
                        methods:{
                            change:function(){
                                this.user.msg="子组件修改接收到父组件数据";
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

    ### 4. 非父子组件间的通信
    非父子组件间的通信,可以通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件

    var Event=new Vue();
    Event.$emit(事件名,数据);
    Event.$on(事件名,data => {});

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>非父子组件间的通信(数据比较简单时使用)</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
         <div class="app">
            <a-comp></a-comp>
            <b-comp></b-comp>    
         </div>
         
         <template id="a">
             <div>
                 <h3>我是a组件,我的数据是:{{msg}}</h3>
                <button @click="change()">把自己的数据msg发出去</button>
             </div>
         </template>
         <template id="b">
             <h1>我是b组件,我接收的数据是:{{msg}}</h1>
         </template>
        <script>
            var bush=new Vue();
            new Vue({
                el:".app",
                components:{
                    'a-comp':{
                        template:"#a",
                        data:function(){
                            return {
                                msg:"a组件的msg"
                            }
                        },
                        methods:{
                            change:function(){
                               bush.$emit('e-send',this.msg);
                            }
                        }
                    },
                    'b-comp':{
                        template:"#b",
                        data:function(){
                            return {
                             msg:''    
                            }
                        },
                        mounted:function(){
                            //这里不能用function(msg){因为这里面的this指向调用它bush,而不是指向b-comp。所以要用msg=>,不改变this。还要注意:监听一定要在触发e-send事件之前,否则会监听不到e-send事件带来的数据}
                            bush.$on('e-send',msg=>{
                                this.msg=msg;
                            });
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

    slot内容分发
    本意:位置、槽
    作用:用来获取组件中的原内容

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>slot内容分发</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    
        <div class="app">
            <my-comp>我是组件里填的内容</my-comp>
        </div>
         <template id="my">
             <div>
                 <h3>我是组件</h3>
                 <slot></slot>
             </div>
         </template>
        <script>
          new Vue({
              el:".app",
              components:{
                  "my-comp":{
                      template:'#my',
    
                  }
              }
          });
            
        </script>
    </body>
    </html>

    组件里的内容会替换slot里的内容

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>slot内容分发</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    
        <div class="app">
            <my-comp>我是组件里填的内容</my-comp>
        </div>
         <template id="my">
             <div>
                 <h3>我是组件</h3>
                 <slot>我是slot里的内容</slot>
             </div>
         </template>
        <script>
          new Vue({
              el:".app",
              components:{
                  "my-comp":{
                      template:'#my',
    
                  }
              }
          });
            
        </script>
    </body>
    </html>

    具名solt:决定组件里的内容是否显示以及显示的位置

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>slot内容分发</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    
        <div class="app">
            <my-comp>
                <div slot="content1">
                    我是内容一
                </div>
                <div>
                    我是内容二
                </div>
            </my-comp>
        </div>
         <template id="my">
             <div>
                 <h3>我是组件</h3>
                 <slot name="content1"></slot>
             </div>
         </template>
        <script>
          new Vue({
              el:".app",
              components:{
                  "my-comp":{
                      template:'#my',
    
                  }
              }
          });
            
        </script>
    </body>
    </html>

    vue-router路由

    ### 1. 简介
    使用Vue.js开发SPA(Single Page Application)单页面应用
    根据不同url地址,显示不同的内容,但显示在同一个页面中,称为单页面应用

    [参考](https://router.vuejs.org/zh-cn)

    bower info vue-router
    cnpm install vue-router -S

    ### 2. 基本用法
    a.布局
    b.配置路由

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>路由基本用法</title>
        <script src="js/vue.js"></script>
        <script src="js/vue-router.js"></script>
    </head>
    <body>
         <div class="app">
             <div>
                 <router-link to="/us">我们</router-link>
                 <router-link to="/news">新闻</router-link>
             </div>
             <div>
                 <router-view></router-view>
             </div>
         </div>
    
        <script>
            var Us={
                template:"<h1>联系我们</h1>"
            };
            var News={
                template:"<h3>新闻内容</h3>"
            };
    
            const routes=[
               {path:'/us',component:Us},
               {path:'/news',component:News}
            ];
            const router = new VueRouter({
                routes:routes
            });
    
            new Vue({
                el:".app",
                router:router
            });
            
            
        </script>
    </body>
    </html>

    模式、激活class、重定向

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>路由基本用法</title>
        <script src="js/vue.js"></script>
        <script src="js/vue-router.js"></script>
        <style type="text/css">
            .router-link-active{
                text-decoration: none;
                font-size: 36px;
                color: red;
            }
        </style>
    </head>
    <body>
         <div class="app">
             <div>
                 <router-link to="/us">我们</router-link>
                 <router-link to="/news">新闻</router-link>
             </div>
             <div>
                 <router-view></router-view>
             </div>
         </div>
    
        <script>
            var Us={
                template:"<h1>联系我们</h1>"
            };
            var News={
                template:"<h3>新闻内容</h3>"
            };
    
            const routes=[
               {path:'*',redirect:'/us'},
               {path:'/us',component:Us},
               {path:'/news',component:News}
            ];
            const router = new VueRouter({
                routes:routes,
                // mode:"history",
                // linkActiveClass:'active' //更新活动链接的class类名
                
            });
    
            new Vue({
                el:".app",
                router:router
            });
            
            
        </script>
    </body>
    </html>

    ### 3. 路由嵌套和参数传递

    路由嵌套

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>路由嵌套</title>
        <script src="js/vue.js"></script>
        <script src="js/vue-router.js"></script>
        <style type="text/css">
        .router-link-active{
            font-size:20px;
            color:#ff7300;
            text-decoration:none;
        }
        </style>
    </head>
    <body>
    <div class="app">
        <div>
            <router-link to="/home">主页</router-link>
            <router-link to="/user">用户</router-link>
        </div>    
        <div>
            <router-view></router-view>
        </div>
        
    </div>    
      
    
     <template id="user">
         <div>
             <h3>用户信息</h3>
             <ul>
                 <router-link to="/user/login" tag="li">注册</router-link>
                <router-link to="/user/regist" tag="li">登陆</router-link>
             </ul>        
             <router-view></router-view>         
         </div>
     </template>
    <script type="text/javascript">
    
        var Home={
            template:"<h3> 主页内容</h3>"
        };
        var User={
            template:"#user"
            // template:"<h2>yon</h2>"
        };
        var Regist={
            template:"<h1>登陆页面。。。。</h1>"
        };
        var Login={
            template:"<h1>注册页面。。。</h1>"
        };
        const routes=[
          {
            path:"/Home",
            component:Home
          },
          {
              path:"/user",
              component:User,
            children:[
             {
                 path:'regist',
                 component:Regist
             },
             {
                 path:'login',
                 component:Login
             }
            ]
          }
          
        ];
        const router=new VueRouter({
            routes:routes
        });
        new Vue({
            el:".app",
            router:router
        });
    </script>    
    </body>
    </html>


    传参的两种形式:
    a.查询字符串:login?name=tom&pwd=123
    {{$route.query}}
    b.rest风格url:regist/alice/456
    {{$route.params}}

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>路由传参数</title>
        <script src="js/vue.js"></script>
        <script src="js/vue-router.js"></script>
        <style type="text/css">
        .router-link-active{
            font-size:20px;
            color:#ff7300;
            text-decoration:none;
        }
        </style>
    </head>
    <body>
    <div class="app">
        <div>
            <router-link to="/home">主页</router-link>
            <router-link to="/user">用户</router-link>
        </div>  
        <div>
            <router-view></router-view>
        </div>
        
    </div>  
      
    
     <template id="user">
        <div>
            <h3>用户信息</h3>
            <ul>
                <router-link to="/user/login?name=peng&pwd=123" tag="li">注册</router-link>
                <router-link to="/user/regist/peng/123" tag="li">登陆</router-link>
            </ul>       
            <router-view></router-view>         
        </div>
     </template>
    <script type="text/javascript">
    
        var Home={
            template:"<h3> 主页内容</h3>"
        };
        var User={
            template:"#user"
        };
        var Regist={
            template:"<h1>登陆页面。。。。获取的参数是:{{$route.params}}</h1>"
        };
        var Login={
            template:"<h1>注册页面。。。获取的参数是:{{$route.query}}</h1>"
        };
        const routes=[
          {
            path:"/Home",
            component:Home
          },
          {
            path:"/user",
            component:User,
            children:[
             {
                path:'regist/:name/:pwd',
                component:Regist
             },
             {
                path:'login',
                component:Login
             }
            ]
          }
          
        ];
        const router=new VueRouter({
            routes:routes
        });
        new Vue({
            el:".app",
            router:router
        });
    </script>   
    </body>
    </html>


    ### 4. 路由实例的方法
    router.push() 添加路由,功能上与<route-link>相同

    router.replace() 替换路由,不产生历史记录

     <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>路由切换</title>
        <script src="js/vue.js"></script>
        <script src="js/vue-router.js"></script>
        <style type="text/css">
        .router-link-active{
            font-size:20px;
            color:#ff7300;
            text-decoration:none;
        }
        </style>
    </head>
    <body>
    <div class="app">
        <div>
            <router-link to="/home">主页</router-link>
            <router-link to="/user">用户</router-link>
        </div>  
        <div>
            <router-view></router-view>
        </div>
        <button @click="change()">切换路由</button>
        <button @click="replace()">替换路由</button>
        
    </div>  
      
    
     <template id="user">
        <div>
            <h3>用户信息</h3>
            <ul>
                <router-link to="/user/login" tag="li">注册</router-link>
                <router-link to="/user/regist" tag="li">登陆</router-link>
            </ul>       
            <router-view></router-view>         
        </div>
     </template>
    <script type="text/javascript">
    
        var Home={
            template:"<h3> 主页内容</h3>"
        };
        var User={
            template:"#user"
            // template:"<h2>yon</h2>"
        };
        var Regist={
            template:"<h1>登陆页面。。。。</h1>"
        };
        var Login={
            template:"<h1>注册页面。。。</h1>"
        };
        const routes=[
          {
            path:"/home",
            component:Home
          },
          {
            path:"/user",
            component:User,
            children:[
             {
                path:'regist',
                component:Regist
             },
             {
                path:'login',
                component:Login
             }
            ]
          }
          
        ];
        const router=new VueRouter({
            routes:routes
        });
        new Vue({
            el:".app",
            router:router,
            methods:{
                change:function(){
                    router.push({path:'home'});
                },
                replace:function(){
                    router.replace({path:'user'});
                }
            }
        });
    </script>   
    </body>
    </html>

    ### 5. 路由结合动画

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>路由结合动画</title>
        <link rel="stylesheet" href="css/animate.css">
        <script src="js/vue.js"></script>
        <script src="js/vue-router.js"></script>
        <style type="text/css">
        .router-link-active{
            font-size:20px;
            color:#ff7300;
            text-decoration:none;
        }
        </style>
    </head>
    <body>
    <div class="app">
        <div>
            <router-link to="/home">主页</router-link>
            <router-link to="/user">用户</router-link>
        </div>  
        <div>
            <transition enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight">
            <transition enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight">
                <router-view></router-view>
            </transition>        
        </div>
        
    </div>  
      
    
     <template id="user">
        <div>
            <h3>用户信息</h3>
            <ul>
                <router-link to="/user/login" tag="li">注册</router-link>
                <router-link to="/user/regist" tag="li">登陆</router-link>
            </ul>    
                 <router-view></router-view>
        </div>
     </template>
    <script type="text/javascript">
    
        var Home={
            template:"<h3> 主页内容</h3>"
        };
        var User={
            template:"#user"
            // template:"<h2>yon</h2>"
        };
        var Regist={
            template:"<h1>登陆页面。。。。</h1>"
        };
        var Login={
            template:"<h1>注册页面。。。</h1>"
        };
        const routes=[
          {
            path:"/Home",
            component:Home
          },
          {
            path:"/user",
            component:User,
            children:[
             {
                path:'regist',
                component:Regist
             },
             {
                path:'login',
                component:Login
             }
            ]
          }
          
        ];
        const router=new VueRouter({
            routes:routes
        });
        new Vue({
            el:".app",
            router:router
        });
    </script>   
    </body>
    </html>

    .vue文件
    .vue文件,称为单文件组件,是Vue.js自定义的一种文件格式,一个.vue文件就是一个单独的组件,在文件内封装了组件相关的代码:html、css、js

    .vue文件由三部分组成:<template>、<style>、<script>
    <template>
    html
    </template>

    <style>
    css
    </style>

    <script>
    js
    </script>

    ### 2. vue-loader
    浏览器本身并不认为.vue文件,所以必须对.vue文件进行加载解析,此时需要vue-loader
    类似的loader还有许多,如:html-loader、css-loader、style-loader、babel-loader等
    需要注意的是vue-loader是基于webpack的

    ### 3. webpack
    webpack是一个前端资源模板化加载器和打包工具,它能够把各种资源都作为模块来使用和处理
    实际上,webpack是通过不同的loader将这些资源加载后打包,然后输出打包后文件
    简单来说,webpack就是一个模块加载器,所有资源都可以作为模块来加载,最后打包输出

    [官网](http://webpack.github.io/)

    webpack版本:v1.x v2.x

    webpack有一个核心配置文件:webpack.config.js,必须放在项目根目录下

    示例,步骤:

    #### 4.1 创建项目,目录结构 如下:
    webpack-demo
    |-index.html
    |-main.js 入口文件
    |-App.vue vue文件
    |-package.json 工程文件
    |-webpack.config.js webpack配置文件
    |-.babelrc Babel配置文件

    ### 4.2 编写App.vue

    ### 4.3 安装相关模板
    cnpm install vue -S

    cnpm install webpack -D  //生产依赖
    cnpm install webpack-dev-server -D  // 访问webpack,搭建服务器

    cnpm install vue-loader -D  
    cnpm install vue-html-loader -D 
    cnpm install css-loader -D
    cnpm install vue-style-loader -D
    cnpm install file-loader -D  //用到字体字库

    cnpm install babel-loader -D   //ES6语法
    cnpm install babel-core -D    //核心
    cnpm install babel-preset-env -D //根据配置的运行环境自动启用需要的babel插件
    cnpm install vue-template-compiler -D //预编译模板

    合并:cnpm install -D webpack webpack-dev-server vue-loader vue-html-loader css-loader vue-style-loader file-loader babel-loader babel-core babel-preset-env vue-template-compiler

    ### 4.4 编写main.js

    /**
     * 使用ES6语法引入模板
     */
    import Vue from 'vue'  //会去node_modules去找(vue装在这里),
    import App from './App.vue' //虽然在同一目录,但因为它不是内部模块,而是自定义模块,所以要加 ./
    
    new Vue({
        el:'#app', //App.vue里要应用
        render:function(h){ //使用render函数渲染组件 :组件注册等价与components
            return h(App);
        }
    });

    ### 4.5 编写webpack.config.js

    module.exports={
        //配置入口文件
        entry:'./main.js',
        //配置入口文件输出位置
        output:{
            path:__dirname, //项目根路径
            filename:'build.js'
        },
        //配置模块加载器
        module:{
            rules:[
                {
                    test:/.vue$/, //所有以.vue结尾的文件都由vue-loader加载
                    loader:'vue-loader'
                },
                {
                    test:/.js$/, //所有以.js结尾的文件都由babel-loader加载,除了node_modules以外
                    loader:'babel-loader',
                    exclude:/node_modules/
                }
            ]
        }
    }

    ### 4.6 编写.babelrc

    {
        "presets":[
            ["env",{"module":false}]
        ]
    }

    ### 4.7 编写package.json

    {
      "name": "webpack-demo",
      "version": "1.0.0",
      "description": "",
      "main": "main.js",
      "scripts": {
        "dev":"webpack-dev-server --open --hot --port 8800"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "vue": "^2.3.4"
      },
      "devDependencies": {
        "babel-core": "^6.25.0",
        "babel-loader": "^7.1.1",
        "babel-preset-env": "^1.5.2",
        "css-loader": "^0.28.4",
        "file-loader": "^0.11.2",
        "vue-html-loader": "^1.2.4",
        "vue-loader": "^13.0.0",
        "vue-style-loader": "^3.0.1",
        "vue-template-compiler": "^2.3.4",
        "webpack": "^3.0.0",
        "webpack-dev-server": "^2.5.0"
      }
    }

    ### 4.8 运行测试
    npm run dev

    vue-cli脚手架

    ### 1. 简介
    vue-cli是一个vue脚手架,可以快速构造项目结构
    vue-cli本身集成了多种项目模板:
    simple 很少简单
    webpack 包含ESLint代码规范检查和unit单元测试等
    webpack-simple 没有代码规范检查和单元测试
    browserify 使用的也比较多
    browserify-simple

    ### 2. 示例,步骤:

    #### 2.1 安装vue-cli,配置vue命令环境
    cnpm install vue-cli -g
    vue --version
    vue list

    #### 2.2 初始化项目,生成项目模板
    语法:vue init 模板名 项目名

    #### 2.3 进入生成的项目目录,安装模块包
    cd vue-cli-demo
    cnpm install

    #### 2.4 运行
    npm run dev //启动测试服务
    npm run build //将项目打包输出dist目录,项目上线的话要将dist目录拷贝到服务器上

    ### 3. 使用webpack模板
    vue init webpack vue-cli-demo2

    ESLint是用来统一代码规范和风格的工具,如缩进、空格、符号等,要求比较严格
    [官网](http://eslint.org)

    问题Bug:如果版本升级到node 8.0 和 npm 5.0,控制台会报错:
    GET http://localhost:8080/__webpack_hmr net::ERR_INCOMPLETE_CHUNKED_ENCODING
    解决方法:
    a)降低Node版本到7.9或以下
    b)修改build/dev-server.js文件,如下:
    var hotMiddleware = require('webpack-hot-middleware')(compiler, {
    log: () => {},
    heartbeat:2000 //添加此行
    })
    参考:https://github.com/vuejs-templates/webpack/issues/731

    一个项目从开始

    2.1 安装vue-cli,配置vue命令环境
    cnpm install vue-cli -g
    vue --version
    vue list

    #### 2.2 初始化项目,生成项目模板
    语法:vue init 模板名(webpack-simple) 项目名

    <? License (MIT) no
    ? License no
    ? Use sass? (y/N) N
    ? Use sass? No
    >

    #### 2.3 进入生成的项目目录,安装模块包
    cd vue-cli-demo
    cnpm install

    #### 2.4 运行
    npm run dev //启动测试服务
    <用vue-router
    cnpm install vue-router -S
    >

    npm run build //将项目打包输出dist目录,项目上线的话要将dist目录拷贝到服务器上

    模块化开发

    ### 1. vue-router模块化
    cnpm install vue-router -S

    #### 1.1 编辑main.js

    #### 1.2 编辑App.vue

    <template>
      <div id="app">
         <div>
             <router-link to="/home">主页</router-link>
             <router-link to="/news">新闻</router-link>
         </div>
         <keep-alive>
            <router-view></router-view>
         </keep-alive>
      </div>
    </template>
    
    <script>
    export default {
      name: 'app',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      },
       mounted:function(){
        console.log(this.$route)
      },
      watch:{
        $route:function(newValue,oldValue){
            console.log('路由发生了变化,跳转到:'+oldValue.path);
        }
      }
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    
    h1, h2 {
      font-weight: normal;
    }
    
    ul {
      list-style-type: none;
      padding: 0;
    }
    
    li {
      display: inline-block;
      margin: 0 10px;
    }
    
    a {
      color: #42b983;
    }
    </style>

    #### 1.3 编辑router.config.js

    ### 2. axios模块化
    cnpm install axios -S

    使用axios的两种方式:
    方式1:在每个组件中引入axios

    <template>
      <div id="app">
         <div>
             <router-link to="/home">主页</router-link>
             <router-link to="/news">新闻</router-link>
         </div>
         <keep-alive>
            <router-view></router-view>
         </keep-alive>
    
    
         <hr>
      <button @click="send">发送AJAX请求</button>
      </div>
    </template>
    
    <script>
    import axios from 'axios'
    export default {
      name: 'app',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      },
       mounted:function(){
        console.log(this.$route)
      },
      watch:{
        $route:function(newValue,oldValue){
            console.log('路由发生了变化,跳转到:'+oldValue.path);
        }
      },
      methods:{
        send:function(){
           axios.get('https://api.github.com/users/tangyang8942')
           .then(function(resp){
              console.log(resp);
           }).catch(function(){
               console.log('请求失败');
           });
        }
      }
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    
    h1, h2 {
      font-weight: normal;
    }
    
    ul {
      list-style-type: none;
      padding: 0;
    }
    
    li {
      display: inline-block;
      margin: 0 10px;
    }
    
    a {
      color: #42b983;
    }
    </style>


    方式2:在main.js中全局引入axios并添加到Vue原型中

    ### 3. 为自定义组件添加事件

     <Mybutton @click.native="send"></Mybutton>

    Elment UI

    ### 1. 简介
    Element UI是饿了么团队提供的一套基于Vue2.0的组件库,可以快速搭建网站,提高开发效率
    ElementUI PC端
    MintUI 移动端

    [官网](http://element.eleme.io/)

    ### 2. 快速上手

    #### 2.1 安装elment ui
    cnpm install element-ui -S

    #### 2.2 在main.js中引入并使用组件
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-default/index.css' //该样式文件需要单独引入
    Vue.use(ElementUI);
    这种方式引入了ElementUI中所有的组件

    #### 2.3 在webpack.config.js中添加loader
    CSS样式和字体图标都需要由相应的loader来加载,所以需要style-loader、css-loader

    默认并没有style-loader模块,所以需要单独安装
    cnpm install style-loader --save-dev

    <template>
      <div id="app">
    
        <h1>{{ msg }}</h1>
        <hr>
        <el-button type="primary">我的按钮</el-button>
        <el-button round>圆角按钮</el-button>
      <el-button icon="el-icon-search" circle></el-button>
      <el-button type="primary" icon="el-icon-edit" circle></el-button>
      <el-button type="success" icon="el-icon-check" circle></el-button>
      <el-button type="info" icon="el-icon-message" circle></el-button>
      <el-button type="warning" icon="el-icon-star-off" circle></el-button>
      <el-button type="danger" icon="el-icon-delete" circle></el-button>
        
      </div>
    </template>
    
    <script>
    export default {
      name: 'app',
      data () {
        return {
          msg: '彭彭'
        }
      }
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    
    h1, h2 {
      font-weight: normal;
    }
    
    ul {
      list-style-type: none;
      padding: 0;
    }
    
    li {
      display: inline-block;
      margin: 0 10px;
    }
    
    a {
      color: #42b983;
    }
    </style>

    #### 2.4 使用组件

    #### 2.5 使用less
    安装loader,需要两个:less、less-loader
    cnpm install less less-loader -D
    在webpack.config.js中添加loader

    ### 3. 按需引入组

    #### 3.1 安装babel-plugin-component
    cnpm install babel-plugin-component -D

    #### 3.2 配置.babelrc文件
    "plugins": [["component", [
    {
    "libraryName": "element-ui",
    "styleLibraryName": "theme-default"
    }
    ]]]

    #### 3.3 只引入需要的插件


    ## 三、 自定义全局组件(插件)

    全局组件(插件):就是指可以在main.js中使用Vue.use()进行全局引入,然后在其他组件中就都可以使用了,如vue-router
    import VueRouter from 'vue-router'
    Vue.use(VueRouter);

    普通组件(插件):每次使用时都要引入,如axios
    import axios from 'axios'

    Vuex

    ### 1. 简介
    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
    简单来说,用来集中管理数据,类似于React中的Redux,都是基于Flux的前端状态管理框架

    ### 2. 基本用法

    #### 2.1 安装vuex
    cnpm install vuex -S

    #### 2.2 创建store.js文件,在main.js中导入并配置store.选项

    #### 2.3 编辑store.js文件
    Vuex的核心是Store(仓库),相当于是一个容器,一个store实例中包含以下属性的方法:
    state 定义属性(状态、数据)
    getters 用来获取属性
    actions 定义方法(动作)
    commit 提交变化,修改数据的唯一方式就是显式的提交mutations
    mutations 定义变化
    注:不能直接修改数据,必须显式提交变化,目的是为了追踪到状态的变化

    #### 2.4 编辑App.vue
    在子组件中访问store对象的两种方式:
    方式1:通过this.$store访问
    方式2:通过mapState、mapGetters、mapActions访问,vuex提供了两个方法:
    mapState 获取state
    mapGetters 获取getters
    mapActions 获取actions

    ### 3. 分模块组织Vuex

    |-src
          |-store
                 |-index.js
                 |-getters.js
                 |-actions.js
                 |-mutations.js
                 |-modules //分为多个模块,每个模块都可以拥有自己的state、getters、actions、mutations
                        |-user.js
                        |-cart.js
                        |-goods.js
                        |....

    ## 一、 准备工作

    ###1. 初始化项目
    vue init webpack itany
    cd itany
    cnpm install
    cnpm install less less-loader -D
    cnpm install vuex axios -S
    npm run dev

    ### 2. 项目资源
    |-reset.css
    |-data.json

    ### 3. 创建目录结构
    首先清除项目中的部分内容

    创建如下目录结构:
    |-data.json
    |-static
         |-css
              |-reset.css

    ### 4. 配置API接口,模拟后台数据
    使用express框架启动一个Node服务器,配置API接口,模拟后台数据

    测试API:
    http://localhost:8080/api/seller
    http://localhost:8080/api/goods
    http://localhost:8080/api/ratings


    ## 二、项目整体结构开发

  • 相关阅读:
    gvim : invalid input string
    端口
    Sequence Overview
    vi的使用
    Ubuntu安装CodeBlocks相关问题总结
    中断
    Ubuntu Software Repository
    UVA 12299 RMQ with Shifts
    UVA 12293 Box Game
    POJ 3468 A Simple Problem with Integers (1)
  • 原文地址:https://www.cnblogs.com/pengc/p/9048017.html
Copyright © 2020-2023  润新知