在vue的项目中,咱们时常会须要对data的改变作出处理,这时候就须要用到watch和computed这两个属性,既然都是数值改变触发改变的属性,他们之间又有什么异同呢?vue
var vm = new Vue({ el: '#app', data: { message: 'red' }, template: ` <div> <p>我是原始值: "{{ message }}"</p> <p>我是计算属性的值: "{{ computedMessage}}"</p> // computed 在 DOM 里直接使用不须要调用 </div> `, computed: { // 计算属性的 getter computedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })
结果:
我是原始值: "red"
我是计算属性的值: "der"缓存
若是不使用计算属性,那么 message.split('').reverse().join('') 就会直接写到 template 里,那么在模版中放入太多声明式的逻辑会让模板自己太重,尤为当在页面中使用大量复杂的逻辑表达式处理数据时,会对页面的可维护性形成很大的影响app
并且计算属性若是依赖不变的话,它就会变成缓存,computed 的值就不会从新计算异步
因此,若是数据要经过复杂逻辑来得出结果,那么就推荐使用计算属性函数
Vue 实例将会在实例化时调用$watch()
,遍历 watch 对象的每个属性this
new Vue({ data: { n: 0, obj: { a: "a" } }, template: ` <div> <button @click="n += 1">n+1</button> <button @click="obj.a += 'hi'">obj.a + 'hi'</button> <button @click="obj = {a:'a'}">obj = 新对象</button> </div> `, watch: { n() { console.log("n 变了"); }, obj:{ handler: function (val, oldVal) { console.log("obj 变了") }, deep: true // 该属性设定在任何被侦听的对象的 property 改变时都要执行 handler 的回调,不论其被嵌套多深 }, "obj.a":{ handler: function (val, oldVal) { console.log("obj.a 变了") }, immediate: true // 该属性设定该回调将会在侦听开始以后被当即调用 } } }).$mount("#app");
注意:不该该使用箭头函数来定义 watcher 函数,由于箭头函数没有 this,它的 this 会继承它的父级函数,可是它的父级函数是 window,致使箭头函数的 this 指向 window,而不是 Vue 实例code
vm.$watch("n", function(val, newVal){ console.log("n 变了"); },{deep: true, immediate: true})
相同点:对象
二者都是观察页面数据变化的。继承
不一样点:get