重开Vue2.0

目录:javascript

 

内容:css

1、Vue内部指令:html

  一、v-if v-else&v-showvue

v-if与v-show都是选择性显示内容的指令,可是两者之间有区别:java

一、v-if:判断是否加载,在须要的时候加载,减小服务器压力node

二、v-show:调整css display属性,使客户端操做更加流畅python

v-if:jquery

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <div v-if="islog">加载</div>
        <!--<div v-else-if="iselse">能够加载</div>-->
        <div v-else="islog">不加载</div>
    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                   islog: false,
                    iselse: true //若是islog=true时,后面两个不显示   
                                      //当islog为false v-else-if为true 显示第二个内容 ,当第二个为alse显示最后一个
                }
            })
        }

    </script>
</body>
</html>
View Code

v-show:webpack

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <div v-show="islog">加载</div>

    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                   islog: true
                }
            })
        }

    </script>
</body>
</html>
View Code

 

  二、v-for 循环模式git

    1. 普通循环模式:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="item in items">
                {{item}}
            </li>
        </ul>

    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                   items: [45,32,77,36,8,54]
                }
            })
        }

    </script>
</body>
</html>
View Code

      2. 数组排序循环:普通排序有个问题就是只能按照一位一位来进行,因此须要下面的方法来修正

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="item in sortItems">
                {{item}}
            </li>
        </ul>

    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                   items: [45,32,77,36,8,54]
                },
                computed:{ //使用computed对items进行排序
                    sortItems:function () {//在排序时,computed中的变量名必须和原来不一样
                        return this.items.sort();

                    }
                }
            })
        }

    </script>
</body>
</html>
View Code

      3. 加强型数字数组排序:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="item in sortItems">
                {{item}}
            </li>
        </ul>

    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                   items: [45,32,77,36,8,54]
                },
                computed:{ //使用computed对items进行排序
                    sortItems:function () {//在排序时,computed中的变量名必须和原来不一样
                        return this.items.sort(sortNumber);//引入排序函数

                    }
                }
            });
            function sortNumber(a,b) {//添加排序函数
                return a-b;
            }
        };
        

    </script>
</body>
</html>
View Code

      4. 数组中增长对象排序:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="item in sortItems">
                {{item}}
            </li>
        </ul>
        <ul>
            <li v-for="(student,index) in sortStudent"> <!-- Vue2.0中排序时,index在value后面   -->
                {{index}}: {{student.name}}-{{student.age}}
            </li>
        </ul>
    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                    items: [45,32,77,36,8,54],
                    students:[
                        {name:'JSPang',age:33},
                        {name:'JS',age:22},
                        {name:'Pang',age:14},
                        {name:'keke',age:50}
                    ]
                },
                computed:{ //使用computed对items进行排序
                    sortItems:function () {//在排序时,computed中的变量名必须和原来不一样
                        return this.items.sort(sortNumber);//引入排序函数

                    },
                    sortStudent: function () {
                        return sortByKey(this.students, 'age');
                    }

                }
            });
            function sortNumber(a,b) {//添加排序函数
                return a-b;
            };
            //数组对象方法排序:
            function sortByKey(arrary,key) {
                return arrary.sort(function (a,b) {
                    var x=a[key];
                    var y=b[key];
                    return ((x<y)?-1:((x>y)?1:0));
                });

            }
        };


    </script>
</body>
</html>
View Code

 

  三、v-text  v-html

其中v-html不推荐使用,由于会形成代码泄漏引起安全问题,v-text能够改善因为各类问题而致使模板{{}}没有渲染成功的问题,若是没有渲染成功v-text不显示内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app" v-text="message">

    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                    message: 'hello world'
                }
            });



        };


    </script>
</body>
</html>
View Code

 

  四、v-on

  v-on对应的是绑定事件并用来监听

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        本厂比赛得分: <span v-text="record"></span><br>
        <button v-on:click="addscore">加分</button>
        <button @click="reducescore">减分</button>
        <br>
        <input type="text" @keyup.enter="onEnter" v-model="incrscore">
    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                    record: 0,
                    incrscore:0
                },
                methods:{
                    addscore:function () {
                        this.record++
                    },
                    reducescore:function () {
                        if(this.record <= 0){
                            this.record = 0
                        }else{
                            this.record--
                        }
                    },
                    onEnter:function () {
                        this.record=this.record+parseInt(this.incrscore);//有坑 须要将后面转换为数字形式
                    }
                }
            });



        };


    </script>
</body>
</html>
View Code

 

  五、v-model

  双向数据绑定

  v-model分为几个不一样类型:

       一、文本框类型:

      1.v-model.lazy表示在光标离开后才生效

      2.v-model.number表示只能够输入数字

      3.v-model.trim表示去空格

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <p>
    <h3>文本框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p>普通类型:<input type="text" v-model="message"></p>
    <p>lazy:<input type="text" v-model.lazy="message"></p>
    <p>number:<input type="text" v-model.number="message"></p>
    <p>trim:<input type="text" v-model.trim="message"></p>
    </p>
    <p>
    <h3>多区域框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p></p>
    </p>
</div>
<script type="text/javascript">
    window.onload = function () {
        var app = new Vue({
            el: '#app',
            data: {
                message: ''
            }
        })
    }

</script>
</body>
</html>
View Code

 

    二、多区域框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <p>
    <h3>文本框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p>普通类型:<input type="text" v-model="message"></p>
    <p>lazy:<input type="text" v-model.lazy="message"></p>
    <p>number:<input type="text" v-model.number="message"></p>
    <p>trim:<input type="text" v-model.trim="message"></p>
    </p>
    <p>
    <h3>多区域框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p><textarea cols="30" rows="10" v-model="message"></textarea></p>
    </p>
</div>
<script type="text/javascript">
    window.onload = function () {
        var app = new Vue({
            el: '#app',
            data: {
                message: ''
            }
        })
    }

</script>
</body>
</html>
View Code

    三、多选框选中一个值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <p>
    <h3>文本框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p>普通类型:<input type="text" v-model="message"></p>
    <p>lazy:<input type="text" v-model.lazy="message"></p>
    <p>number:<input type="text" v-model.number="message"></p>
    <p>trim:<input type="text" v-model.trim="message"></p>
    </p>
    <p>
    <h3>多区域框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p><textarea cols="30" rows="10" v-model="message"></textarea></p>
    </p>
    <p>
    <h3>多选框绑定一个值</h3>
    <input type="checkbox" id="isTrue" v-model="isTrue">
    <label for="isTrue"><span v-text="isTrue"></span></label>
    </p>
</div>
<script type="text/javascript">
    window.onload = function () {
        var app = new Vue({
            el: '#app',
            data: {
                message: '',
                isTrue:true
            }
        })
    }

</script>
</body>
</html>
View Code

    四、多选框选中数组

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <p>
    <h3>文本框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p>普通类型:<input type="text" v-model="message"></p>
    <p>lazy:<input type="text" v-model.lazy="message"></p>
    <p>number:<input type="text" v-model.number="message"></p>
    <p>trim:<input type="text" v-model.trim="message"></p>
    </p>
    <p>
    <h3>多区域框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p><textarea cols="30" rows="10" v-model="message"></textarea></p>
    </p>
    <p>
    <h3>多选框绑定一个值</h3>
    <input type="checkbox" id="isTrue" v-model="isTrue">
    <label for="isTrue"><span v-text="isTrue"></span></label>
    </p>
    <p>
    <h3>多选框绑定数组</h3>
    <input type="checkbox" id="jspang" value="jspang" v-model="web_names">
    <label for="jspang">jspang</label>
    <input type="checkbox" id="panda" value="panda" v-model="web_names">
    <label for="panda">panda</label>
    <input type="checkbox" id="pangzi" value="pangzi" v-model="web_names">
    <label for="pangzi">pangzi</label>
    <p v-text="web_names"></p>
    </p>
</div>
<script type="text/javascript">
    window.onload = function () {
        var app = new Vue({
            el: '#app',
            data: {
                message: '',
                isTrue:true,
                web_names:[]
            }
        })
    }

</script>
</body>
</html>
View Code

    五、单选框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <p>
    <h3>文本框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p>普通类型:<input type="text" v-model="message"></p>
    <p>lazy:<input type="text" v-model.lazy="message"></p>
    <p>number:<input type="text" v-model.number="message"></p>
    <p>trim:<input type="text" v-model.trim="message"></p>
    </p>
    <p>
    <h3>多区域框</h3>
    <p >你想表达的文字是:   <span v-text="message"></span></p>
    <p><textarea cols="30" rows="10" v-model="message"></textarea></p>
    </p>
    <p>
    <h3>多选框绑定一个值</h3>
    <input type="checkbox" id="isTrue" v-model="isTrue">
    <label for="isTrue"><span v-text="isTrue"></span></label>
    </p>
    <p>
    <h3>多选框绑定数组</h3>
    <input type="checkbox" id="jspang" value="jspang" v-model="web_names">
    <label for="jspang">jspang</label>
    <input type="checkbox" id="panda" value="panda" v-model="web_names">
    <label for="panda">panda</label>
    <input type="checkbox" id="pangzi" value="pangzi" v-model="web_names">
    <label for="pangzi">pangzi</label>
    <p v-text="web_names"></p>
    </p>
    <p>
    <h3>单选框绑定</h3>
    <input type="radio" id="sex1" value="male" v-model="gender">
    <label for="sex1"></label>
    <input type="radio" id="sex2" value="female" v-model="gender">
    <label for="sex2"></label>
    <p>你选中的性别是:<span v-text="gender"></span></p>
    </p>
    <p>
</div>
<script type="text/javascript">
    window.onload = function () {
        var app = new Vue({
            el: '#app',
            data: {
                message: '',
                isTrue:true,
                web_names:[],
                gender:'male'
            }
        })
    }

</script>
</body>
</html>
View Code

 

  六、v-bind

  v-bind能够绑定资源也能够绑定类

       一、资源绑定

      img操做:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <p>
            <h3>资源绑定</h3>
        <p><img :src="srcUrl" alt="" width="200px"/></p>
        
        </p>
    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                    srcUrl: 'https://www.baidu.com/img/bd_logo1.png'
                }
            })
        }

    </script>
</body>
</html>
View Code

      a操做:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <p>
            <h3>资源绑定</h3>
        <p><img :src="srcUrl" alt="" width="200px"/></p>
        <p><a :href="aurl">点击</a></p>

        </p>
    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                    srcUrl: 'https://www.baidu.com/img/bd_logo1.png',
                    aurl: 'https://www.baidu.com'
                }
            })
        }

    </script>
</body>
</html>
View Code

    二、类操做

    

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .classA{
            color: red;
        }
        .classB{
            font-size: 30px;
        }
    </style>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <p>
            <h3>资源绑定</h3>
        <p><img :src="srcUrl" alt="" width="200px"/></p>
        <p><a :href="aurl">点击</a></p>

        </p>
        <p>
        <h3>类操做</h3>
        <p :class="classname">1.绑定class</p>
        <p :class="{classA:isok}">2.绑定class判断</p>
        <p :class="[classA,classB]">3.绑定class数组</p>
        <p :class="isok?classA:classB">4.绑定class数组三元运算</p>
        <p :style="{color:red,fontSize:font}">5.style绑定</p>
        <p :style="styeobj">6.style绑定对象</p>
        <hr>
        <div>
            <input type="checkbox" id="isok" v-model="isok">
            <label for="isok">绑定->{{isok}}</label>
        </div>

        </p>
    </div>
    <script type="text/javascript">
        window.onload=function () {
            var app=new Vue({
                el:'#app',
                data:{
                    srcUrl: 'https://www.baidu.com/img/bd_logo1.png',
                    aurl: 'https://www.baidu.com',
                    classname: 'classA',
                    isok:false,
                    classA:'classA',
                    classB:'classB',
                    red:'red',
                    font:'40px',
                    styeobj:{
                        color:'green',
                        fontSize:'50px'
                    }
                }
            })
        }

    </script>
</body>
</html>
View Code

 

  七、v-pre   v-cloak    v-once

    v-pre:不渲染使用v-pre

    v-cloak:所有渲染完毕才显示

    v-once:只渲染一次(v-model操做不对今生效) 

 

2、全局API

  全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,好比咱们今天要学习的指令Vue.directive。说的简单些就是,在构造器外部用Vue提供给咱们的API函数来定义新的功能。

  一、Vue.directive自定义指令

    Vue.directive能够建立自定义指令完成某些特定任务,好比能够定义一个v-gavin的指令,做用是让文字变成绿色

    为了实现这个功能,能够写一个简单的demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <div v-text="message" v-gavin="color"></div>
    <button @click="add">增长</button>
</div>
<script type="text/javascript">
    window.onload = function () {
            Vue.directive('gavin',function (el,binding,vnode) {
                console.log(el);
                console.log(binding);
                el.style='color:'+binding.value;

            })
        var app = new Vue({
            el: '#app',
            data: {
                message: 0,
                color: 'red'
            },
            methods: {
                add: function () {
                    this.message++
                }
            }

        })
    }

</script>
</body>
</html>
View Code

  fucntion函数中三个参数:

  el:指令所绑定的元素,能够用来直接操做DOM

  binding:一个对象,包含指令的不少信息

  vnode:Vue编译生成的虚拟节点

 

  在自定义指令存在生命周期的概念,它包含五个生命周期也叫作五个钩子函数,分别是:

  1. bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数能够定义一个绑定时执行一次的初始化动做。
  2. inserted:被绑定元素插入父节点时调用(父节点存在便可调用,没必要存在于document中)。
  3. update:被绑定于元素所在的模板更新时调用,而不管绑定值是否变化。经过比较更新先后的绑定值,能够忽略没必要要的模板更新。
  4. componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  5. unbind:只调用一次,指令与元素解绑时调用。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    <div v-text="message" v-gavin="color"></div>
    <button @click="add">增长</button>
    <button onclick="unbind()">解绑</button>

</div>
<script type="text/javascript">

        window.onload = function () {
            function unbind() {
                app.$destroy();//Vue提供的销毁绑定的函数 $destory()
            };
            Vue.directive('gavin',{
                bind:function () {
                    console.log('1. bind');
                },
                inserted:function(){
                    console.log('2. inserted');
                },
                update:function(el,binding){
                    console.log('3. update');
                    el.style='color:'+binding.value
                },
                componentUpdated:function(){
                    console.log('4. componentUpdated');
                },
                unbind:function(){
                    console.log('5. unbind');
                }})
        var app = new Vue({
            el: '#app',
            data: {
                message: 0,
                color: 'red'
            },
            methods: {
                add: function () {
                    this.message++
                }
            }

        })
    }

</script>
</body>
</html>
View Code

 

  二、Vue.extend构造器的延伸

  Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器。常常服务于Vue.component用来生成组件,能够简单理解为当在模板中遇到该组件名称做为标签的自定义元素时,会自动调用“扩展实例构造器”来生产组件实例,并挂载到自定义元素上。

     能够构建一个小demo来演示一下无参数标签的实例:

     

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app"></div>
    <author></author>
    <script type="text/javascript">
        var authorExtend = Vue.extend({
            template:"<p><a :href='authorUrl'><span v-text='authorName'></span></a></p>",
            data:function () {
                return{
                    authorName:'Gavin',
                    authorUrl:'https://www.baidu.com'
                }
            }
        })
        new authorExtend().$mount('author')//mount绑定,能够代替new Vue({el: 'app方式'})
        new authorExtend().$mount('#app')//能够相似于jquery方式绑定
    </script>
</body>
</html>
View Code

 

  三、Vue.set

  Vue.set 的做用就是在构造器外部操做构造器内部的数据、属性或者方法。好比在vue构造器内部定义了一个count为1的数据,咱们在构造器外部定义了一个方法,要每次点击按钮给值加1.就须要用到Vue.set。

  什么是外部数据,就是不在Vue构造器里里的data处声明,而是在构造器外部声明,而后在data处引用就能够了。外部数据的加入让程序更加灵活,咱们能够在外部获取任何想要的数据形式,而后让data引用。

  demo以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        {{count}}
        {{name}}
        {{arr}}
    </div>
    <script type="text/javascript">
        window.onload=function () {
            var outData ={
                count:1,
                name: 'Gain',
                arr: ['aaa','bbb','ccc']
            }
            var app=new Vue({
                el:'#app',
                data: outData//引用外部数据
            })
        }

    </script>
</body>
</html>
View Code

 

  修改外部数据的三种方式:

  一、outData++

  二、app.count++

  三、Vue.set(outData,'count',4);  //outData我、是外部数据  count是它里面的一项   4表示须要改变为4

 

  因为Javascript的限制,Vue不能自动检测如下变更的数组。

    *当你利用索引直接设置一个项时,vue不会为咱们自动更新。

    *当你修改数组的长度时,vue不会为咱们自动更新。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="vue.js"></script>
    <title>Vue.set 全局操做</title>
</head>
<body>
<h1>Vue.set 全局操做</h1>
<hr>
<div id="app">
    <ul>
        <li v-for=" aa in arr">{{aa}}</li>
    </ul>

</div>
<button onclick="add()">外部添加</button>

<script type="text/javascript">

    function add(){
        console.log("我已经执行了");
//        app.arr[1]='ddd';//使用该方式无法改变数组内数据
        Vue.set(app.arr,1,'d');
    }
    var outData={
        arr:['aaa','bbb','ccc']
    };
    var app=new Vue({
        el:'#app',
        data:outData
    })
</script>
</body>
</html>
View Code

  这时咱们的界面是不会自动跟新数组的,咱们须要用Vue.set(app.arr,1,’d’)来设置改变,vue才会给咱们自动更新,这就是Vue.set存在的意义。

   

  四、Vue生命周期  

  Vue一共有10个生命周期函数,咱们能够利用这些函数在vue的每一个阶段都进行操做数据或者改变内容。

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        {{message}}

        <button @click="add">add</button></div>
    <button onclick="des()">des</button>
    <script type="text/javascript">
        function des() {
            app.$destroy();
        }
        var app=new Vue({
            el: '#app',
            data:{
                message:0
            },
            methods:{
                add:function () {
                    this.message++;
                }


            },
            beforeCreate:function(){
                console.log('1-beforeCreate 初始化以后');
            },
            created:function(){
                console.log('2-created 建立完成');
            },
            beforeMount:function(){
                console.log('3-beforeMount 挂载以前');
            },
            mounted:function(){
                console.log('4-mounted 被建立');
            },
            beforeUpdate:function(){
                console.log('5-beforeUpdate 数据更新前');
            },
            updated:function(){
                console.log('6-updated 被更新后');
            },
            activated:function(){//vuerouter中生效
                console.log('7-activated');
            },
            deactivated:function(){//vuerouter中生效
                console.log('8-deactivated');
            },
            beforeDestroy:function(){
                console.log('9-beforeDestroy 销毁以前');
            },
            destroyed:function(){
                console.log('10-destroyed 销毁以后')
            }
        })

    </script>
</body>
</html>
View Code

 

 

  五、template

  template有三种写法:

    一、直接在Vue中写模板:直接在构造器里的template选项后边编写。这种写法比较直观,可是若是模板html代码太多,不建议这么写。

<body>
    <div id="app">

    </div>
    <script type="text/javascript">
        var app=new Vue({
            el: '#app',
            data:{
                message: 'hello world!'
            },
            template:`<h2 style="color:red">我是选项模板</h2>`
        })
    </script>
</body>
View Code

    二、写在template标签中的模板

<body>
    <div id="app">

    </div>
    <template id="dd">
        <h2 style="color:red">我是template中的模板</h2>
    </template>
    <script type="text/javascript">
        var app=new Vue({
            el: '#app',
            data:{
                message: 'hello world!'
            },
            template:'#dd'
//            template:`<h2 style="color:red">我是选项模板</h2>`
        })
    </script>
</body>
View Code

    三、写在script中的模板

  

<body>
    <div id="app">

    </div>
    <template id="dd">
        <h2 style="color:red">我是template中的模板</h2>
    </template>
    <script type="x-template" id="dd1">
        <h2 style="color:red">我是script中的模板</h2>
</script>
    <script type="text/javascript">
        var app=new Vue({
            el: '#app',
            data:{
                message: 'hello world!'
            },
            template:'#dd1'
//            template:`<h2 style="color:red">我是选项模板</h2>`
        })
    </script>
</body>
View Code

 

  六、Component

    组件就是制做自定义的标签,这些标签在HTML中是没有的。好比:<j></j>

  component分为两种状况:

    一、全局组件

    二、局部组件

    其中全局组件在整个Vue生命周期内均可以调用,而局部组件只在对应的Vue下能够调用。

    demo以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <gavin></gavin>
    </div>
    <div id="app1">
        <gavin></gavin>
    </div>
    <template id="t1">
        <h2>我是全局组件</h2>
    </template>
    
    <script type="text/javascript">
        Vue.component('gavin',{
            template: '#t1'
        });
        var app=new Vue({
                el:'#app'
            });
        var app1=new Vue({
            el: '#app1'
        })


    </script>
</body>
</html>
全局组件

    demo局部以下,能够看到ga组件只能在app上调用,在app1上调用会报错

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <gavin></gavin>
        <ga></ga>
    </div>
    <div id="app1">
        <gavin></gavin>
        <ga></ga>
    </div>
    <template id="t1">
        <h2>我是全局组件</h2>
    </template>
    <template id="t2">
        <h2>我是局部组件</h2>
    </template>
    <script type="text/javascript">
        Vue.component('gavin',{
            template: '#t1'
        });
        var app=new Vue({
            el:'#app',
            components:{
                'ga': {
                    template: '#t2'
                }
            }
            });
        var app1=new Vue({
            el: '#app1'
        })


    </script>
</body>
</html>
View Code

     组件注册的是一个标签,而指令注册的是已有标签里的一个属性。在实际开发中咱们仍是用组件比较多,指令用的比较少。由于指令看起来封装的没那么好

 

    props选项就是设置和获取标签上的属性值的,例如咱们有一个自定义的组件<panda></panda>,这时咱们想给他加个标签属性写成<panda here=’China’></panda> 意思就是熊猫来自中国,固然这里的China能够换成任何值。定义属性的选项是props。

    一、定义属性并获取值

    定义属性咱们须要用props选项,加上数组形式的属性名称,例如:props:[‘here’]。在组件的模板里读出属性值只须要用插值的形式,例如{{ here }}.   

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <gavin here="china"></gavin>
    </div>
    <template id="t1">
        <h2>组件传参: {{here}}</h2>
    </template>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    message: 'china'
                },
                components:{
                    'gavin':{
                        template:'#t1',
                        props:['here']

                    }
                }

            })


    </script>
</body>
</html>
View Code

    二、属性若是中间带‘-’,须要小驼峰式写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <gavin from-here="china"></gavin>
    </div>
    <template id="t1">
        <h2>组件传参: {{fromHere}}</h2>
    </template>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    message: 'china'
                },
                components:{
                    'gavin':{
                        template:'#t1',
                        props:['fromHere']

                    }
                }

            })


    </script>
</body>
</html>
View Code

    三、向组件中传参-  须要经过v-bind  或者:方式进行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <gavin :from-here="message"></gavin>
    </div>
    <template id="t1">
        <h2>组件传参: {{fromHere}}</h2>
    </template>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    message: 'china'
                },
                components:{
                    'gavin':{
                        template:'#t1',
                        props:['fromHere']

                    }
                }

            })


    </script>
</body>
</html>
View Code

 

     父子组件:

      注意:须要使用div包裹起来才能使用子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
       <gavin></gavin>
    </div>
    <template id="t2">

        <h3>我是子组件</h3>

    </template>
    <template id="t1">
        <!--须要使用div包裹起来才能使用子组件-->
        <div>
        <h2>我是父组件</h2>
        <sun></sun>
        </div>
    </template>

    <script type="text/javascript">
        var sun = {
            template: '#t2'
        };
        var father = {
            template: '#t1',
            components:{
                'sun': sun
            }
        };
            var app=new Vue({
                el:'#app',
                components:{
                    'gavin': father
                }

            })


    </script>
</body>
</html>
View Code

   

  component标签:

  <component></component>标签是Vue框架自定义的标签,它的用途就是能够动态绑定咱们的组件,根据数据的不一样更换不一样的组件。

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <component :is="who"></component>
        <button @click="changeComponent">Change</button>
    </div>
    <template id="t1">
        <div style="color:red">I'm Component A</div>
    </template>
    <template id="t2">
        <div style="color:green">I'm Component B</div>
    </template>
    <template id="t3">
        <div style="color:blue">I'm Component C</div>
    </template>
    <script type="text/javascript">
            var componentA = {
                template: '#t1'
            };
            var componentB = {
                template: '#t2'
            };
            var componentC = {
                template: '#t3'
            };
            var app=new Vue({
                el:'#app',
                data:{
                    who: 'componentA'
                },
                components:{
                    'componentA': componentA,
                    'componentB': componentB,
                    'componentC': componentC
                },
                methods:{
                    changeComponent:function () {
                        if(this.who==='componentA'){
                            this.who = 'componentB';
                        }else if(this.who==='componentB'){
                            this.who = 'componentC';
                        }else{
                            this.who = 'componentA';
                        }
                    }
                }
            })


    </script>
</body>
</html>
View Code

 

 

 

3、选项

  一、propsData选项

  propsData 不是和属性有关,他用在全局扩展时进行传递数据。先回顾一下全局扩展的知识,做一个<header></header>的扩展标签出来。实际咱们并比推荐用全局扩展的方式做自定义标签,咱们学了组件,彻底可使用组件来作,这里只是为了演示propsData的用法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <header></header>
    <script type="text/javascript">
        var header_a = Vue.extend({
            template: `<p>{{message}}-{{a}}</p>`,
            data:function(){
                return{
                    message:'hello world'
                }
            },
            props:['a']
        });
        new header_a({propsData:{a:'扩展传值'}}).$mount('header')


    </script>
</body>
</html>
View Code 

  扩展标签已经作好了,这时咱们要在挂载时传递一个数字过去,咱们就用到了propsData。

  咱们用propsData三步解决传值:

    一、在全局扩展里加入props进行接收。propsData:{a:1}

    二、传递时用propsData进行传递。props:[‘a’]

    三、用插值的形式写入模板。{{ a }}

  总结:propsData在实际开发中咱们使用的并很少,咱们在后边会学到Vuex的应用,他的做用就是在单页应用中保持状态和数据的。

 

  二、computed 选项

  computed 的做用主要是对原数据进行改造输出。改造输出:包括格式的编辑,大小写转换,顺序重排,添加符号……。

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <div v-text="newPrice"></div>
        <ul>
            <li v-for="item in newslists"><span v-text="item.title"></span>-<span v-text="item.date"></span></li>
        </ul>
    </div>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    price: 100,
                    news:[
                        {title:'香港或就“装甲车被扣”事件追责 起诉涉事运输公司',date:'2017/12/10'},
                        {title:'日本第二大准航母服役 外媒:针对中国潜艇',date:'2017/12/12'},
                        {title:'中国北方将有明显雨雪降温天气 南方阴雨持续',date:'2017/12/13'},
                        {title:'起底“最短命副市长”:不到40天落马,全家被查',date:'2017/12/23'}
                    ]
                },
                computed:{
                    newPrice:function () {
                        return this.price = ""+this.price+''
                    },
                    newslists:function () {
                        return this.news.reverse();
                    }
                }
            })


    </script>
</body>
</html>
View Code

 

  三、methods选项 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <div v-text="num"></div>
        <p><button @click="add(money)">add</button></p>
        <p><input type="text" v-model="money"></p>
    </div>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    num:0,
                    money:''
                },
                methods:{
                    add:function (mon) {
                        if(mon!=0){
                            this.num+=parseInt(mon);
                        }else {
                            this.num++;
                        }
                    }
                }
            })


    </script>
</body>
</html>
View Code 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <div v-text="num"></div>
        <p><button @click="add(money,$event)">add</button></p>
        <p><input type="text" v-model="money"></p>
    </div>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    num:0,
                    money:''
                },
                methods:{
                    add:function (mon,event) {
                        if(mon!=0){
                            this.num+=parseInt(mon);
                        }else {
                            this.num++;
                        };
                        console.log(event);
                    }
                }
            })


    </script>
</body>
</html>
增长第二个参数$event
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <div v-text="num"></div>
        <!--<p><button @click="add(money,$event)">add</button></p>-->
        <p><button @click="add(money)">add</button></p>
        <p><input type="text" v-model="money"></p>
        <btn @click.native="add(money)"></btn>
    </div>
    <template id="t1">
        <div>
            <button >add</button>
        </div>
    </template>
    <script type="text/javascript">
            var btn={
                template:'#t1'
            };
            var app=new Vue({
                el:'#app',
                data:{
                    num:0,
                    money:''
                },
                components:{
                    'btn': btn
                },
                methods:{
//                    add:function (mon,event) {
                    add:function (mon) {
                        if(mon!=0){
                            this.num+=parseInt(mon);
                        }else {
                            this.num++;
                        };
//                        console.log(event);
                    }
                }
            })


    </script>
</body>
</html>
自定义组件调用内部构造器方法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <div v-text="num"></div>
        <!--<p><button @click="add(money,$event)">add</button></p>-->
        <p><button @click="add(money)">add</button></p>
        <p><input type="text" v-model="money"></p>
        <btn @click.native="add(money)"></btn>
    </div>
    <div><button onclick="app.add(2)">外部add</button></div>
    <template id="t1">
        <div>
            <button >add</button>
        </div>
    </template>
    <script type="text/javascript">
            var btn={
                template:'#t1'
            };
            var app=new Vue({
                el:'#app',
                data:{
                    num:0,
                    money:''
                },
                components:{
                    'btn': btn
                },
                methods:{
//                    add:function (mon,event) {
                    add:function (mon) {
                        if(mon!=0){
                            this.num+=parseInt(mon);
                        }else {
                            this.num++;
                        };
//                        console.log(event);
                    }
                }
            })


    </script>
</body>
</html>
外部标签调用

 

使用方法和正常的javascript传递参数的方法同样,分为两部:

  一、在methods的方法中进行声明,好比咱们给add方法加上一个num参数,就要写出add:function(num){}.

  二、调用方法时直接传递,好比咱们要传递2这个参数,咱们在button上就直接能够写。<button @click=”add(2)”></button>.

  三、在add()里面出来能够传递2之外还能够传递$event这个参数,这个参数包括不少mouseEvent操做

  四、若是自定义组件时想要使用构造器里方法,必须使用@click.native=add()方法,native选项能够保证自定义组件可使用构造器内方法

  五、若是外部标签想要使用构造器方法,能够直接采用onclick='app.add()'方法直接调用

   

  

  四、watch选项

  数据变化的监控常用,咱们能够先来看一个简单的数据变化监控的例子。例如天气预报的穿衣指数,它主要是根据温度来进行提示的

  demo以下:

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <p>温度:<span v-text="temp"></span></p>
        <p>穿衣建议:<span v-text="sugg"></span></p>
        <div><button @click="incrtemp">升高温度</button><button @click="redutemp">下降温度</button></div>
    </div>
    <script type="text/javascript">
            var suggs=['棉衣','夏装','春装','秋装']
            var app=new Vue({
                el:'#app',
                data:{
                    temp:0,
                    sugg:suggs[0]
                },
                methods:{
                    incrtemp:function () {
                        this.temp+=5;
                    },
                    redutemp:function () {
                        this.temp-=5;
                    }
                },
                watch:{
                    temp:function (newVal,oldVal) {//newVal是temp新数值,oldVal是temp原值
                        if(newVal <=0){
                            this.sugg=suggs[0];
                        }else if(newVal>0 && newVal<=16){
                            this.sugg=suggs[2];
                        }else if(newVal>16 && newVal<26){
                            this.sugg=suggs[3]
                        }else{
                            this.sugg=suggs[1]
                        }

                    }
                }

            })


    </script>
</body>
</html>
View Code

  其中watch:{

    temp:function(newVal,oldVal){}  //newVal表示temp这个变量的新变化的值,而oldVal表示temp这个变量原来的值

    }

  

  为了下降耦合度,还能够将watch放在构造器外部书写:

app.$watch('temp',function (newVal,oldVal) {
            if(newVal <=0){
                this.sugg=suggs[0];
            }else if(newVal>0 && newVal<=16){
                this.sugg=suggs[2];
            }else if(newVal>16 && newVal<26){
                this.sugg=suggs[3]
            }else{
                this.sugg=suggs[1]
            }})
View Code

 

  五、mixins混入选项

  Mixins通常有两种用途:

    一、在你已经写好了构造器后,须要增长方法或者临时的活动时使用的方法,这时用混入会减小源代码的污染。

    二、不少地方都会用到的公用方法,用混入的方法能够减小代码量,实现代码重用。

 

    在mixins插入后,mixin插入优先于构造器的updated,可是同时全局的mixin优先于普通的mixin

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        {{num}}
        <p><button @click="add(4)">add</button></p>
    </div>
    <script type="text/javascript">
            var addCon = {
                updated:function () {
                    console.log('混入方式:'+this.num);
                }

            };
            Vue.mixin({
                updated:function(){
                    console.log('我是全局被混入的');
                }
            });
            var app=new Vue({
                el:'#app',
                data:{
                    num: 0
                },
                methods:{
                    add:function (val) {
                        console.log('原生的方式执行')
                        this.num+=parseInt(val)
                    }
                },
                updated:function () {
                    console.log('原生的更新执行')
                },
                mixins:[addCon]
            })


    </script>
</body>
</html>
View Code

 

  六、extends选项

  经过外部增长对象的形式,对构造器进行扩展

  extends:后面只能跟一个扩展选项名

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
    {{num}}
    <p><button @click="add(4)">add</button></p>
</div>
<script type="text/javascript">
    var extendobj = {
        updated:function () {
            console.log('extend选项插入')
        }
    };
    var app=new Vue({
        el:'#app',
        data:{
            num: 0
        },
        methods:{
            add:function (val) {
                console.log('原生的方式执行');
                this.num+=parseInt(val)
            }
        },
        updated:function () {
            console.log('原生的更新执行')
        },
        extends: extendobj
    })


</script>
</body>
</html>
View Code

 

  七、delimiters

    delimiters的做用是改变咱们插值的符号。Vue默认的插值是双大括号{{}}。但有时咱们会有需求更改这个插值的形式

delimiters:['${','}']

 

 

4、实例与内部组件

  实例就是在构造器外部操做构造器内部的属性选项或者方法,就叫作实例?实例的做用就是给原生的或者其余javascript框架一个融合的接口或者说是机会,让Vue和其余框架一块儿使用

  一、Vue与Jquery配合

  注意:在调用时必须经过钩子函数mounted或者updated调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
</head>
<body>
    <div id="app">
        {{message}}
    </div>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    message: 'hello world!!!'
                },
                mounted:function () {
                    $('#app').html('这是jquery!')
                }
            })


    </script>
</body>
</html>
View Code

  对于内部方法能够经过外部引用方式调用

app.add();//外部能够经过实例方式调用

 

 

  二、$mount()  $destroy()$forceUpdate()  $nextTick()方法

      mount():

  $mount方法是用来挂载咱们的扩展的

  $mount须要经过Vue.extend来完成扩展

   

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">

    </div>
    <template id="t1">
        <div>
            <span v-text="message"></span>
        </div>
    </template>
    <script type="text/javascript">
         var mountExt = Vue.extend({
             template: '#t1',
             data:function () {
                 return{
                     message: 'hello world!'
                 }
             }
         });
         var vm = new mountExt().$mount('#app')


    </script>
</body>
</html>
View Code

  $destroy()

  用$destroy()进行卸载

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">

    </div>
    <p><button onclick="destroy()">卸载</button></p>
    <template id="t1">
        <div>
            <span v-text="message"></span>
        </div>
    </template>
    <script type="text/javascript">
         var mountExt = Vue.extend({
             template: '#t1',
             data:function () {
                 return{
                     message: 'hello world!'
                 }
             },
             mounted:function () {
                 console.log('绑定')
             },
             destroyed:function () {
                 console.log('卸载完毕');
             }
         });
         var vm = new mountExt().$mount('#app');
         function destroy() {
             vm.$destroy();
         }


    </script>
</body>
</html>
View Code

  $forceUpdate()

    
vm.$forceUpdate()

   $nextTick()

  修改数据会自动触发

function tick() {
             vm.message='修改数据'
             vm.$nextTick(function(){
                 console.log('message更新完后我被调用了');
             })
         }

 

  完整demo以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app"></div>
    <p><button onclick="destroy()">卸载</button></p>
    <p><button onclick="reload()">更新</button></p>
    <p><button onclick="tick()">修改数据</button></p>
    <template id="t1">
        <div>
            <span v-text="message"></span>
        </div>
    </template>
    <script type="text/javascript">
         var mountExt = Vue.extend({
             template: '#t1',
             data:function () {
                 return{
                     message: 'hello world!'
                 }
             },
             mounted:function () {
                 console.log('绑定')
             },
             updated:function () {
                 console.log('数据更新')
             },
             destroyed:function () {
                 console.log('卸载完毕');
             }
         });
         var vm = new mountExt().$mount('#app');
         function destroy() {
             vm.$destroy();
         }
         function reload() {
             vm.$forceUpdate();
         }
         function tick() {
             vm.message='修改数据'
             vm.$nextTick(function(){
                 console.log('message更新完后我被调用了');
             })
         }


    </script>
</body>
</html>
View Code

 

  三、实例事件

  

  实例事件就是在构造器外部写一个调用构造器内部的方法。这样写的好处是能够经过这种写法在构造器外部调用构造器内部的数据。

咱们仍是写一个点击按钮,持续加1的例子

    一、$on

     在构造器外部添加事件, $on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法。若是按钮在做用域外部,能够利用$emit来执行

    

app.$on('reduce',function (num) {
                this.message -=num;
            });
function reduce(num) {
     app.$emit('reduce',num);
    };

 

    二、$once

     执行一次的事件

app.$once('reduceOnce',function (num) {
                console.log('执行了reduceOnce()');
                this.message -=num;

            });
function reduceOnce(num) {
        app.$emit('reduceOnce',num);
            }

 

    三、$off

     关闭事件

function off() {
              app.$off('reduce')  
            }

 

  完整代码以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        {{message}}
        <div>
            <button @click="add(2)">add</button>
        </div>
    </div>
    <div><button onclick="reduce(2)">reduce</button></div>
    <div><button onclick="reduceOnce(2)">reduceOnce</button></div>
    <div><button onclick="off()">off</button></div>
    <script type="text/javascript">
            var app=new Vue({
                el:'#app',
                data:{
                    message: 0
                },
                methods:{
                    add:function (num) {
                        console.log('执行了add()');
                        this.message+=parseInt(num);
                    }
                }
            });
            app.$on('reduce',function (num) {
                console.log('执行了reduce()');
                this.message -=num;
            });
            function reduce(num) {
                app.$emit('reduce',num);
            };

            app.$once('reduceOnce',function (num) {
                console.log('执行了reduceOnce()');
                this.message -=num;

            });
            function reduceOnce(num) {
                app.$emit('reduceOnce',num);
            };
            function off() {
              app.$off('reduce')
            }

    </script>
</body>
</html>
View Code

 

  四、内置组件-slot

  slot是标签的内容扩展,也就是说你用slot就能够在自定义组件时传递给组件内容,组件接收内容并输出

  slot使用分两步:

  一、在html组件中用slot属性传递值:

<gavin>
           <span slot="Url">{{Dataobj.address}}</span>
           <span slot="netname">{{Dataobj.username}}</span>
           <span slot="skill">{{Dataobj.skill}}</span>
        </gavin>

  二、在组件模板中使用slot标签接收属性值

<template id="t1">
        <div>
            <p>地址:<slot name="Url"></slot></p>
            <p>网名:<slot name="netname"></slot></p>
            <p>技能:<slot name="skill"></slot></p>
        </div>
    </template>

  完整demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="app">
        <gavin>
           <span slot="Url">{{Dataobj.address}}</span>
           <span slot="netname">{{Dataobj.username}}</span>
           <span slot="skill">{{Dataobj.skill}}</span>
        </gavin>
    </div>
    <template id="t1">
        <div>
            <p>地址:<slot name="Url"></slot></p>
            <p>网名:<slot name="netname"></slot></p>
            <p>技能:<slot name="skill"></slot></p>
        </div>
    </template>
    <script type="text/javascript">
            var gavin={
                template:'#t1'
            };
            var app=new Vue({
                el:'#app',
                data:{
                    Dataobj:{
                        'address': 'https://www.baidu.com',
                        'username': 'gavin',
                        'skill': 'python'
                    }
                },
                components:{
                    'gavin':gavin
                }
            })


    </script>
</body>
</html>
View Code

 

5、vue-cli

  安装vue-cli的前提是你已经安装了npm,安装npm你能够直接下载node的安装包进行安装。你能够在命令行工具里输入npm -v  检测你是否安装了npm和版本状况。出现版本号说明你已经安装了npm和node,若是该命令不可使用,须要安装node软件包,根据你的系统版本选择下载安装就能够了。

  下载地址:http://nodejs.cn/download/

  

npm没有问题,接下来咱们能够用npm 命令安装vue-cli了:

npm install vue-cli -g

-g :表明全局安装。若是你安装时报错,通常是网络问题,你能够尝试用cnpm来进行安装。安装完成后,能够用vue -V来进行查看 vue-cli的版本号。注意这里的V是大写的,若是vue -V的命令管用了,说明已经顺利的把vue-cli安装到咱们的计算机里了

 

  咱们用vue init命令来初始化项目,具体看一下这条命令的使用方法。

 vue init <template-name> <project-name>

  

vue init webpack vuecliTest

 

init:表示我要用vue-cli来初始化项目

  <template-name>:表示模板名称,vue-cli官方为咱们提供了5种模板,

    webpack-一个全面的webpack+vue-loader的模板,功能包括热加载,linting,检测和CSS扩展。

    webpack-simple-一个简单webpack+vue-loader的模板,不包含其余功能,让你快速的搭建vue的开发环境。

    browserify-一个全面的Browserify+vueify 的模板,功能包括热加载,linting,单元检测。

    browserify-simple-一个简单Browserify+vueify的模板,不包含其余功能,让你快速的搭建vue的开发环境。

    simple-一个最简单的单页应用模板。

  <project-name>:标识项目名称,这个你能够根据本身的项目来起名字。

  在实际开发中,通常咱们都会使用webpack这个模板,那咱们这里也安装这个模板,在命令行输入如下命令:

  

  输入命令后,会询问咱们几个简单的选项,咱们根据本身的须要进行填写就能够了。

  •   Project name :项目名称 ,若是不须要更改直接回车就能够了。注意:这里不能使用大写,因此我把名称改为了vueclitest
  • Project description:项目描述,默认为A Vue.js project,直接回车,不用编写。
  • Author:做者,若是你有配置git的做者,他会读取。
  • Install  vue-router? 是否安装vue的路由插件,咱们这里须要安装,因此选择Y
  • Use ESLint to lint your code? 是否用ESLint来限制你的代码错误和风格。咱们这里不须要输入n,若是你是大型团队开发,最好是进行配置。
  • setup unit tests with  Karma + Mocha? 是否须要安装单元测试工具Karma+Mocha,咱们这里不须要,因此输入n。
  • Setup e2e tests with Nightwatch?是否安装e2e来进行用户行为模拟测试,咱们这里不须要,因此输入n。

  命令行出现上面的文字,说明咱们已经初始化好了第一步。命令行提示咱们如今能够做的三件事情。

  一、cd vuecliTest  进入咱们的vue项目目录。

  二、npm install  安装咱们的项目依赖包,也就是安装package.json里的包,若是你网速很差,你也可使用cnpm来安装。

  三、npm run dev 开发模式下运行咱们的程序。给咱们自动构建了开发用的服务器环境和在浏览器中打开,并实时监视咱们的代码更改,即时呈现给咱们。

  

  vue-cli文件解释:  

  vue-cli脚手架工具就是为咱们搭建了开发所须要的环境,为咱们省去了不少精力。有必要对这个环境进行熟悉,咱们就从项目的结构讲起。

  Ps:因为版本实时更新和你选择安装的不一样(这里列出的是模板为webpack的目录结构),因此你看到的有可能和下边的有所差异。

.
|-- build                            // 项目构建(webpack)相关代码
|   |-- build.js                     // 生产环境构建代码
|   |-- check-version.js             // 检查node、npm等版本
|   |-- dev-client.js                // 热重载相关
|   |-- dev-server.js                // 构建本地服务器
|   |-- utils.js                     // 构建工具相关
|   |-- webpack.base.conf.js         // webpack基础配置
|   |-- webpack.dev.conf.js          // webpack开发环境配置
|   |-- webpack.prod.conf.js         // webpack生产环境配置
|-- config                           // 项目开发环境配置
|   |-- dev.env.js                   // 开发环境变量
|   |-- index.js                     // 项目一些配置变量
|   |-- prod.env.js                  // 生产环境变量
|   |-- test.env.js                  // 测试环境变量
|-- src                              // 源码目录
|   |-- components                     // vue公共组件
|   |-- store                          // vuex的状态管理
|   |-- App.vue                        // 页面入口文件
|   |-- main.js                        // 程序入口文件,加载各类公共组件
|-- static                           // 静态文件,好比一些图片,json数据等
|   |-- data                           // 群聊分析获得的数据用于数据可视化
|-- .babelrc                         // ES6语法编译配置
|-- .editorconfig                    // 定义代码格式
|-- .gitignore                       // git上传须要忽略的文件格式
|-- README.md                        // 项目说明
|-- favicon.ico 
|-- index.html                       // 入口页面
|-- package.json                     // 项目基本信息

  重要文件讲解:

  package.json

  package.json文件是项目根目录下的一个文件,定义该项目开发所须要的各类模块以及一些项目配置信息(如项目名称、版本、描述、做者等)。

  package.json 里的scripts字段,这个字段定义了你能够用npm运行的命令。在开发环境下,在命令行工具中运行npm run dev 就至关于执行 node build/dev-server.js  .也就是开启了一个node写的开发行建议服务器。由此能够看出script字段是用来指定npm相关命令的缩写。

"scripts": {
    "dev": "node build/dev-server.js",
    "build": "node build/build.js"
  },

  

在执行完npm run build命令后,在你的项目根目录生成了dist文件夹,这个文件夹里边就是咱们要传到服务器上的文件。

dist文件夹下目录包括:

  • index.html 主页文件:由于咱们开发的是单页web应用,因此说通常只有一个html文件。
  • static 静态资源文件夹:里边js、CSS和一些图片。

 

main.js是整个项目的入口文件,在src文件夹下:

import Vue from 'vue'      
import App from './App'
import router from './router'
 
Vue.config.productionTip = false   //生产环境提示,这里设置成了false
 
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

经过代码能够看出这里引进了App的组件和<App/>的模板,它是经过 import App from ‘./App’这句代码引入的。  咱们找到App.vue文件,打开查看

 

App.vue文件

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>
</template>
 
<script>
export default {
  name: 'app'
}
</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;
}
</style>

 

app.vue文件咱们能够分红三部分解读,

  • <template></template>标签包裹的内容:这是模板的HTMLDom结构,里边引入了一张图片和<router-view></router-view>标签,<router-view>标签说明使用了路由机制。咱们会在之后专门拿出一篇文章讲Vue-router。
  • <script></script>标签包括的js内容:你能够在这里些一些页面的动态效果和Vue的逻辑代码。
  • <style></style>标签包裹的css内容:这里就是你平时写的CSS样式,对页面样子进行装饰用的,须要特别说明的是你能够用<style scoped></style>来声明这些css样式只在本模板中起做用。

 

router/index.js 路由文件

引文在app.vue中咱们看到了路由文件,虽然router的内容比较多,可是咱们先简单的看一下。下篇文章咱们就开始讲Vue-router

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    }
  ]
})

咱们能够看到 import Hello from ‘@/components/Hello’这句话, 文件引入了/components/Hello.vue文件。这个文件里就配置了一个路由,就是当咱们访问网站时给咱们显示Hello.vue的内容

 

Hello.vue文件解读:

这个文件就是咱们在第一节课看到的页面文件了。也是分为<template><script><style>三个部分,之后咱们大部分的工做都是写这些.vue结尾的文件。如今咱们能够试着改一些内容,而后预览一下。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li><a href="https://gitter.im/vuejs/vue" target="_blank">Gitter Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
      <br>
      <li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a></li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
    </ul>
  </div>
</template>
 
<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
 
ul {
  list-style-type: none;
  padding: 0;
}
 
li {
  display: inline-block;
  margin: 0 10px;
}
 
a {
  color: #42b983;
}
</style>

 

 

6、vue-router

因为Vue在开发时对路由支持的不足,后来官方补充了vue-router插件,它在Vue的生态环境中很是重要,在实际开发中只要编写一个页面就会操做vue-router。要学习vue-router就要先知道这里的路由是什么?这里的路由并非指咱们平时所说的硬件路由器,这里的路由就是SPA(单页应用)的路径管理器。再通俗的说,vue-router就是咱们WebApp的连接路径管理系统

有的小伙伴会有疑虑,为何咱们不能像原来同样直接用<a></a>标签编写连接哪?由于咱们用Vue做的都是单页应用,就至关于只有一个主的index.html页面,因此你写的<a></a>标签是不起做用的,你必须使用vue-router来进行管理

安装vue-router

vue-router是一个插件包,因此咱们仍是须要用npm来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。

npm install vue-router --save-dev

若是你安装很慢,也能够用cnpm进行安装,若是你在使用vue-cli中已经选择安装了vue-router,那这里不须要重复安装了

解读router/index.js文件

咱们用vue-cli生产了咱们的项目结构,你能够在src/router/index.js文件,这个文件就是路由的核心文件

import Vue from 'vue'   //引入Vue
import Router from 'vue-router'  //引入vue-router
import Hello from '@/components/Hello'  //引入根目录下的Hello.vue组件
 
Vue.use(Router)  //Vue全局使用Router
 
export default new Router({
  routes: [              //配置路由,这里是个数组
    {                    //每个连接都是一个对象
      path: '/',         //连接路径
      name: 'Hello',     //路由名称,
      component: Hello   //对应的组件模板
    }
  ]
})
上边的代码中已经对每行都进行了注释,其实在这个路由文件里只配置了一个功能,就是在进入项目时,显示Hello.vue里边的内容代码。

增长一个Hi的路由和页面

对路由的核心文件熟悉后,咱们试着增长一个路由配置,咱们但愿在地址栏输入  http://localhost:8080/#/hi   的时候出现一个新的页面,先来看一下咱们但愿获得的效果。

咱们看一下具体的操做步骤:

  • 在src/components目录下,新建 Hi.vue 文件。
  • 编写文件内容,和咱们以前讲过的同样,文件要包括三个部分<template><script>和<style>。文件很简单,只是打印一句话。
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>
 
<script>
export default {
  name: 'hi',
  data () {
    return {
      msg: 'Hi, I am JSPang'
    }
  }
}
</script>
 
 
<style scoped>
 
</style>
  • 引入 Hi组件:咱们在router/index.js文件的上边引入Hi组件
import Hi from '@/components/Hi'
  • 增长路由配置:在router/index.js文件的routes[]数组中,新增长一个对象,代码以下。
{
  path:'/hi',
  name:'Hi',
  component:Hi
}

经过上面的配置已经能够增长一个新的页面了。是否是觉的本身的Vue功力一会儿就提高了一个档次。为了方便小伙伴查看,贴出如今的路由配置文件:

import Vue from 'vue'   //引入Vue
import Router from 'vue-router'  //引入vue-router
import Hello from '@/components/Hello'  //引入根目录下的Hello.vue组件
import Hi from '@/components/Hi' 
 
Vue.use(Router)  //Vue全局使用Router
 
export default new Router({
  routes: [              //配置路由,这里是个数组
    {                    //每个连接都是一个对象
      path: '/',         //连接路径
      name: 'Hello',     //路由名称,
      component: Hello   //对应的组件模板
    },{
      path:'/hi',
      name:'Hi',
      component:Hi
    }
  ]
})

router-link制做导航

如今经过在地址栏改变字符串地址,已经能够实现页面内容的变化了。这并不知足需求,咱们须要的是在页面上有个像样的导航连接,咱们只要点击就能够实现页面内容的变化。制做连接须要<router-link>标签,咱们先来看一下它的语法。

<router-link to="/">[显示字段]</router-link>
  • to:是咱们的导航路径,要填写的是你在router/index.js文件里配置的path值,若是要导航到默认首页,只须要写成  to=”/”  ,
  • [显示字段] :就是咱们要显示给用户的导航名称,好比首页  新闻页。

明白了router-link的基本语法,咱们在 src/App.vue文件中的template里加入下面代码,实现导航。

<p>导航 :
   <router-link to="/">首页</router-link>
   <router-link to="/hi">Hi页面</router-link>
</p>

 

  配置路由子系统

子路由的状况通常用在一个页面有他的基础模版,而后它下面的页面都隶属于这个模版,只是部分改变样式

  步骤:

    一、改造App.vue的导航代码

       App.vue代码

<p>导航 :
      <router-link to="/">首页</router-link> | 
      <router-link to="/hi">Hi页面</router-link> |
      <router-link to="/hi/hi1">-Hi页面1</router-link> |
      <router-link to="/hi/hi2">-Hi页面2</router-link>
</p>

    二、改写components/Hi.vue页面

      把Hi.vue改为一个通用的模板,加入<router-view>标签,给子模板提供插入位置。“Hi页面1”   和 “Hi页面2”  都至关于“Hi页面”的子页面,有点想继承关系。咱们在“Hi页面”里加入<router-view>标签。

      components/Hi.vue,就是第5行的代码,其余代码不变

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
 
    <router-view class="aaa"></router-view>
  </div>
</template>
 
<script>
export default {
  name: 'hi',
  data () {
    return {
      msg: 'Hi, I am JSPang'
    }
  }
}
</script>
<style scoped>
 
</style>

    三、在components目录下新建两个组件模板 Hi1.vue 和 Hi2.vue

      新建的模板和Hi.vue没有太多的差异,知识改变了data中message的值,也就是输出的结果不太同样了。

      Hi1.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>
<script>
export default {
  name: 'hi',
  data () {
    return {
      msg: 'Hi, I am Hi1!'
    }
  }
}
</script>
<style scoped>
 
</style>

 

      Hi2.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>
<script>
export default {
  name: 'hi',
  data () {
    return {
      msg: 'Hi, I am Hi2'
    }
  }
}
</script>
<style scoped>
</style>

    四、修改router/index.js代码

      咱们如今导航有了,母模板和子模板也有了,只要改变咱们的路由配置文件就能够了。子路由的写法是在原有的路由配置下加入children字段。

children:[
{path:'/',component:xxx},
{path:'xx',component:xxx},
]

      children字段后边跟的是个数组,数组里和其余配置路由基本相同,须要配置path和component。具体看一下这个子路由的配置写法。

import Vue from 'vue'   
import Router from 'vue-router'  
import Hello from '@/components/Hello'  
import Hi from '@/components/Hi' 
import Hi1 from '@/components/Hi1' 
import Hi2 from '@/components/Hi2' 
 
Vue.use(Router) 
 
export default new Router({
  routes: [             
    {                    
      path: '/',        
      name: 'Hello',     
      component: Hello   
    },{
      path:'/hi',
      component:Hi,
      children:[
        {path:'/',component:Hi},
        {path:'hi1',component:Hi1},
        {path:'hi2',component:Hi2},
      ]
    }
  ]
})

 

  vue-router如何传递参数

  开发中,参数的传递是个最基本的业务需求。经过URL地址来传递参数是一个形式,咱们先想象一个基本需求,就是在咱们点击导航菜单时,跳转页面上能显示出当前页面的路径,来告诉用户你想在所看的页面位置(相似于面包屑导航)。

  一、用name传递参数

两步完成用name传值并显示在模板里:

  a、在路由文件src/router/index.js里配置name属性。

 

{
          path: 'hi1',
          name: 'Hi1',
          component: Hi1,
        },

  b、模板里(src/App.vue)用$router.name的形势接收,好比直接在模板中显示:

<p>{{ $route.name }}</p>

 

  二、经过<router-link> 标签中的to传参

  咱们用<router-link>标签中的to属性进行传参,须要您注意的是这里的to要进行一个绑定,写成:to。

<router-link :to="{name:xxx,params:{key:value}}">valueString</router-link>

  

  这里的to前边是带冒号的,而后后边跟的是一个对象形势的字符串.

  • name:就是咱们在路由配置文件中起的name值。
  • params:就是咱们要传的参数,它也是对象形势,在对象里能够传递多个值。

  了解基本的语法后,咱们改造一下咱们的src/App.vue里的<router-link>标签,咱们把hi1页面的<router-link>进行修改。

<router-link :to="{name:'hi1',params:{username:'gavin'}}">Hi页面1</router-link>

  把src/reouter/index.js文件里给hi1配置的路由起个name,就叫hi1.

{path:'/hi1',name:'hi1',component:Hi1},

  最后在模板里(src/components/Hi1.vue)用$route.params.username进行接收.

{{$route.params.username}}

 

 

  四、单页面多路由操做

  实际需求是这样的,在一个页面里咱们有2个以上<router-view>区域,咱们经过配置路由的js文件,来操做这些区域的内容。例如咱们在src/App.vue里加上两个<router-view>标签。咱们用vue-cli创建了新的项目,并打开了src目录下的App.vue文件,在<router-view>下面新写了两行<router-view>标签,并加入了些CSS样式。

<router-view ></router-view>
 <router-view name="left" style="float:left;width:50%;background-color:#ccc;height:300px;"></router-view>
 <router-view name="right" style="float:right;width:50%;background-color:#c0c;height:300px;"></router-view>

  如今的页面中有了三个<router-view>标签,也就是说咱们须要在路由里配置这三个区域,配置主要是在components字段里进行。

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
import Hi1 from '@/components/Hi1'
import Hi2 from '@/components/Hi2'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      components: {
        default:Hello,
        left:Hi1,
        right:Hi2
      }
    },{
      path: '/Hi',
      components: {
        default:Hello,
        left:Hi2,
        right:Hi1
      }
    }
 
  ]
})

  

上边的代码咱们编写了两个路径,一个是默认的‘/’,另外一个是’/Hi’.在两个路径下的components里面,咱们对三个区域都定义了显示内容。

定义好后,咱们须要在component文件夹下,新建Hi1.vue和Hi2.vue页面就能够了。

Hi1.vue

<template>
    <div>
        <h2>{{ msg }}</h2> 
    </div>
</template>
 
<script>
export default {
  name: 'hi1',
  data () {
    return {
      msg: 'I am Hi1 page.'
    }
  }
}
</script>

H2.vue

<template>
    <div>
        <h2>{{ msg }}</h2>
    </div>
</template>
 
<script>
export default {
  name: 'hi2',
  data () {
    return {
      msg: 'I am Hi2 page.'
    }
  }
}
</script>

最后在App.vue中配置咱们的<router-link>就能够了

<router-link to="/">首页</router-link> | 
<router-link to="/hi">Hi页面</router-link> |

 

五、利用url传参

  在实际开发也是有不少用URL传值的需求,好比咱们在新闻列表中有不少新闻标题整齐的排列,咱们须要点击每一个新闻标题打开不一样的新闻内容,这时在跳转路由时跟上新闻编号就十分实用。

:冒号的形式传递参数

咱们能够在路由配置文件里以:冒号的形式传递参数,这就是对参数的绑定。

  1. 在配置文件里以冒号的形式设置参数。咱们在/src/router/index.js文件里配置路由。
{
    path:'/params/:newsId/:newsTitle',
     component:Params
}

  

  咱们须要传递参数是新闻ID(newsId)和新闻标题(newsTitle).因此咱们在路由配置文件里制定了这两个值。

  2. 在src/components目录下创建咱们params.vue组件,也能够说是页面。咱们在页面里输出了url传递的的新闻ID和新闻标题。

<template>
    <div>
        <h2>{{ msg }}</h2>
        <p>新闻ID:{{ $route.params.newsId}}</p>
        <p>新闻标题:{{ $route.params.newsTitle}}</p>
    </div>
</template>
 
<script>
export default {
  name: 'params',
  data () {
    return {
      msg: 'params page'
    }
  }
}
</script>

   3. 在App.vue文件里加入咱们的<router-view>标签。这时候咱们能够直接利用url传值了。

<router-link to="/params/123/gavin website is very good">params</router-link> |

  

正则表达式在URL传值中的应用

上边的例子,咱们传递了新闻编号,如今需求升级了,咱们但愿咱们传递的新闻ID只能是数字的形式,这时候咱们就须要在传递时有个基本的类型判断,vue是支持正则的。

  加入正则须要在路由配置文件里(/src/router/index.js)以圆括号的形式加入。

path:'/params/:newsId(\\d+)/:newsTitle',

 

六、vue-router的redirect

开发中有时候咱们虽然设置的路径不一致,可是咱们但愿跳转到同一个页面,或者说是打开同一个组件。这时候咱们就用到了路由的从新定向redirect参数。

redirect基本重定向

咱们只要在路由配置文件中(/src/router/index.js)把原来的component换成redirect参数就能够了。咱们来看一个简单的配置export default new Router({  routes: [    {

 
 
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
components: {
HelloWorld : HelloWorld
}
},
{
path: '/params/:newsId(\\d{1,4})/:newsTitle',
name: 'Params',
component: Params
},
{
path: '/gohome',
name: 'GOHOME',
redirect: '/' //重定向使用redirect参数
},
{
path: '/goparams/:newsId(\\d{1,4})/:newsTitle',//带参数的重定向只要照搬初始值便可
name: 'GoParams',
redirect: '/params/:newsId(\\d{1,4})/:newsTitle'//带参数重定向照搬初始值便可
}
]
})
 

这里咱们设置了goback路由,可是它并无配置任何component(组件),而是直接redirect到path:’/’下了,这就是一个简单的从新定向。

重定向时传递参数

咱们已经学会了经过url来传递参数,那咱们重定向时若是也须要传递参数怎么办?其实vue也已经为咱们设置好了,咱们只须要在ridirect后边的参数里复制重定向路径的path参数就能够了。可能你看的有点晕,咱们来看一段代码:

{
  path:'/params/:newsId(\\d+)/:newsTitle',
  component:Params
},{
  path:'/goParams/:newsId(\\d+)/:newsTitle',
  redirect:'/params/:newsId(\\d+)/:newsTitle'
}

已经有了一个params路由配置,咱们在设置一个goParams的路由重定向,并传递了参数。这时候咱们的路由参数就能够传递给params.vue组件了。参数接收方法和正常的路由接收方法同样。

 

七、alias别名的使用

  alias也能够实现相似重定向的效果

  1.首先咱们在路由配置文件里(/src/router/index.js),给上节课的Home路径起一个别名

{
    path: '/hi1',
    component: Hi1,
    alias:'/gavin'
 }

  2.配置咱们的<router-link>,起过别名以后,能够直接使用<router-link>标签里的to属性,进行从新定向。

<router-link to="/gavin">gavin</router-link>

  

  redirect和alias的区别

  • redirect:仔细观察URL,redirect是直接改变了url的值,把url变成了真实的path路径。
  • alias:URL路径没有别改变,这种状况更友好,让用户知道本身访问的路径,只是改变了<router-view>中的内容。

  填个小坑:

  别名请不要用在path为’/’中,以下代码的别名是不起做用的。

{
  path: '/',
  component: Hello,
  alias:'/home'
}

 

 

 八、路由的过渡动画

<transition>标签

想让路由有过渡动画,须要在<router-view>标签的外部添加<transition>标签,标签还须要一个name属性。

<transition name="fade">
  <router-view ></router-view>
</transition>

咱们在/src/App.vue文件里添加了<transition>标签,并给标签起了一个名字叫fade。

css过渡类名:

组件过渡过程当中,会有四个CSS类名进行切换,这四个类名与transition的name属性有关,好比name=”fade”,会有以下四个CSS类名:

  1. fade-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后马上删除。
  2. fade-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成后移除。
  3. fade-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后马上删除。
  4. fade-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除。

从上面四个类名能够看出,fade-enter-active和fade-leave-active在整个进入或离开过程当中都有效,因此CSS的transition属性在这两个类下进行设置。

那咱们就在App.vue页面里加入四种CSS样式效果,并利用CSS3的transition属性控制动画的具体效果。代码以下:

.fade-enter {
  opacity:0;
}
.fade-leave{
  opacity:1;
}
.fade-enter-active{
  transition:opacity .5s;
}
.fade-leave-active{
  opacity:0;
  transition:opacity .5s;

上边的代码设置了改变透明度的动画过渡效果,可是默认的mode模式in-out模式,这并非咱们想要的。下面咱们学一下mode模式。

过渡模式mode:

  • in-out:新元素先进入过渡,完成以后当前元素过渡离开。
  • out-in:当前元素先进行过渡离开,离开完成后新元素过渡进入。
<transition name="fade" mode="out-in">
    <router-view/>
    </transition>

 

  九、mode模式与404页面处理

  mode的两个值

  1. histroy:当你使用 history 模式时,URL 就像正常的 url,例如 http://jsapng.com/lms/,也好看!
  2. hash:默认’hash’值,可是hash看起来就像无心义的字符排列,不太好看也不符合咱们通常的网址浏览习惯。
export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/params/:newsId(\\d{1,4})/:newsTitle',
      name: 'Params',
      component: Params
    },
    {
      path: '/gohome',
      name: 'GOHOME',
      redirect: '/' //重定向使用redirect参数
    },
    {
      path: '/goparams/:newsId(\\d{1,4})/:newsTitle',//带参数的重定向只要照搬初始值便可
      name: 'GoParams',
      redirect: '/params/:newsId(\\d{1,4})/:newsTitle'//带参数重定向照搬初始值便可
    },
    {
      path: '/hi1',
      name: 'Hi1',
      component: Hi1,
      alias: '/gavin'
    }
      ]
})

 

  404页面的设置:

  用户会常常输错页面,当用户输错页面时,咱们但愿给他一个友好的提示,为此美工都会设计一个漂亮的页面,这个页面就是咱们常说的404页面。vue-router也为咱们提供了这样的机制.

  1.设置咱们的路由配置文件(/src/router/index.js):

{
   path:'*',
   component:Error
}

  

  这里的path:’*’就是找不到页面时的配置,component是咱们新建的一个Error.vue的文件。

  2.新建404页面:

    在/src/components/文件夹下新建一个Error.vue的文件。简单输入一些有关错误页面的内容。

<template>
    <div>
        <h2>{{ msg }}</h2>
    </div>
</template>
<script>
export default {
  data () {
    return {
      msg: 'Error:404'
    }
  }
}
</script>

 

十、路由的钩子函数

  

一个组件从进入到销毁有不少的钩子函数,一样在路由中也设置了钩子函数。路由的钩子选项能够写在路由配置文件中,也能够写在咱们的组件模板中。咱们这节课就介绍这两种钩子函数的写法。

路由配置文件中的钩子函数

咱们能够直接在路由配置文件(/src/router/index.js)中写钩子函数。可是在路由文件中咱们只能写一个beforeEnter,就是在进入此路由配置时。先来看一段具体的代码:

{
      path:'/params/:newsId(\\d+)/:newsTitle',
      component:Params,
      beforeEnter:(to,from,next)=>{
        console.log('我进入了params模板');
        console.log(to);
        console.log(from);
        next();
},

咱们在params路由里配置了bdforeEnter得钩子函数,函数咱们采用了ES6的箭头函数,须要传递三个参数。咱们并在箭头函数中打印了to和from函数。具体打印内容能够在控制台查看object。

三个参数:

  1. to:路由将要跳转的路径信息,信息是包含在对像里边的。
  2. from:路径跳转前的路径信息,也是一个对象的形式。
  3. next:路由的控制参数,经常使用的有next(true)和next(false),最重要的next({path ,'XXX'}) , XXX表明要重定向的url,这表示咱们若是想重定向除了refdirect和alias还有一种选择

写在模板中的钩子函数

在配置文件中的钩子函数,只有一个钩子-beforeEnter,若是咱们写在模板中就能够有两个钩子函数可使用:

  • beforeRouteEnter:在路由进入前的钩子函数。
  • beforeRouteLeave:在路由离开前的钩子函数。
export default {
  name: 'params',
  data () {
    return {
      msg: 'params page'
    }
  },
  beforeRouteEnter:(to,from,next)=>{
    console.log("准备进入路由模板");
    next();
  },
  beforeRouteLeave: (to, from, next) => {
    console.log("准备离开路由模板");
    next();
  }
}
</script>

这是咱们写在params.vue模板里的路由钩子函数。它能够监控到路由的进入和路由的离开,也能够轻易的读出to和from的值。

 

  十一、编程式导航

    this.$router.go(-1) 和 this.$router.go(1)

    这两个编程式导航的意思是后退和前进,功能跟咱们浏览器上的后退和前进按钮同样,这在业务逻辑中常常用到。好比条件不知足时,咱们须要后退。
router.go(-1)表明着后退,咱们可让咱们的导航进行后退,而且咱们的地址栏也是有所变化的。
    1.咱们先在app.vue文件里加入一个按钮,按钮并绑定一个goback( )方法。
<button @click="goback">后退</button>

    2.在咱们的script模块中写入goback()方法,并使用this.$router.go(-1),进行后退操做。

<script>
export default {
  name: 'app',
  methods:{
    goback(){
      this.$router.go(-1);
    }
  }
}
</script>

    打开浏览器进行预览,这时咱们的后退按钮就能够向之前的网页同样后退了。

     router.go(1):表明着前进,用法和后退同样

 

 

    this.$router.push(‘/xxx ‘):

    这个编程式导航都做用就是跳转,好比咱们判断用户名和密码正确时,须要跳转到用户中心页面或者首页,都用到这个编程的方法来操做路由。

    咱们设置一个按钮,点击按钮后回到站点首页。

    1.先编写一个按钮,在按钮上绑定goHome( )方法。

<button @click="goHome">回到首页</button>

    2.在<script>模块里加入goHome方法,并用this.$router.push(‘/’)导航到首页

export default {
  name: 'app',
  methods:{
    goback(){
      this.$router.go(-1);
    },
    goHome(){
      this.$router.push('/');
    }
  }
}

 

 

7、vuex

vuex是一个专门为vue.js设计的集中式状态管理架构。状态?我把它理解为在data中的属性须要共享给其余vue组件使用的部分,就叫作状态。简单的说就是data中须要共用的属性。好比:咱们有几个页面要显示用户名称和用户等级,或者显示用户的地理位置。若是咱们不把这些属性设置为状态,那每一个页面遇到后,都会到服务器进行查找计算,返回后再显示。在中大型项目中会有不少共用的数据,因此尤大神给咱们提供了vuex。

 

 一、入门小实验:

首先安装vuex:

cnpm install vuex --save

新建一个vuex文件夹(这个不是必须的),并在文件夹下新建store.js文件,文件中引入咱们的vue和vuex。

import Vue from 'vue';
import Vuex from 'vuex';

使用咱们vuex,引入以后用Vue.use进行引用。

Vue.use(Vuex);

经过这三步的操做,vuex就算引用成功了

如今咱们store.js文件里增长一个常量对象。store.js文件就是咱们在引入vuex时的那个文件。

const state={
    count:1
}

用export default 封装代码,让外部能够引用。

export default new Vuex.Store({
    state
 
})

新建一个vue的模板,位置在components文件夹下,名字叫count.vue。在模板中咱们引入咱们刚建的store.js文件,并在模板中用{{$store.state.count}}输出count 的值。

<template>
    <div>
        <h2>{{msg}}</h2>
        <hr/>
        <h3>{{$store.state.count}}</h3>
    </div>
</template>
<script>
    import store from '@/vuex/store'
    export default{
        data(){
            return{
                msg:'Hello Vuex',
 
            }
        },
        store
        
    }
</script>

在store.js文件中加入两个改变state的方法

const mutations={
    add(state){
        state.count++;
    },
    reduce(state){
        state.count--;
    }
}

这里的mutations是固定的写法,意思是改变的,咱们到时候会用一节课专门讲这个mutations,因此你先不用着急,只知道咱们要改变state的数值的方法,必须写在mutations里就能够了。

 

在count.vue模板中加入两个按钮,并调用mutations中的方法。

<div>
    <button @click="$store.commit('add')">+</button>
    <button @click="$store.commit('reduce')">-</button>
</div>

这样进行预览就能够实现对vuex中的count进行加减了。

 

二、state 状态对象

在第1节咱们已经写了一个 const state ,这个就是咱们说的访问状态对象,它就是咱们SPA(单页应用程序)中的共享值。今天咱们主要学习状态对象赋值给内部对象,也就是把stroe.js中的值,赋值给咱们模板里data中的值。咱们有三种赋值方式,咱们一个一个来学习一下。

  一、computed属性能够在输出前,对data中的值进行改变,咱们就利用这种特性把store.js中的state值赋值给咱们模板中的data值。

 

computed:{
    count(){
        return this.$store.state.count;
    }
}

这里须要注意的是return this.$store.state.count这一句,必定要写this,要不你会找不到$store的。这种写法很好理解,可是写起来是比较麻烦的,那咱们来看看第二种写法。

  二、mapState的对象赋值

咱们首先要用import引入mapState。

import {mapState} from 'vuex';

而后还在computed计算属性里写以下代码:

computed:mapState({
        count:state=>state.count
 })

  三、经过mapState数组赋值

computed:mapState(["count"])

这个算是最简单的写法了,在实际项目开发当中也常常这样使用。

 

三、Mutations状态修改

$store.commit( )

Vuex提供了commit方法来修改状态,咱们粘贴出第一节课的代码内容,简单回顾一下,咱们在button上的修改方法。

<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>

store.js文件:

onst mutations={
    add(state){
        state.count++;
    },
    reduce(state){
        state.count--;
    }
}

值:

这只是一个最简单的修改状态的操做,在实际项目中咱们经常须要在修改状态时传值。好比上边的例子,是咱们每次只加1,而如今咱们要经过所传的值进行相加。其实咱们只须要在Mutations里再加上一个参数,并在commit的时候传递就就能够了。咱们来看具体代码:

如今store.js文件里给add方法加上一个参数n。添加的地方我已经标黄了。

const mutations={
    add(state,n){
        state.count+=n;
    },
    reduce(state){
        state.count--;
    }
}

在Count.vue里修改按钮的commit( )方法传递的参数,咱们传递10,意思就是每次加10.

<p>
   <button @click="$store.commit('add',10)">+</button>
   <button @click="$store.commit('reduce')">-</button>
</p>

这样两个简单的修改咱们就完成了传值,咱们能够在浏览器中实验一下了。

模板获取Mutations方法

实际开发中咱们也不喜欢看到$store.commit( )这样的方法出现,咱们但愿跟调用模板里的方法同样调用。

例如:@click=”reduce”   就和没引用vuex插件同样。

要达到这种写法,只须要简单的两部就能够了:

  1. 在模板count.vue里用import 引入咱们的mapMutations:
import { mapState,mapMutations } from 'vuex';

  2. 在模板的<script>标签里添加methods属性,并加入mapMutations

methods:mapMutations([
        'add','reduce'
]),

经过上边两步,咱们已经能够在模板中直接使用咱们的reduce或者add方法了,就像下面这样。

<button @click="reduce">-</button>

 

备注:

若是想将编写完毕的vue项目上传到服务器上发布,须要在config目录下的index.js文件下找到:

assetsPublicPath: '/', 把它变为assetsPublicPath: './',

而后运行npm run build进行项目打包

 

 

四、getters计算过滤操做

getters从表面是得到的意思,能够把他看做在获取数据以前进行的一种再编辑,至关于对数据的一个过滤和加工。你能够把它看做store.js的计算属性。

getters基本用法:

好比咱们如今要对store.js文件中的count进行一个计算属性的操做,就是在它输出前,给它加上100.

咱们首先要在store.js里用const声明咱们的getters属性。

const getters = {
    count:function(state){
        return state.count +=100;
    }
}

写好了gettters以后,咱们还须要在Vuex.Store()里引入,因为以前咱们已经引入了state盒mutations,因此引入里有三个引入属性。代码以下,

export default new Vuex.Store({
    state,mutations,getters
})

在store.js里的配置算是完成了,咱们须要到模板页对computed进行配置。在vue 的构造器里边只能有一个computed属性,若是你写多个,只有最后一个computed属性可用,因此要对上节课写的computed属性进行一个改造。改造时咱们使用ES6中的展开运算符”…”。

computed:{
    ...mapState(["count"]),
    count(){
        return this.$store.getters.count;
    }
},

须要注意的是,你写了这个配置后,在每次count 的值发生变化的时候,都会进行加100的操做。

用mapGetters简化模板写法:

咱们都知道state和mutations都有map的引用方法把咱们模板中的编码进行简化,咱们的getters也是有的,咱们来看一下代码。

首先用import引入咱们的mapGetters

import { mapState,mapMutations,mapGetters } from 'vuex';

在computed属性中加入mapGetters

...mapGetters(["count"])

 

 

五、actoin异步修改状态

actions和以前讲的Mutations功能基本同样,不一样点是,actions是异步的改变state状态,而Mutations是同步改变状态

在store.js中声明actions

actions是能够调用Mutations里的方法的,咱们仍是继续在上节课的代码基础上进行学习,在actions里调用add和reduce两个方法。

const actions={
addAction(context,n){
context.commit('add',n);
},
reduceAction({commit},n){
commit('reduce',n)
}
}

在actions里写了两个方法addAction和reduceAction,在方法体里,咱们都用commit调用了Mutations里边的方法。细心的小伙伴会发现这两个方法传递的参数也不同。

  • context:上下文对象,这里你能够理解称store自己。
  • {commit}:直接把commit对象传递过来,可让方法体逻辑和代码更清晰明了。

模板中的使用

咱们须要在count.vue模板中编写代码,让actions生效。咱们先复制两个之前有的按钮,并改为咱们的actions里的方法名,分别是:addAction和reduceAction。

<p>
<button @click="addAction(50)">+</button>
<button @click="reduceAction(50)">-</button>
</p>

改造一下咱们的methods方法,首先仍是用扩展运算符把mapMutations和mapActions加入。

methods:{
    ...mapMutations([  
        'add','reduce'
    ]),
    ...mapActions(['addAction','reduceAction'])
},

你还要记得用import把咱们的mapActions引入才可使用。

增长异步检验

咱们如今看的效果和咱们用Mutations做的如出一辙,确定有的小伙伴会好奇,那actions有什么用,咱们为了演示actions的异步功能,咱们增长一个计时器(setTimeOut)延迟执行。在addAction里使用setTimeOut进行延迟执行

const actions={
addAction(context,n){
context.commit('add',n);
setTimeout(()=>context.commit('reduce',n),3000);
console.log('我比reduce先执行')
},
reduceAction({commit},n){
commit('reduce',n)
}
}

 

六、modules模块组

随着项目的复杂性增长,咱们共享的状态愈来愈多,这时候咱们就须要把咱们状态的各类操做进行一个分组,分组后再进行按组编写。那今天咱们就学习一下module:状态管理器的模块组操做。

声明模块组:

在vuex/store.js中声明模块组,咱们仍是用咱们的const常量的方法声明模块组。代码以下:

const moduleA={
    state,mutations,getters,actions
}

声明好后,咱们须要修改原来 Vuex.Stroe里的值:

export default new Vuex.Store({
    modules:{a:moduleA}
})

在模板中使用

如今咱们要在模板中使用count状态,要用插值的形式写入。

<h3>{{$store.state.a.count}}</h3>

若是想用简单的方法引入,仍是要在咱们的计算属性中rutrun咱们的状态。写法以下:

computed:{
    count(){
        return this.$store.state.a.count;
    }
},
相关文章
相关标签/搜索