前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue成神之路之选项

Vue成神之路之选项

作者头像
小胖
发布2018-12-13 16:08:37
3K0
发布2018-12-13 16:08:37
举报
前言

记录平时学到的知识,标题写的大气一点,也算是给自己一点鼓励,希望在技术这条路可以远走越远,路越走越宽~

文中代码地址

PS:如果对你有一点帮助,请顺手给个小星星哦,鼓励我继续写下去~

引入的文件文件说明

vue.js——开发版本:包含完整的警告和调试模式 vue.min.js——生产版本:删除了警告,进行了压缩

1. propsData Option 全局扩展的数据传递

propsData在实际开发中使用的并不多,用在全局扩展时进行传递数据,主要搭配Vue.extend使用。

在实际的项目中,使用全局扩展的方式制作自定义标签比较少用,完全可以使用组件来替代。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>propsData Option</title>
</head>
<body>
    <h1>propsData Option</h1>
    <hr>
    <div id="app"></div>

    <script type="text/javascript">
       var  header_a = Vue.extend({
           template:`<p>{{message}}</p>`,
           data:function(){
               return {
                   message:'Hello,I am Header'
               }
           }
       });
       
       new header_a().$mount('#app');
    </script>
</body>
</html>

扩展标签已经做好了,这时要在挂载时传递数据,就用到了propsData。

使用用propsData三步解决传值:

  1. 在全局扩展里加入props进行接收;
  2. 传递时用propsData进行传递;
  3. 用插值的形式写入模板;

完整代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>propsData Option</title>
</head>
<body>
    <h1>propsData Option</h1>
    <hr>
    <div id="app"></div>

    <script type="text/javascript">
        var  header_a = Vue.extend({
            template:`<p>{{message}}-{{a}}</p>`,
            data:function(){
                return {
                    message:'Hello,I am Header'
                }
            },
            props:['a']
        }); 
        
        new header_a({propsData:{a:1}}).$mount('header');
    </script>
</body>
</html>
2.computed Option 计算选项

computed计算属性的主要作用是在数据渲染之前,根据实际需求对数据进行处理,比如:大小写转换,顺序重排,添加符号……。为了不污染data中定义的数据源,在computed里需要新声明一个对象保存处理之后的数据。

computed计算属性的所有getter和setter的this上下文自动地绑定为 Vue 实例。注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。

代码语言:javascript
复制
computed: {
  aDouble: vm => vm.a * 2 
}

计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。

用计算属性反转新闻数据数组,让最近发生的新闻放在前面显示,demo:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>computed 计算选项</title>
</head>
<body>
    <h1>computed 计算选项</h1>
    <hr>
    <div id="app">
        {{newPrice}}
        <br>
        <br>
        <ul>
            <li v-for="item in reverseNews">{{item.title}} - {{item.date}}</li>
        </ul>
    </div>
    <script type="text/javascript">
        var newsList = [
            {title:'中国香港或就“装甲车被扣”事件追责 起诉涉事运输公司',date:'2017/3/10'},
            {title:'日本第二大准航母服役 外媒:针对中国潜艇',date:'2017/3/12'},
            {title:'中国北方将有明显雨雪降温天气 南方阴雨持续',date:'2017/3/13'},
            {title:'起底“最短命副市长”:不到40天落马,全家被查',date:'2017/3/23'},
        ];

        var app=new Vue({
            el:'#app',
            data:{
                price:100,
                newsList: newsList
            },
            computed:{
                newPrice:function(){
                    return this.price='¥' + this.price + '元';
                },
                reverseNews:function(){
                    return this.newsList.reverse();
                }
            }
        })
    </script>
</body>
</html>

computed 计算属性是非常有用并且在实际的项目开发中经常使用,它在输出数据前可以根据实际项目需求对数据进行处理,改变数据。

3. methods Option 方法选项

在Vue中,可以使用v-on给元素绑定事件,在methods选项中处理一些逻辑方面的事情。在Vue中的逻辑处理,一般都在Vue的methods选项中来处理,那是因为很多事件处理逻辑代码都很复杂,如果直接把JavaScript代码写在v-on指令中有时并不可行,所以在methods中定义方法,让v-on指令来接收(调用)。

一个数字,每点击一下按钮加2:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>methods Option</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>methods Option</h1>
    <hr>
    <div id="app">
        {{ a }}
        <p><button @click="add">add</button></p>
    </div>
    <script type="text/javascript">
        var app=new Vue({
            el:'#app',
            data:{
                a:1
            },
            methods:{
                add () {
                    this.a++
                }
            }
        })
    </script>
</body>
</html>

methods中参数的传递:

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

  1. 在methods的方法中进行声明,比如给add方法传入一个num参数,就要写出add (num){...};
  2. 调用方法时直接传递,比如要传递2这个参数,在button上就直接可以写。<button @click=”add(2)”></button>;

给add添加num参数,并在按钮上调用传递:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>methods Option</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>methods Option</h1>
    <hr>
    <div id="app">
        {{ a }}
        <p><button @click="add(2)">add</button></p>
    </div>
    <script type="text/javascript">
        var app=new Vue({
            el:'#app',
            data:{
                a:1
            },
            methods:{
                add (num) {
                    this.a += num
                }
            }
        })
    </script>
</body>
</html>

这时,再点击按钮时结果每次加2。

methods中的$event参数:

传递的$event参数都是关于你点击鼠标的一些事件和属性。传递方法:

代码语言:javascript
复制
<button @click=”add(2,$event)”>add</button> 。

这时候可以打印一下,看看event到底是个怎样的对象。你会发现,它包含了大部分鼠标事件的属性:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>methods Option</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>methods Option</h1>
    <hr>
    <div id="app">
        {{ a }}
        <p><button @click="add(2,'每次加2', $event)">add</button></p>
    </div>
    <script type="text/javascript">
        var app=new Vue({
            el:'#app',
            data:{
                a:1
            },
            methods:{
                add (num, msg, event) {
                    console.log('num==>', num)
                    console.log('msg==>', msg)
                    console.log('event==>', event)
                    this.a += num
                }
            }
        })
    </script>
</body>

native 给组件绑定构造器里的原生事件:

在实际开发中经常需要把某个按钮封装成组件,然后反复使用,如何让组件调用构造器里的方法,而不是组件里的方法。就需要用到.native修饰器了。

把我们的add按钮封装成组件,声明btn对象:

代码语言:javascript
复制
var btn={
    template:`<button>组件Add</button>`     
}

在构造器里注册组件:

代码语言:javascript
复制
components:{
    "btn":btn
}

用.native修饰器来调用构造器里的add方法:

代码语言:javascript
复制
<p><btn @click.native="add(3)"></btn></p>

完整代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>methods Option</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>methods Option</h1>
    <hr>
    <div id="app">
       {{a}}
       <p><button @click="add(2, '每次加2', $event)">add</button></p>
       <p><btn @click.native="add(3, '每次加3', $event)"></btn></p>
    </div>

    <script type="text/javascript">
       var btn={
           template:'<button>外部组件</button>'
       }
        var app=new Vue({
            el:'#app',
            data:{
                a:1
            },
            methods:{
                add (num, msg, event) {
                    console.log('num==>', num)
                    console.log('msg==>', msg)
                    console.log('event==>', event)
                    this.a += num
                }
            },
            components:{
                "btn":btn
            }
        })
    </script>
</body>
</html>

作用域外部调用构造器里的方法:

这种不经常使用,如果你出现了这种情况,说明你的代码组织不够好。

代码语言:javascript
复制
<button onclick="app.add(4)" >外部调用构造器里的方法</button>

完整代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>methods Option</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>methods Option</h1>
    <hr>
    <div id="app">
       {{a}}
       <p><button @click="add(2, '每次加2', $event)">add</button></p>
       <p><btn @click.native="add(3, '每次加3', $event)"></btn></p>
    </div>
    <button onclick="app.add(4, '每次加4')">外部访问构造器里的方法</button>

    <script type="text/javascript">
       var btn={
           template:'<button>外部组件</button>'
       }
        var app=new Vue({
            el:'#app',
            data:{
                a:1
            },
            methods:{
                add (num, msg, event) {
                    console.log('num==>', num)
                    console.log('msg==>', msg)
                    console.log('event==>', event)
                    this.a += num
                }
            },
            components:{
                "btn":btn
            }
        })
    </script>
</body>
</html>
4. Watch 选项 监控数据

使用watch选项来监控数据的变化。watch选项对应一个对象,键是观察表达式,值是对应回调。值也可以是方法名,或者是对象,包含选项。在实例化时为每个键调用 $watch() 。

天气预报的穿衣指数,它主要是根据温度来进行提示,温度大于26度时,建议穿T恤短袖,温度小于26度大于0度时,建议穿夹克长裙,温度小于0度时建议穿棉衣羽绒服:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>watch Option</title>
</head>
<body>
    <h1>watch Option</h1>
    <hr>
    <div id="app">
        <p>今日温度:{{temperature}}°C</p>
        <p>穿衣建议:{{suggestion}}</p>
        <p>
            <button @click="add">添加温度</button>
            <button @click="reduce">减少温度</button>
        </p>
    </div>

    <script type="text/javascript">
        var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
        var app=new Vue({
            el:'#app',
            data:{
                temperature:14,
                suggestion:'夹克长裙'
            },
            methods:{
                add:function(){
                    this.temperature+=5;
                },
                reduce:function(){
                    this.temperature-=5;
                }
            },
            watch:{
                temperature (newVal,oldVal) {
                    if(newVal>=26){
                        this.suggestion=suggestion[0];
                    }else if(newVal<26 && newVal >=0)
                    {
                        this.suggestion=suggestion[1];
                    }else{
                        this.suggestion=suggestion[2];
                    }
                }
            }
        })
    </script>
</body>
</html>

handler方法和immediate属性:

这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 temperature 改变时才执行监听计算。那我们想要一开始就让它最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 watch 代码如下:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>watch Option</title>
</head>
<body>
    <h1>watch Option</h1>
    <hr>
    <div id="app">
        <p>今日温度:{{temperature}}°C</p>
        <p>穿衣建议:{{suggestion}}</p>
        <p>
            <button @click="add">添加温度</button>
            <button @click="reduce">减少温度</button>
        </p>
    </div>

    <script type="text/javascript">
        var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
        var app=new Vue({
            el:'#app',
            data:{
                temperature:14,
                suggestion:'T恤短袖'
            },
            methods:{
                add:function(){
                    this.temperature+=5;
                },
                reduce:function(){
                    this.temperature-=5;
                }
            },
            watch:{
                temperature: {
                    handler (newVal,oldVal) {
                        if(newVal>=26){
                            this.suggestion=suggestion[0];
                        }else if(newVal<26 && newVal >=0)
                        {
                            this.suggestion=suggestion[1];
                        }else{
                            this.suggestion=suggestion[2];
                        }
                    },
                    // 代表在wacth里声明了temperature这个方法之后立即先去执行handler方法
                    immediate: true
                }
            }
        })
    </script>
</body>
</html>

注意到handler了吗,我们给 temperature 绑定了一个handler方法,之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。

而immediate:true代表如果在 wacth 里声明了 temperature 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。

在上面的事例中把suggestion的初始数据设置为'T恤短袖',而初始温度是14°C,这时如果没有让watch在最初绑定的时候就执行,那么推荐的穿衣就有问题,因为14°C原本是推荐穿'夹克长裙'的,通过让watch在最初绑定的时候就执行完美解决了这个问题。

deep属性: watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听,比如我们 data 里有一个obj属性:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>watch Option</title>
</head>
<body>
    <h1>watch Option</h1>
    <hr>
    <div id="app">
        <p>今日温度:{{obj.temperature}}°C</p>
        <p>穿衣建议:{{obj.suggestion}}</p>
        <p>
            <button @click="add">添加温度</button>
            <button @click="reduce">减少温度</button>
        </p>
    </div>

    <script type="text/javascript">
        var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
        var app=new Vue({
            el:'#app',
            data: {
                obj: {
                    temperature: 14,
                    suggestion:'T恤短袖'
                }
            },
            methods:{
                add:function(){
                    this.obj.temperature+=5;
                },
                reduce:function(){
                    this.obj.temperature-=5;
                }
            },
            watch: {
                obj: {
                    handler(newVal, oldVal) {
                        console.log('obj.a changed', newVal.temperature)
                        if(newVal.temperature>=26){
                            this.obj.suggestion=suggestion[0];
                        }else if(newVal.temperature<26 && newVal.temperature >=0)
                        {
                            this.obj.suggestion=suggestion[1];
                        }else{
                            this.obj.suggestion=suggestion[2];
                        }
                        console.log('obj.a 2', newVal.suggestion)
                    },
                    immediate: true
                }
            } 
        })
    </script>
</body>
</html>

当我们在点击添加温度和减少温度按钮改变obj.temperature的值时,发现是无效的。受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

默认情况下 handler 只监听obj这个属性它的引用的变化,我们只有给obj赋值的时候它才会监听到,比如我们在 mounted事件钩子函数中对obj进行重新赋值:

代码语言:javascript
复制
mounted: {
  this.obj = {
    temperature: 40,
    suggestion:'T恤短袖'
  }
}

这样我们的 handler 才会执行。

如果需要监听obj里的属性temperature的值,这时候deep属性就派上用场了:

代码语言:javascript
复制
watch: {
    obj: {
        handler(newVal, oldVal) {
            console.log('obj.a changed', newVal.temperature)
            if(newVal.temperature>=26){
                this.obj.suggestion=suggestion[0];
            }else if(newVal.temperature<26 && newVal.temperature >=0)
            {
                this.obj.suggestion=suggestion[1];
            }else{
                this.obj.suggestion=suggestion[2];
            }
            console.log('obj.a 2', newVal.suggestion)
        },
        immediate: true,
        deep: true
    }
} 

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

优化,可以使用字符串形式监听:

代码语言:javascript
复制
watch: {
    'obj.temperature': {
        handler(newVal, oldVal) {
            console.log('obj.a changed', newVal)
            if(newVal>=26){
                this.obj.suggestion=suggestion[0];
            }else if(newVal<26 && newVal >=0)
            {
                this.obj.suggestion=suggestion[1];
            }else{
                this.obj.suggestion=suggestion[2];
            }
            console.log('obj.a 2', this.obj.suggestion)
        },
        immediate: true,
        deep: true
    }
} 

这样Vue.js才会一层一层解析下去,直到遇到属性temperature,然后才给temperature设置监听函数。

完整代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>watch Option</title>
</head>
<body>
    <h1>watch Option</h1>
    <hr>
    <div id="app">
        <p>今日温度:{{obj.temperature}}°C</p>
        <p>穿衣建议:{{obj.suggestion}}</p>
        <p>
            <button @click="add">添加温度</button>
            <button @click="reduce">减少温度</button>
        </p>
    </div>

    <script type="text/javascript">
        var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
        var app=new Vue({
            el:'#app',
            data: {
                obj: {
                    temperature: 14,
                    suggestion:'T恤短袖'
                }
            },
            methods:{
                add:function(){
                    this.obj.temperature+=5;
                },
                reduce:function(){
                    this.obj.temperature-=5;
                }
            },
            // watch: {
            //     obj: {
            //         handler(newVal, oldVal) {
            //             console.log('obj.a changed', newVal.temperature)
            //             if(newVal.temperature>=26){
            //                 this.obj.suggestion=suggestion[0];
            //             }else if(newVal.temperature<26 && newVal.temperature >=0)
            //             {
            //                 this.obj.suggestion=suggestion[1];
            //             }else{
            //                 this.obj.suggestion=suggestion[2];
            //             }
            //             console.log('obj.a 2', newVal.suggestion)
            //         },
            //         immediate: true,
            //         deep: true
            //     }
            // }

            //优化使用字符串形式监听
            watch: {
                'obj.temperature': {
                    handler(newVal, oldVal) {
                        console.log('obj.a changed', newVal)
                        if(newVal>=26){
                            this.obj.suggestion=suggestion[0];
                        }else if(newVal<26 && newVal >=0)
                        {
                            this.obj.suggestion=suggestion[1];
                        }else{
                            this.obj.suggestion=suggestion[2];
                        }
                        console.log('obj.a 2', this.obj.suggestion)
                    },
                    immediate: true,
                    deep: true
                }
            } 
        })
    </script>
</body>
</html>

用实例属性写watch监控:

有些时候我们会用实例属性的形式来写watch监控。也就是把我们watch卸载构造器的外部,这样的好处就是降低我们程序的耦合度,使程序变的灵活:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>watch Option</title>
</head>
<body>
    <h1>watch Option</h1>
    <hr>
    <div id="app">
        <p>今日温度:{{temperature}}°C</p>
        <p>穿衣建议:{{suggestion}}</p>
        <p>
            <button @click="add">添加温度</button>
            <button @click="reduce">减少温度</button>
        </p>
    </div>

    <script type="text/javascript">
        var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
        var app=new Vue({
            el:'#app',
            data:{
                temperature:14,
                suggestion:'夹克长裙'
            },
            methods:{
                add:function(){
                    this.temperature+=5;
                },
                reduce:function(){
                    this.temperature-=5;
                }
            }
        })

        app.$watch('temperature',function(newVal,oldVal){
            if(newVal>=26){
                this.suggestion=suggestion[0];
            }else if(newVal<26 && newVal >=0)
            {
                this.suggestion=suggestion[1];
            }else{
                this.suggestion=suggestion[2];
            }
        })
    </script>
</body>
</html>

注销watch:

为什么要注销 watch?因为我们的组件是经常要被销毁的,比如我们跳一个路由,从一个页面跳到另外一个页面,那么原来的页面的 watch 其实就没用了,这时候我们应该注销掉原来页面的 watch 的,不然的话可能会导致内置溢出。当把 watch 写在组件的选项中的,它会随着组件的销毁而销毁。

但是,如果我们使用上面的这样的方式写 watch:

代码语言:javascript
复制
app.$watch('temperature',function(newVal,oldVal){
    if(newVal>=26){
        this.suggestion=suggestion[0];
    }else if(newVal<26 && newVal >=0)
    {
        this.suggestion=suggestion[1];
    }else{
        this.suggestion=suggestion[2];
    }
})

那么就要手动注销了,这种注销其实也很简单:

代码语言:javascript
复制
var unwatch = app.$watch('temperature',function(newVal,oldVal){
    if(newVal>=26){
        this.suggestion=suggestion[0];
    }else if(newVal<26 && newVal >=0)
    {
        this.suggestion=suggestion[1];
    }else{
        this.suggestion=suggestion[2];
    }
})

unWatch(); // 手动注销watch

app.$watch调用后会返回一个值,就是unWatch方法,你要注销 watch 只要调用unWatch方法就可以了。

5. mixins 混入选项

混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。

mixins一般有两种用途:

  1. 在你已经写好了构造器后,需要增加方法或者临时的活动时使用的方法,这时用混入会减少源代码的污染。
  2. 很多地方都会用到的公用方法,用混入的方法可以减少代码量,实现代码重用。

现在有个数字点击递增的程序,假设已经完成了,这时希望每次数据变化时都能够在控制台打印出提示:“数据发生变化”:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>Mixins Option</title>
</head>
<body>
    <h1>Mixins Option Demo</h1>
    <hr>
    <div id="app">
        <p>num: {{ num }}</p>
        <P><button @click="add">增加数量</button></P>
    </div>
    <script type="text/javascript">
        //额外临时加入,用于显示日志
        var addLog={
            updated:function(){
                console.log("数据放生变化,变化成"+this.num+".");
            }
        }

        var app=new Vue({
            el:'#app',
            data:{
                num:1
            },
            methods:{
                add:function(){
                    this.num++;
                }
            },
            //混入
            mixins:[addLog]
        })
    </script>
</body>
</html>

选项合并:

当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合,合并规则:

  1. 值为对象的选项,例如数据对象data、方法对象methods、组件对象components和自定义指令对象directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>Mixins Option</title>
</head>
<body>
    <h1>Mixins Option Demo</h1>
    <hr>
    <div id="app">
        <p>num: {{ num }}</p>
        <P><button @click="add">增加数量</button></P>
    </div>
    <script type="text/javascript">
        //额外临时加入,用于显示日志
        var addLog={
            data: function () {
                return {
                    message: 'hello',
                    foo: 'abc'
                }
            },
            updated () {
                console.log("数据放生变化,变化成"+this.num+".");
            },
            created () {
                console.log('混入对象的钩子被调用==>', this.$data)
            }
        }

        var app=new Vue({
            el:'#app',
            data:{
                num:1,
                message: 'goodbye',
                bar: 'def'
            },
            methods:{
                add:function(){
                    this.num++;
                }
            },
            created () {
                console.log('实例钩子被调用==>', this.$data)
            },
            //混入
            mixins:[addLog]
        })
    </script>
</body>
</html>

打开控制台可以看到,混入的created钩子函数和实例的created钩子函数打印出的this.$data都为{bar: "def", foo: "abc", message: "goodbye", num: 1}

  1. 由1的例子可以看出,同名钩子函数将混合为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

mixins的调用顺序:

从执行的先后顺序来说,都是混入的先执行,然后构造器里的再执行,需要注意的是,这并不是方法的覆盖,而是被执行了两边。

同名钩子函数将混合为一个数组,因此都将被调用。混入对象的钩子将在组件自身钩子之前调用。

全局API混入方式:

可以全局注册混入对象。但应注意使用!因为一旦使用全局混入对象,将会影响到所有之后创建的 Vue 实例。

定义全局的混入,然后在需要这段代码的地方直接引入js,就可以拥有这个功能了:

代码语言:javascript
复制
Vue.mixin({
    updated:function(){
        console.log('我是全局被混入的');
    }
})

注意:全局混入的执行顺序要前于混入和构造器里的方法。

完整代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>Mixins Option</title>
</head>
<body>
    <h1>Mixins Option Demo</h1>
    <hr>
    <div id="app">
        <p>num: {{ num }}</p>
        <P><button @click="add">增加数量</button></P>
    </div>
    <script type="text/javascript">
        //全局混入
        Vue.mixin({
            created () {
                console.log('我是全局混入');
            }
        })

        //额外临时加入,用于显示日志
        var addLog={
            data: function () {
                return {
                    message: 'hello',
                    foo: 'abc'
                }
            },
            updated () {
                console.log("数据放生变化,变化成"+this.num+".");
            },
            created () {
                console.log('混入对象的钩子被调用==>', this.$data)
            }
        }

        var app=new Vue({
            el:'#app',
            data:{
                num:1,
                message: 'goodbye',
                bar: 'def'
            },
            methods:{
                add:function(){
                    this.num++;
                }
            },
            created () {
                console.log('实例钩子被调用==>', this.$data)
            },
            //混入
            mixins:[addLog]
        })
    </script>
</body>
</html>
6. extends Option 扩展选项

通过外部增加对象的形式,对构造器进行扩展。允许声明扩展另一个组件(可以是一个简单的选项对象或构造函数),而无需使用 Vue.extend。这主要是为了便于扩展单文件组件。和 mixins 类似。

选项合并:

当组件和扩展对象含有同名选项时,这些选项将以恰当的方式混合,合并规则:

  1. 值为对象的选项,例如数据对象data、方法对象methods、组件对象components和自定义指令对象directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
  2. 同名钩子函数将混合为一个数组,因此都将被调用。另外,扩展对象的钩子将在组件自身钩子之前调用。

完整代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Extends Optin</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>Extends Optin Demo</h1>
    <hr>
    <div id="app">
        {{message}}
        <p><button @click="add">add</button></p>
    </div>
    <script type="text/javascript">
        var bbb={
            created () {
                console.log("我是扩展出来的钩子函数");
            },
            methods:{
                add () {
                    console.log('我是被扩展出来的方法!');
                }
            }
        };

        var app=new Vue({
            el:'#app',
            data:{
                message:'hello Vue!'
            },
            methods:{
                add () {
                    console.log('我是原生方法');
                }
            },
            created () {
                console.log("我是原生的钩子函数");
            },
            extends:bbb
        })
    </script>
</body>
</html>

打开控制台可以看到,扩展出来的钩子函数先执行,然后是实例的钩子函数;点击按钮之后只有实例的方法被执行。

7. delimiters 选项

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

比如后台渲染模板如swig,也使用“{{ }}“作为渲染,与前端vue的数据绑定“Mustache”语法 (双大括号)产生冲突,此时只要在新建Vue对象时,添加delimiters: ['${', '}'],就搞定了。

现在插值形式就变成了${}。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>delimiters Option</title>
</head>
<body>
    <h1>delimiters Option</h1>
    <hr>
    <div id="app">
        <ul>
            <li v-for=" aa in arr">${aa}</li>
        </ul>
    </div>
    <script type="text/javascript">

        var outData={
            arr:['aaa','bbb','ccc'],
        };

        var app=new Vue({
            delimiters: ['${', '}'],
            el: '#app',
            data: outData
        })
    </script>
</body>
</html>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.11.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 引入的文件文件说明
  • 1. propsData Option 全局扩展的数据传递
  • 2.computed Option 计算选项
  • 3. methods Option 方法选项
  • 4. Watch 选项 监控数据
  • 5. mixins 混入选项
  • 6. extends Option 扩展选项
  • 7. delimiters 选项
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档