Vue 中的computed 和 watch

768 阅读1分钟

Computed

计算属性是通过监听依赖的变化而产生对应的属性,这让计算属性必须包含return

计算属性包含了getset两部分,默认只有get,set需要自行添加,set在设置属性是,是修改属性的依赖而不是直接修改属性

computed{
    fullname:{
        get:{
            return this.firstName+' ' +this.lastName
        }
        set:function(newName){
            let names = newName.splict( ' ')
            this.firstName = names[0]
            this.lastName = names[name.length-1]
        }
    }
}

vm.fullname = 'jack ma',setter被调用,this.firstNamethis.lastName 发生改变

注意:computed 可以对属性缓存,当依赖没有发生改变时,依旧读取的是缓存的结果,并不会多次执行代码。并且可以利用闭包的方法来达到传参的的目的。

:data="closure(item, itemName, blablaParams)"
computed: {
 closure () {
   return function (a, b, c) {
        /** do something */
        return data
    }
 }
}

Wathch

侦听属性是通过侦听属性的变化,来做出的一些逻辑。

<template>
  <div class="attr">
    <h1>watch属性</h1>
    <h2>{{ $data }}</h2>
    <button @click="() => (a += 1)">修改a的值</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      a: 1,
      b: { c: 2, d: 3 },
      e: {
        f: {
          g: 4
        }
      },
      h: [],
      obj: { a: 1, }
    };
  },
  watch: {
    a: function(val, oldVal) {
      this.b.c += 1;
    },
    "b.c": function(val, oldVal) {
      this.b.d += 1;
    },
    "b.d": function(val, oldVal) {
      this.e.f.g += 1;
    },
    e: {
      handler: function(val, oldVal) {
        this.h.push("jack");
      },
      deep: true //用于监听e对象内部值的变化
    }
  },
   obj: { 
       handler: function(newVal, oldVal) { 
           console.log(newVal);
           },
       deep: true,
       immediate: true 
       }
    
};
</script>

edeepfalse,那么watch认为this.e.f.g+1只是g发生了变化,而e并没有发生变化。

objimmediatetrue,当代码加载后立即触发一次obj中的handler

两者的对比

image.png

  • watch:监测的是属性值, 只要属性值发生变化,其都会触发执行回调函数来执行一系列操作。
  • computed:监测的是依赖值,依赖值不变的情况下其会直接读取缓存进行复用,变化的情况下才会重新计算。

有点很重要的区别是:计算属性不能执行异步任务,计算属性必须同步执行。也就是说计算属性不能向服务器请求或者执行异步任务。如果遇到异步任务,就交给侦听属性。watch也可以检测computed属性。