# 监听器

监听器可以监听 data 对象『属性 / 计算属性』的变化。

需要注意的是,在你决定使用监听器时,你可以先考虑下,你所要实现的功能,使用『计算属性』是否能实现?

# 基本使用

监听器使用起来很简单:只要设置要监听的属性名就可以。例如:

<div id="app" v-cloak>
  <p><label>长方形的长: <input v-model="height"></label></p>
  <p><label>长方形的宽: <input v-model="width"></label></p>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
  const vm = new Vue({
    el: '#app',
    data() {
      return {
        width: 0,
        height: 0
      }
    },
    watch: {
      width() {
        console.info("width 的值变动了");
      },
      height() {
        console.info("height 的值变动了");
      }
    }
  });
</script>

# 监听 data 对象中某个对象的属性

有些时候会将一整个对象存储在 data 对象中。为了监听这个对象的属性变化,可以再监听器的名称中使用 . 操作符,就像访问这个对象属性一样:

<div id="app" v-cloak>
  <p><label>username: <input v-model="tom.username"></label></p>
  <p><label>password: <input v-model="tom.password"></label></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
  const vm = new Vue({
    el: '#app',
    data() {
      return {
        tom: {
          username: '',
          password: ''
        }
      }
    },
    watch: {
     'tom.username'() {
        console.info("用户名变动了");
      },
     'tom.password'() {
        console.info("密码变动了");
      }
    }
  });
</script>

# 获得旧值

当监听器的属性发生变化时,监听器会传入两个参数:

  1. 所监听属性的当前值;

  2. 原来的旧值。

利用这一特性可以用来了解到底发生了什么变化:

watch: {
  'tom.username'(val, oldVal) {
    console.info("用户名变动了,从 " + oldVal + " 变成了 " + val);
  }
}

当然,这里的 val 等于 this.tom.username

# 深度(deep)监听:监听对象的数组

data () {
  return {
    demo:[
      {
        name:'张三',
        age:18
      }, {
        name:'李四',
        age:20
      }
    ]
  }
},
mounted () {
  window.myVue = this
},
watch: {
  demo: {
    handler (val) {
      console.log(val)
    },
    deep: true // 这里是关键,代表递归监听 demo 的变化
  }
},

myVue.demo[0].age = 30  // [{name:'张三', age:30}, {name:'李四',age:20}]