Skip to content

监视属性(侦听属性)

1. 监视属性watch

  1. 当被监视的属性变化时,回调函数自动被调用,进行相关的操作
  2. 监视的属性必须存在,才能进行监视!!
  3. 监视的两种写法:
    (1)new Vue时传入watch配置中
    (2)通过vm.$wactch配置
js
const vm = new Vue({
  el: "#editor",
  data: {
    msg: "测试一下Vue",
    name: "jack",
    age: 12
  },
  computed: {
    info() {
      return this.name + " " + this.age;
    }
  },
  watch: {
    name: {
      // 初始化时让handler调用一下
      immediate: true,
      // handler什么时候调用,当name发生改变时
      handler(newValue, oldValue) {
        console.log(
          "name被修改了, 修改前:" + oldValue + " 修改后" + newValue
        );
      },
    // 计算属性也可以被监视
    info: {
      handler(newValue, oldValue) {
        console.log(
          "info被修改了, 修改前:" + oldValue + " 修改后" + newValue
        );
      }
    }
    }
  }
});
// 监视可以动态配置,如果监视的属性不存在,也不会报错
vm.$watch("age", {
  immediate: true,
  handler(newValue, oldValue) {
    console.log(
      "age被修改了, 修改前:" + oldValue + " 修改后" + newValue
    );
  }
});

ggg

2. 深度监视

如果需要监视Vue属性是一个多层结构的对象,如果需要监视其中的一个属性的话:

html
<div id="editor">
    <input v-model="info.name"/><br/>
    <h3>你好,{{info.name}}</h3>
    <hr/>
</div>
<script>
const vm = new Vue({
  // el: "#editor",
  data: {
    msg: "测试一下Vue",
    info: {
        name: "jack",
        age: 12
    }
  },
  watch: {
    // 监视多级结构中某个属性的变化
    'info.name': {  //多级结构不允许对象的key加有.所有需要引号引起来
        handler() {
            console.log('name被修改了')
        }
    }
  }
});
vm.$mount("#editor"); 
</script>

如果监视这个Vue属性所有层级结构的话,比如上面的info有很多属性的话,太多属性可以有简便的写法监视,只需要在watch中配置deep:true 总结:

  1. Vue中的watch默认不监测对象内部值得改变(一层)
  2. 配置deep:true 可以监测对象内部值改变(多层)

提示

  1. Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
  2. 使用watch时根据数据具体的结构,决定是否使用深度监视。

3. 监视的简写

js
const vm = new Vue({
    el: "#editor",
    data: {
        msg: "测试一下Vue",
        info: {
            name: "jack",
            age: 12
        },
        address:{
            province: 'sichuan',
            city: 'chengdu'
        }
    },
    watch: {
        // 监视多级结构中所有的变化
        // 'info': {
        //     deep: true,
        //     handler(newValue, oldValue) {
        //         console.log('name被修改了')
        //     }
        // }
        // 简写: 如果不写deep和immediate或者说只有handler,可以使用以下简写形式
        info(newValue, oldValue){
            console.log('name被修改了')
        }
    }
});
//动态配置监视的简写形式, 注意这里不能使用箭头函数,否则里面的this不再是Vue实例
vm.$watch('address', function (newValue, oldValue) {
    console.log('province被修改了')
})

5. 计算属性和监视的区别

computed和wach之间的区别:

  1. computed能完成的功能, watch都可以完成。
  2. watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
  3. computed和wach都能实现的话,往往使用computed更简洁一些。

提示

两个重要的小原则(避免this报错为undefined):

  1. 所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
  2. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm或者组件实例对象。