vue2 watch 用法

Vue 2 的 watch 选项用于监听组件中数据的变化,并在变化时执行相应的操作。它的用法分为"对象写法"和"数组写法",还可以配置深度监听、立即执行等选项。下面按常见场景逐一说明。


1. 基本用法(函数写法)

监听单个数据属性,最简单、最常用的形式:

js 复制代码
export default {
  data() {
    return {
      msg: 'hello'
    }
  },
  watch: {
    // 监听 msg 的变化
    msg(newVal, oldVal) {
      console.log('msg 变化:', oldVal, '→', newVal)
    }
  }
}

2. 对象写法(带选项)

当需要配置 immediatedeep 等高级选项时使用:

js 复制代码
export default {
  data() {
    return {
      user: { name: 'Tom', age: 18 }
    }
  },
  watch: {
    user: {
      handler(newVal, oldVal) {
        console.log('user 对象变化:', newVal)
      },
      deep: true,      // 深度监听对象内部属性变化
      immediate: true  // 组件创建后立即执行一次 handler
    }
  }
}

3. 监听对象的某个具体属性

监听嵌套对象中的某个字段,用字符串路径:

js 复制代码
export default {
  data() {
    return {
      user: { name: 'Tom', age: 18 }
    }
  },
  watch: {
    // 监听 user.name
    'user.name'(newVal, oldVal) {
      console.log('user.name 变化:', newVal)
    }
  }
}

4. 数组写法(同时监听多个字段)

当多个字段共享同一个回调时,可以用数组:

js 复制代码
export default {
  data() {
    return {
      a: 1,
      b: 2
    }
  },
  watch: {
    // a 或 b 任一变化都会触发
    a: 'someMethod',
    b: 'someMethod'
  },
  methods: {
    someMethod() {
      console.log('a 或 b 变化了')
    }
  }
}

5. 使用 $watch 在运行时动态监听

有时需要在 createdmounted 钩子里根据条件动态监听:

js 复制代码
export default {
  data() {
    return { count: 0 }
  },
  created() {
    this.$watch(
      () => this.count,
      (newVal, oldVal) => {
        console.log('count 变化:', newVal)
      },
      { immediate: true }
    )
  }
}

6. 常见配置项

选项 说明
deep 是否深度监听对象或数组内部变化(默认 false)。
immediate 是否在监听开始后立即执行一次 handler(默认 false)。
flush 控制回调触发时机(Vue2 内部使用较少,Vue3 更常用)。

7. 注意事项

  • 性能 :开启 deep: true 会递归遍历对象,开销较大,尽量避免监听大对象。
  • 数组/对象替换:直接替换整个数组或对象引用(而非修改内部元素)总能被监听到。
  • 数组索引/长度 :直接通过索引修改数组元素 arr[0] = newVal 不会被检测到,应使用 Vue.setthis.$set

8. 完整示例

vue 复制代码
<template>
  <div>
    <input v-model="user.name" />
    <p>姓名:{{ user.name }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: { name: 'Tom' }
    }
  },
  watch: {
    'user.name': {
      handler(newVal, oldVal) {
        console.log(`姓名从 ${oldVal} 改为 ${newVal}`)
      },
      immediate: true
    }
  }
}
</script>

以上覆盖了 Vue 2 中 watch 的绝大多数日常用法,根据场景选择合适的形式即可。