目录
手动指定监听对象
侦听ref对象
侦听ref对象中的某个属性
reactive写法
watchEffect 自动侦听
多源侦听
一次性侦听器
手动指定监听对象
基础语法:
import { watch, ref } from 'vue' const count = ref(0) // 监听单个 ref watch(count, (newVal, oldVal) => { console.log(`计数器变化:${oldVal} → ${newVal}`) }) // 立即执行版 watch(count, callback, { immediate: true })
侦听ref对象
<div id="app">
<select v-model="a">
<option value="10">学生</option>
<option value="12">老师</option>
<option value="14">教务</option>
<option value="16">管理员</option>
</select>
</div>
<script type="module">
import { createApp, ref, reactive, watch } from '/vue.esm-browser.js'
createApp({
setup() {
const a = ref("")
watch(a, (a, b) => {
console.log(a + "-------" + b);
})
return {
a,
}
}
}).mount("#app")
</script>
如果匿名函数只有一个参数,则这个参数代表新值。
watch(a, (a) => {
console.log(a);
})
侦听ref对象中的某个属性
<div id="app"> <select v-model="a.msg"> <option value="10">学生</option> <option value="12">老师</option> <option value="14">教务</option> <option value="16">管理员</option> </select> {{a}} </div> <script type="module"> import { createApp, ref, reactive, watch } from '/vue.esm-browser.js' createApp({ setup() { const a = ref({ msg: "", obj: "" }) watch(() => a.value.msg, (a, b) => { console.log(a + "-------" + b); }) return { a, } } }).mount("#app") </script>
注意:参数绑定的是a.msg,监听的观察要写成() => a.value.msg
reactive写法
<script type="module"> import { createApp, ref, reactive, watch } from '/vue.esm-browser.js' createApp({ setup() { const a = reactive({ msg: "", obj: "" }) watch(() => a.msg, (a, b) => { console.log(a + "-------" + b); }) return { a, } } }).mount("#app")
const z = reactive({ msg: 0 }) watch(z, (n, o) => { console.log(n.msg + '---' + o.msg); })
注意:`newValue` 此处和 `oldValue` 是相等的,因为它们是同一个对象
watchEffect 自动侦听
watchEffect会自动收集所有的依赖,在满足某个条件时执行。默认情况下会立即执行一次。
watchEffect() 的好处相对较小。但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。此外,如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect() 可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。
<div id="app">
<select v-model="a.msg">
<option value="10">学生</option>
<option value="12">老师</option>
<option value="14">教务</option>
<option value="16">管理员</option>
</select>
{{a}}
</div>
<script type="module">
import { createApp, ref, reactive, watch, watchEffect } from '/vue.esm-browser.js'
createApp({
setup() {
const a = reactive({
msg: "1",
obj: ""
})
watchEffect(() => {
console.log("监听开始");
if (a.msg == 10) {
console.log("学生");
}
if (a.msg == 12) {
console.log("老师");
}
if (a.msg == 14) {
console.log("教务");
}
console.log("end");
})
return {
a,
}
}
}).mount("#app")
多源侦听
根据vue的官方文档,发现watch可以侦听多个数据(数组形式),当这个数组中有一个值发生变化,就会执行一次回调函数。
值得一提的是,y
是一个 ref
,所以直接使用 y
而不是 () => y.value。
const x = ref(0)
const y = ref(0)
watch([x, y], ([xn, yn], [xo, yo]) => {
console.log(`新值${xn},${yn}`);
console.log(`旧值${xo},${yo}`);
})
一次性侦听器
注:该功能仅支持 3.4 及以上版本
每当被侦听源发生变化时,侦听器的回调就会执行。如果希望回调只在源变化时触发一次,可以使用once:true
watch(
source,
(newValue, oldValue) => {
// 当 `source` 变化时,仅触发一次
},
{ once: true }
)
const z = reactive({
msg: 0
})
watch(z, (n, o) => {
console.log(n.msg + '---' + o.msg);
},
{ once: true }
)
这样无论侦听源变换多少次,侦听器都只会执行一次。