Vue构造选项 - 2 - computed/watch

140 阅读1分钟

1. computed 计算属性

计算属性就是被计算出来的属性就叫计算属性。

new Vue({
  data: {
    user: {
      email: "1",
      nickname: "2",
      phone: "3"
    }
  },
  template:`
		<div>
			{{user.nickname || user.email || user.phone}}
		</div>
`
}).$mount('#app');

以上代码实现在网页中昵称、邮箱、号码依次优先展示。但如果在网页中有多处展示相同内容的地方,重复使用{{user.nickname || user.email || user.phone}}并不方便,且不利于统一处理。

于是使用computed。

new Vue({
  data: {
    user: {
      email: "1",
      nickname: "2",
      phone: "3"
    }
  },
  computed:{
  	displayName(){
    	const user = this.user,
        return user.nickname || user.email || user.phone
    }
  },
  template:`
		<div>
			{{displayName}}
		</div>
	`
}).$mount('#app');

多处使用,统一使用displayName这一计算属性即可。

再给displayName添加getter和setter

computed: {
    displayName: {
      get() {
        const user = this.user;
        return user.nickname || user.email || user.phone;
      },
      set(value) {
         this.user.nickname = value;
      }
    }
  }

关于计算属性的缓存

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。如果依赖的属性没有变化,就不会重新计算,getter/setter默认不会做缓存,Vue做了特殊处理。

2. watch 侦听

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发生了改变。
  • 当执行obj.a += 'hi'时,侦听到obj.a发生了改变,而obj不变
  • 当执行obj = {a:'a'}时,即obj指向一个新的对象,而新对象中的a属性与原来的对象的a属性值相同,于是侦听到obj发生了改变,而obj.a不变。

总结起来就是简单类型进行值的比较,复杂类型进行所保存的地址的比较。

watch的两个参数:

  • deep

    deep为true表示该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深。

    若以上代码进行修改

    watch:{
      obj() {
        handler:{console.log("obj 变了");},
        deep: true
      },
    }
    

    则执行obj.a += 'hi'时,由于obj中的a属性的值发生了变化,所以obj也被视为发生了改变。

  • immediate

    immediate为true表示该回调将会在侦听开始之后被立即调用。默认为false,当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行,设置为true则首次绑定时也执行函数。

3. computed与watch

computed根据你所依赖的数据动态显示新的计算结果,计算结果会被缓存。

watch所监听的data的数据发生变化,便执行回调,在方法中会传入 newVal 和 oldVal。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。如果你需要在某个数据变化时做一些事情,使用watch。

当你有一些数据需要随着其它数据变动而变动时,很容易滥用 watch,这时候应该使用computed计算属性。