- 某些情况下需要监听某个响应式数据的变化,这时就需要使用监听器(
watch
)来实现了
watch的使用语法如下
- 选项:watch
- 类型:
{ [key: string]: string | Function | Object | Array}
- 详解:
watch
属性是一个对象,该对象的键(key
)是需要观察的表达式, 值(value
)可以是回调函数、方法名等。Vue.js 3实例会在实例化时调用$watch
来遍历watch
对象的每个属性
下面通过一个案例来演示watch
的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
请输入问题:<input type="text" v-model="question">
<div> {{ answer }}</div>
</template>
<script src="./js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
question: '',
answer: '',
}
},
watch: {
question: function (newValue, oldValue) {
console.log(`新value值: ${newValue}, 旧value值: ${oldValue}`)
this.questionAnswer()
}
},
methods: {
questionAnswer() {
this.answer = `你的问题是${this.question}? 答案: ahahahaha`
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
</html>
- 上面使用的是
watch
的function语法,下面展示了一个对象语法的使用
watch: {
question: {
handler(newValue, oldValue) {
console.log(`新value值: ${newValue}, 旧value值: ${oldValue}`)
this.queryAnswer()
}
}
},
- watch对象语法的常见配置选项有以下几种
handler
:要监听的回调函数,当监听属性发生变化时会调用该函数deep
:是否深度监听对象或数组中每个属性的变化,默认是falseimmediate
:是否立即执行回调函数,默认值是false
handler选项
- 这是Vue.js 3中监听属性变化时的回调函数。当属性发生变化时,该函数会被调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{ info.name }}</h2>
<h2>{{ info.book.name }}</h2>
<button @click="changeInfo">改变info</button>
<button @click="changeInfoName">改变infoName</button>
<button @click="changeInfoBookName">改变infoBookName</button>
</template>
<script src="./js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
info: {
name: "clarence",
age: 18,
book: {
name: "harry potter"
}
}
}
},
watch: {
info: {
handler(newInfo, oldInfo) {
console.log(`newValue: ${newInfo}, oldValue: ${oldInfo}`)
}
}
},
methods: {
changeInfo() {
this.info = {
name: "liu",
age: 100,
book: {
name: "One hundred years of loneliness"
}
}
},
changeInfoName() {
this.info.name = "rose"
},
changeInfoBookName() {
this.info.book.name = "Vue"
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
</html>
- 效果如下图,点击"改变info"之后,发现watch函数打印出结果,这说明调用到了watch函数,而当点击"改变infoName"和改变"infoBookName"按钮之后并没有调用到watch函数
- 这是因为默认情况下watch函数仅监听对info对象引用的变化,而不会监听其内部属性的变化,如果需要监听内部属性的变化,需要使用deep进行深度监听
deep
- deep选项用于配置是否深度监听对象中属性的变化,修改watch函数如下
watch: {
info: {
handler(newInfo, oldInfo) {
console.log(`newValue: ${newInfo}, oldValue: ${oldInfo}`)
},
// 深度监听info对象的更新, info内部属性的改变均可被监听到
deep: true
}
},
immediate
- immediate选项可以让handler中定义的函数立即执行一次,默认情况下,该函数只在监听的数据发生变化时才会回调,像下面这样
watch: {
info: {
handler(newInfo, oldInfo) {
console.log(`newValue: ${newInfo}, oldValue: ${oldInfo}`)
},
// 深度监听info对象的更新, info内部属性的改变均可被监听到
deep: true,
// handler中定义的函数立即执行一次
immediate: true,
}
},
- 可以实现的效果是每次刷新页面都会立即执行一次handler中定义的函数
此外,watch还可以只监听对象中的某个属性,比如上面的例子中,我只希望监听info中的name属性,那么watch可以这样写
watch: {
"info.name": {
handler(newInfo, oldInfo) {
console.log(`newValue: ${newInfo}, oldValue: ${oldInfo}`)
},
// 深度监听info对象的更新, info内部属性的改变均可被监听到
deep: true,
// handler中定义的函数立即执行一次
immediate: true,
}
},