Vue-监视属性watch

监视属性

当我们需要监测 计算属性或者data中某个属性的值发送变化时,就可以使用到vue提供的监视属性。
重要的事情说3遍:监视属性是属性,监视属性是属性,监视属性是属性!

下面是监视属性最简单的案例:

new Vue({
  el: '#app',
  data() {
    return {
      isHot: true
    }
  },
  computed: {
    newIsHot(){
      return this.isHot + '111';
    }
  },
  //监视data中的isHot属性
  watch: {
    isHot: {
      handler(newVal,oldVal) {
        console.log('isHot旧值:',oldVal)
        console.log('isHot旧值:',newVal)
      }
    },
    //监视计算属性中的newIsHot属性
    newIsHot: {
      handler(newVal,oldVal) {
        console.log('newIsHot旧值:',oldVal)
        console.log('newIsHot旧值:',newVal)
      }
    }
  }
})

以监视isHot为例,当isHot属性值发生变化时,就调用handler函数。
除了handler函数,还有其他配置,如immediate,如下:

  //监视data中的isHot属性
  watch: {
    isHot: {
      handler(newVal,oldVal) {
        console.log('isHot旧值:',oldVal)
        console.log('isHot旧值:',newVal)
      }
    },
    //监视计算属性中的newIsHot属性
    newIsHot: {
      immediate: true,
      handler(newVal,oldVal) {
        console.log('newIsHot旧值:',oldVal)
        console.log('newIsHot旧值:',newVal)
      }
    }
  }

当immediate为true时(不写默认为false),初始化时会调用一次handler函数(不管属性值有没有被改变)。

除了上面直接在vue实例写watch,还有第二种写法如下:

const vm = new Vue({
  el: '#app',
  data() {
    return {
      isHot: true
    }
  }
})

vm.$watch('isHot',{
  handler(newVal,oldVal) {
    console.log('isHot旧值:',oldVal)
    console.log('isHot旧值:',newVal)
  }
})

两种写法效果都是一样的,但实际可能运用的情况不同。

watch{} 和 $watch的使用场景

如果在写组件时就已经明确了要监视某个属性,那就用watch{};如果刚开始不确定或不需要监视某个属性,但在后面又需要开始监视监视某个属性,就可用$watch。通常都是 this.$watch来使用。

监视属性之深度监视

上面的简单案例中,监视的属性是一个一级层次的属性;但如果监视的属性是多个层级的,那watch还能监视到吗?案例如下:

const vm = new Vue({
  el: '#app',
  data() {
    return {
      isHot: true,
      obj: {
        a: 1,
        b: 2
      }
    }
  },
  //监视data中的isHot属性
  watch: {
    obj: {
      handler(newVal,oldVal) {
        console.log('obj旧值:',oldVal)
        console.log('obj旧值:',newVal)
      }
    }
  }
})

假设我们修改了obj中的a的值,能够监视到obj发生变化了吗?答案是不能,默认情况下,watch只能监视一级层级属性发生的变化,如 x:1,t:true等等。像多级嵌套的属性,watch不能监测到在第二级开始的属性变化。
那有什么时候办法可以实现吗?有的,watch还提供了一个配置:deep,如下:

const vm = new Vue({
  el: '#app',
  data() {
    return {
      isHot: true,
      obj: {
        a: 1,
        b: 2
      }
    }
  },
  //监视data中的isHot属性
  watch: {
    obj: {
      deep: true,
      handler(newVal,oldVal) {
        console.log('obj旧值:',oldVal)
        console.log('obj旧值:',newVal)
      }
    }
  }
})

deep不写默认fasle,为true时表示可监视此属性的多个层级属性的变化情况,进而调用handler。
如果说只想监测一个多层级属性的某个层级的属性,比如说我要监测 obj中的a,b我不监视。那就可以这样写:

const vm = new Vue({
  el: '#app',
  data() {
    return {
      isHot: true,
      obj: {
        a: 1,
        b: 2
      }
    }
  },
  //监视data中的isHot属性
  watch: {
    'obj.a': {
      deep: true,
      handler(newVal,oldVal) {
        console.log('a旧值:',oldVal)
        console.log('b旧值:',newVal)
      }
    }
  }
})

watch简写

watch简写的前提是:监视的属性配置只有handler时,才可简写。如果还有deep等属性需要配置,则不能简写watch。如下:

const vm = new Vue({
  el: '#app',
  data() {
    return {
      isHot: true,
      obj: {
        a: 1,
        b: 2
      }
    }
  },
  //监视data中的isHot属性
  watch: {
    isHot(newVal,oldVal) {
      console.log('isHot旧值:',oldVal)
      console.log('isHot旧值:',newVal)
    }
  }
})
posted @ 2022-05-20 11:15  爱编程DE文兄  阅读(105)  评论(0编辑  收藏  举报