Vue.js - 监听器watch的使用详解(深度监听、属性监听、立即执行、$watch)
作者:hangge | 2026-03-16 09:00
在 data 属性中可以定义响应式数据,并在模板中使用。当响应式数据发生变化时,模板中对应的内容也会自动更新。但在某些情况下,需要监听某个响应式数据的变化,这时就需要使用监听器(watch)来实现了。
(2)上面是 function 语法的完整写法,还可以简写为如下形式:
(2)如果我们启用 deep 选项对对象进行深度监听,那么在三个按钮上依次单击,可以发现 info 内部发生的改变都可以被 watch 监听到,即控制台会打印新旧 info 的信息。
(2)浏览器中运行代码,只需要简单地刷新浏览器,handler 中定义的函数就会立即执行一次:
一、基本用法
1,function 语法
(1)下面是一个 watch 的简单使用样例:
- 有一个输入框(input),用户可在其中输入一个问题。
- 在代码中实时监听用户输入的问题,一旦输入的内容发生变化,就到服务器中查询答案(这里直接为 answer 变量重新赋值,模拟服务器返回答案)。
<template>
<div class="my-component">
<input type="text" v-model="question">
<div>{{ anwser }}</div>
</div>
</template>
<script>
export default {
name: 'MyComponent',
data() {
return {
question: "",
anwser: ""
}
},
// 监听属性
watch: {
// 侦听question的变化
// question :侦听的data中的属性的名称
// newValue :变化后的新值
// oldValue :变化前的旧值
question: function (newValue, oldValue) {
console.log("新值: ", newValue, "旧值", oldValue);
// question 变化后调用 queryAnswer() 方法
this.queryAnswer();
}
},
// 方法
methods: {
queryAnswer() {
this.anwser = `你的问题是:${this.question}? `;
}
},
}
</script>
(2)上面是 function 语法的完整写法,还可以简写为如下形式:
// 监听属性
watch: {
// 侦听question的变化
// question :侦听的data中的属性的名称
// newValue :变化后的新值
// oldValue :变化前的旧值
question(newValue, oldValue) {
console.log("新值: ", newValue, "旧值", oldValue);
// question 变化后调用 queryAnswer() 方法
this.queryAnswer();
}
},
2,对象语法
对象语法和 function 语法的编写方式略有不同,但它们所实现的功能是相同的。
watch: {
// 侦听question的变化
// question :侦听的data中的属性的名称
// newValue :变化后的新值
// oldValue :变化前的旧值
question: {
handler(newValue, oldValue) {
console.log("新值: ", newValue, "旧值", oldValue);
// question 变化后调用 queryAnswer() 方法
this.queryAnswer();
}
}
},
3,字符串语法
下面是一个字符串语法样例,监听属性 question 的值是 queryAnswer 字符串。当 question 发生变化时,会触发 queryAnswer 函数的回调。
// 监听属性
watch: {
question: 'queryAnswer'
},
// 方法
methods: {
queryAnswer() {
this.anwser = `你的问题是:${this.question}? `;
}
},
4,数组语法
下面样例监听属性 question 的值是一个数组,数组中的第一项为字符申语法、第二项是函数语法、第三项是对象语法。当 question 值发生改变时,会依次调用 handle1、handle2 和 handle3 函数。// 监听属性
watch: {
question: [
'handle1',
function handle2(newVal, oldVal) {
console.log('handle2', newVal, oldVal)
},
{
handler: function (newVal, oldVal) {
console.log('handle3', newVal, oldVal)
},
}
]
},
// 方法
methods: {
handle1() {
console.log('handle1')
}
}
5,$watch 的 API 语法
(1)Vue.js 还提供了 watchAPI 进行监听。例如我们可以在 created 生命周期中使用 this.$watch 进行监听,其使用语法为 this.$watch(source, callback, options)。
- source:要监听的源。
- callback:监听的回调函数。
- options:额外的选项,比如 deep、immediate。
(2)下面样例使用 this.$watch 监听 data 属性中定义的对象类型变量 info。
created() {
this.$watch('info', function (newVal, oldVal) {
console.log('watch', newVal, oldVal)
}, { deep: true, immediate: true })
},
二、watch 配置选项
1,基本介绍
watch 对象语法的常见配置选项有以下几种:
- handler:要监听的回调函数,当监听属性发生变化时会调用该函数。(这个在上面样例中已经演示了)
- deep:是否深度监听对象或数组中每个属性的变化,默认值是 false。
- immediate:是否立即执行回调函数,默认值是 false。
2,deep 选项
(1)由于 deep 默认值为 false,即不会深度监听对象中属性的变化。下面样例运行后会发现:
- 单击“改变 info”按钮,watch 能够监听到 info 变量的更新
- 单击“改变 info.name”按钮,发现页面上显示的 name 已经更新,但是 watch 却没有检测到 info 对象的修改,即控制台不会打印出新旧 info 的信息。
- 单击“改变改变 info.site.name”按钮,发现页面上显示的 info.site.name 已经更新,但是 watch 却没有检测到 info 对象的修改,即控制台不会打印出新旧 info 的信息。
<template>
<div class="my-component">
<h2>{{ info.name }}</h2>
<h2>{{ info.site.name }}</h2>
<button @click="changeSite">改变info</button>
<button @click="changeSiteName">改变info.site</button>
<button @click="changeSiteBookName">改变info.site.name</button>
</div>
</template>
<script>
export default {
name: 'MyComponent',
data() {
return {
info: { name: "hangge", age: 18, site: { name: '航歌' } }
}
},
// 监听属性
watch: {
// 侦听info对象的更新
info: {
handler: function (newInfo, oldInfo) {
console.log("newValue:", newInfo, "oldValue:", oldInfo);
}
}
},
methods: {
changeSite() {
this.info = { name: "baidu", age: 18, site: { name: '百度' } }
},
changeSiteName() {
this.info.name = "google";
},
changeSiteBookName() {
this.info.site.name = "谷歌";
}
},
}
</script>
(2)如果我们启用 deep 选项对对象进行深度监听,那么在三个按钮上依次单击,可以发现 info 内部发生的改变都可以被 watch 监听到,即控制台会打印新旧 info 的信息。
watch: {
// 侦听info对象的更新
info: {
handler: function (newInfo, oldInfo) {
console.log("newValue:", newInfo, "oldValue:", oldInfo);
},
// 深度侦听 info 对象的更新(info内部发生的改变是可以侦听到的)
deep: true
}
},
3,immediate 选项
(1)immediate 选项可以让 handler 中定义的函数立即执行一次,在默认情况下,该函数只在监听的数据发生变化时才会回调。下面代码我在 watch 属性中的 info 对象多了 immediate:true 配置:
watch: {
// 侦听info对象的更新
info: {
handler: function (newInfo, oldInfo) {
console.log("newValue:", newInfo, "oldValue:", oldInfo);
},
// 深度侦听 info 对象的更新(info内部发生的改变是可以侦听到的)
deep: true,
immediate: true // 让handler中定义的函数立即执行一次
}
},
(2)浏览器中运行代码,只需要简单地刷新浏览器,handler 中定义的函数就会立即执行一次:

附:仅监听对象中的某个属性
(1)前面提到,当需要监听一个对象时,可以使用 watch 选项。如果想要监听对象的引用的变化或者监听对象内部属性的变化,那么可以配置 deep 选项。
(2)除此之外,还可以直接监听对象中某个属性的变化,而不是监听整个对象。 比如下面样例,仅监听 info 对象中 name 属性的变化。
watch: {
"info.name": {
handler: function (newInfo, oldInfo) {
console.log("newValue:", newInfo, "oldValue:", oldInfo);
}
}
},
全部评论(0)