在Vue中,methods、 computed 和 watch 都可以呈现类似的最终效果,甚至将同一个函数定义为methods、 computed 和 watch,那么它们有什么区别呢?
1. 从性质上看
methods是定义在vue实例里的函数,需要手动调用。
类型: { [key: string]: Function }
methods对象中,键是函数名称,值是对应的函数。
computed是计算属性,在取用时与data对象里的数据属性方式相同。
类型: { [key: string]: Function | { get: Function, set: Function } }
computed对象中,键是函数名称,值是对应的函数表达式。
使用 get 与 set 实现双向绑定。
watch是监听属性,在取用时与data对象里的数据属性方式相同。但watch调用的函数是回调函数。
类型: { [key: string]: string | Function | Object }
watch对象中,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。
ps:watch虽然可以监听到对象的变化,但是无法监听到具体对象里面那个属性的变化。
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
//当firstName发生改变之后,firstName对应的函数才会被调用
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
2. 从作用机制上看
methods中保存着vue实例的函数,在使用时需要手动调用才能执行。
<!-- 在模板中调用 -->
<p>Reversed message: "{{ reversedMessage() }}"</p>
<button v-on:click="doThis()"></button>
<!-- 或者直接使用函数名 -->
<button v-on:click="doThis"></button>
另外,手动调用也意味着我们可以传参,以及事件对象。
<!-- 直接使用函数名调用时,会默认将第一个参数作为事件对象 $event -->
<!-- 调用函数传参时,事件对象 $event 必须作为最后一个参数显式传递-->
<button v-on:click="say("Hi",$event)"></button>
watch和computed是调用属性,将自动调用相关函数,不需要手动调用。
<!-- 在模板中调用时不需要 "()" -->
<p>Reversed message: "{{ reversedMessage }}"</p>
为watch和computed都以Vue的依赖追踪机制为基础,当某个数据发生变化时,所有依赖这个数据的“相关”数据“自动”发生变化,即自动调用相关函数。
在下面的例子中,computed属性调用的computedDate函数,data中不存在依赖值,所以只会返回一次new Date值,因为computed的依赖值并未发生改变,而computed只会提供缓存的值(多次调用不会变化),但是methods会不断被调用
new Vue({
el: '#app',
methods: {
getMethodsDate: function () {
alert(new Date())
},
// 返回computed选项中设置的计算属性——computedDate
getComputedDate: function () {
alert(this.computedDate)
}
},
computed: {
computedDate: function () {
return new Date()
}
}
})
3. 从使用场景上看
methods、 computed 和 watch 对应不同的使用场景:
- methods适用于各类场景,因为它不处理数据逻辑关系,只提供可调用的函数
- computed适用于“一个数据受多个数据影响”的使用场景
- watched适用于“一个数据影响多个数据”的使用场景
computed的使用场景:一个数据受多个数据影响
当我们需要对data进行转化(感觉有点像excel的数据透视图),并且依赖于其它数据时,应该使用 computed,因为只有 computed 依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。利用 computed 的缓存特性,避免每次获取值时,都要重新计算。
watch的使用场景:一个数据影响多个数据
当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。