vue 的 computed 和 watch 的区别

190 阅读2分钟

1,computed 是计算属性,在调用的时候,直接当属性去使用,不必写括号去调用。会依赖数据的变化去计算属性。计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。

例如:

new Vue({
  data: {
    user: {
      email: "renshisan@qq.com",
      nickname: "方方",
      phone: "13212312312"
    }
  },
  computed: {
    displayName: {
        const user = this.user;
        return user.nickname || user.email || user.phone;
    }
	},
  template:`
		<div>
			{{displayName}}
		</div>
`
}).$mount('#app');

上述代码就可以优先显示名字、邮箱或者电话。我们如果想展示名字,就直接调用displayName即可。

或者用 get 和 set 来实现:

new Vue({
  data: {
    user: {
      email: "renshisan@qq.com",
      nickname: "方方",
      phone: "13812312312"
    }
  },
  computed: {
    displayName: {
      get() {
        const user = this.user;
        return user.nickname || user.email || user.phone;
      },
      set(value) {
         this.user.nickname = value;
      }
    }
  },
    template:`
		<div>
			{{displayName}}
		</div>
`
}).$mount('#app');

设置displayName是一个对象,在它里面有一个get函数和set函数,通过get函数获取user。然后再通过set函数传一个value。特别注意:这里不能直接this.nickname = value,因为this这里指向全局函数。

2,watch 是监听侦听。当在数据发生变化时,watch 提供了两个选项,immediate,表示是否在第一次渲染的时候是执行这个函数, 默认是false,true 的话表示设置监听之后被立即调用。deep,表示监听一个对象是否要看这个对象属性里面的变化。默认是 false,true 的话表示监听会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深。

总结:

当一个属性受多个属性影响的时候,使用computed;当一条数据影响多条数据的时候,使用watch。

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() {
      console.log("obj 变了");
    },
    "obj.a": function() {
      console.log("obj.a 变了");
    }
  }
}).$mount("#app");

上面代码当中就一个普通的变量和对象,然后有三个按钮分别有三个对应的操作。

  • 当点击 n+1 的时候, n+1 是一个简单类型n会发生改变。(简单类型的值一定会发生改变,因为简单类型存的是值,复杂类型存的才是地址)

  • 当点击 obj.a+"hi" 的时候里面的值依然会发生改变,因为这是一个对象简单类型。

  • 当点击 obj=新对象 的时候这个对象的地址会发生改变vue才会认为这个对象发生了改变。