Vue.js中的methods,computed,watch。

写这篇文章好像有点多余了,可是我以为仍是有多数新手搞不懂它们的区别。数组

那咱们从字面意思来看它们:bash

  • methods: 方法。组件或者实例声明方法的地方。
  • computed: 计算。用来计算(监听)属性的变化。
  • watch 观察。用来观察(监听)属性的变化。

咱们下面分解学习它们。app


methods

methods里声明的方法,都能在当前组件或者实例中使用。经过this.xx调用。函数

例子:学习

<div id="app">
    <div>{{count}}</div>
    <button @click="add">点击+1</button>
</div>

var app = new Vue({
    el: '#app', //挂载到#app上
    data(){
        return {
            count:0
        }
    },
    methods:{
        add(){
            this.count+=1;
        }   
    },
    
})
复制代码

<button @click="add">点击+1</button> 中的@click就是v-on:click的缩写,用来监听DOM的click事件。ui

固然咱们还能够这样写:this

<div id="app">
    <div>{{count}}</div>
    <button @click="count+1">点击+1</button>
</div>
复制代码

但不推荐这样写,若是逻辑稍微多一些这样是不可行的,仍是要在methods定义一个方法。固然v-on不但能够接收一个方法名称,还能够传参数:spa

<div id="app">
    <div>{{count}}</div>
    <button @click="add(100)">点击+1</button>
</div>

var app = new Vue({
    el: '#app', //挂载到#app上
    data(){
        return {
            count:0
        }
    },
    methods:{
        add(num){
            this.count = num;
        }   
    },
})
复制代码

computed

computed里的属性,都不用在data里定义,也能够经过this.xx访问到,若是在data里定义会报错The computed property "doubleCount" is already defined in data.code

例子:咱们计算2倍的count。 两种方式:对象

1.
<div id="app">
    <div>{{count}}</div>
    <div>2倍的{{count*2}}</div>
    <button @click="add">点击+1</button>
</div>
var app = new Vue({
    el: '#app',
    data(){
    	return {
            count:0,
    	}
    },
    methods:{
        add(){
            this.count +=1;
        }   
    },
})
复制代码
2.
<div id="app">
    <div>{{count}}</div>
    <div>2倍的{{doubleCount}}</div>
    <button @click="add">点击+1</button>
</div>
var app = new Vue({
    el: '#app',
    data(){
    	return {
            count:0,
    	}
    },
    methods:{
        add(){
            this.count +=1;
        }   
    },
    computed:{
        doubleCount(){
            return this.count*2;
        }
    }
})
复制代码

咱们知道{{}} 里面是能够写表达式的。可是当逻辑复杂一些,咱们就须要用到 computed

这里咱们声明了一个计算属性 doubleCount。函数里面return的值 就是该计算属性的依赖项,也就是说doubleCount的值是根据return后面的值的变化而变化的。可是这是有条件的:依赖项必须是响应式的,不然doubleCount的值是不会随着依赖项的改变而改变的。

咱们看官网的例子:

<div id="app">
    <div>当前时间{{now}}</div>
</div>
computed: {
  now: function () {
    return Date.now()
  }
}

复制代码

如今计算属性now的依赖项是Date.now(),很显然Date.now()是一直改变的,但它并非响应式的数据。因此now不会随着Date now()的值的改变而改变。所以now的值是一开始就肯定了。

工做中经常使用的例子:

咱们知道Vue 是不建议 v-for & v-if 一块儿使用的

items:[
    {
        name:'aa',
        status:false
    },
    {
        name:'bb',
        status:true
    },
    {
        name:'cc',
        status:true
    }
]
复制代码

如今咱们须要循环 items可是咱们只须要显示status == true的数据,通常咱们会这么作。

<ul>
    <li v-for="(item,index) in items" v-if="item.status" :key='index'>{{item.name}}</li>
</ul>
复制代码

能够说是很简单了,可是上面提到了 不建议 v-for & v-if 一块儿使用。这个时候咱们就用到了咱们的computed

<ul>
    <li v-for="(item,index) in showItems" v-if="item.status" :key='index'>{{item.name}}</li>
</ul>

computed: {
  // 定义一个计算属性 showItems 返回一个 items过滤后的数组。
  showItems: function () {
    return this.items.filter(v => v.status)
  }
}
复制代码

watch

侦听属性。简单的理解:当你监听的属性改变的时候你想 do something。这个时候的监听的属性就须要在data里面定义或者是computed定义的属性。

用法:监听this.count的改变,当this.count改变的时候,会触发watch里面的count方法

<div id="app">
    <div>{{count}}</div>
    <button @click="add">点击+1</button>
</div>
var app = new Vue({
    el: '#app',
    data(){
        return {
            count:1,
        }
    },
    methods:{
        add(num){
            this.count ++;
        }   
    },
    watch:{
        count(newVal,oldVal){
            console.log(newVal); //改变以后的值
            console.log(oldVal);//改变以前的值
        }
    }
})
复制代码

那咱们还拿上面的例子:计算2倍的count。

<div id="app">
    <div>{{count}}</div>
    <div>{{doubleCount}}</div>
    <button @click="add">点击+1</button>
</div>
var app = new Vue({
    el: '#app',
    data(){
        return {
            count:1,
            doubleCount:0
        }
    },
    methods:{
        add(num){
            this.count ++;
        }   
    },
    watch:{
        count(newVal,oldVal){
            this.doubleCount = newVal*2;
        }
    }
})
复制代码

count改变的时候咱们改变 this.doubleCount 的值。这里跟computed能实现一样的效果。可是watch监听的属性,只有在属性值改变的时候才会触发属性对应的方法。也就是当this.count改变的时候才会触发watch里面的count方法。这个时候this.doubleCount初始值就仍是 0。并非 2。

immediate [ɪˈmiːdiət]

watch里面的参数。上面说了 watch里面的count对应的方法,只有在this.count改变的时候才会触发。这个时候immediate: true就可让他默认触发。要使用immediate 就要改变watch里面的数据解构。

watch:{
    count:{
        handler(newVal,oldVal) {
          this.doubleCount = newVal*2
        },
        immediate: true
    }
}
复制代码

这个时候只要watch监听了count。默认就会执行对应的 handler方法。这个时候this.doubleCount就为2。

deep [diːp]

watch里面的参数。咱们都知道对象 {} 都指向一个内存地址。当其属性改变的时候,对象的内存地址没发生改变。故当watch监听一个对象的时候,对象属性发生改变,watch监听不到。

例子:

<div id="app">
    <div>{{count}}</div>
    <div>{{doubleCount}}</div>
    <button @click="add">点击+1</button>
</div>
var app = new Vue({
    el: '#app',
    data(){
        return {
            obj:{
                count:1,
            },
            doubleCount:0
        }
    },
    methods:{
        add(num){
            this.obj.count ++;
        }   
    },
    watch:{
        obj(newVal,oldVal){
            this.doubleCount = newVal.count*2;
        }
    }
})
复制代码

当改变obj.count的时候并不会触发watch里对应的obj方法。这个时候就用到了deep

为了发现对象内部值的变化,能够在选项参数中指定 deep: true 。注意监听数组的变更不须要这么作。

<div id="app">
    <div>{{count}}</div>
    <div>{{doubleCount}}</div>
    <button @click="add">点击+1</button>
</div>
var app = new Vue({
    el: '#app',
    data(){
        return {
            obj:{
                count:1,
            },
            doubleCount:0
        }
    },
    methods:{
        add(num){
            this.obj.count ++;
        }   
    },
    watch:{
        obj:{
            handler(newVal,oldVal) {
                console.log(newVal +'--'+ oldVal )
                this.doubleCount = newVal.count*2;
            },
            immediate: true,//默认触发 handler 方法
            deep:true
        }
    }
})
复制代码

这样就完成了对一个对象的监听。

咱们会发现 methods,computed,watch。会有一些相同之处,同一个效果用这三个都能实现。可是咱们在实际开发的时候仍是要让它们各司其职,不要弄混了。

这篇文章较浅。若是你以为有用,就点个赞~~~

相关文章
相关标签/搜索