一 侦听响应式ref
侦听响应式ref常量,当常量的ref的value值发生改变时会触发watch
一个小栗子:当输入框的输入内容变化时下方的文本也会跟着改变
<template><div class="box content"><div class="intro"><el-input v-model="input" @change="inputChange"></el-input></div><div class="intro"><el-text>{{ message }}</el-text></div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
import { getCurrentInstance } from 'vue';const instance = getCurrentInstance().proxy;const input = ref("");
const message = ref("");watch(input, (newValue, oldValue) => {message.value = "input值发生了变化,newValue = " + newValue + ", oldValue = " + oldValue;
});/** 事件回调 */
const inputChange = () => {console.log("input value = ", input.value);
}
</script>
<style scoped lang="less">
.box{display: flex;flex-direction: column;margin: 10px;padding: 15px;.intro{padding: 20px;}
}
</style>
二 监听reactive响应式对象
系统默认是深层监听,当响应式对象的属性发生改变时,会触发watch
一个小栗子:当点击一次primary按钮时,可以看到cmpNum的count会加3
<template><div class="box content"><div class="intro"><el-button type="primary" @click="cmpNumChange">cmpNum.count = {{ cmpNum.count }}</el-button></div><div class="intro"><el-text>{{ cmpMsg }}</el-text></div></div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
import { getCurrentInstance } from 'vue';const instance = getCurrentInstance().proxy;const cmpNum = reactive({count: 0});
const cmpMsg = ref("");// 监听reactive响应式对象,系统默认是深层监听,当响应式对象的属性发生改变时,会触发watch
// 当点击一次primary按钮时,可以看到cmpNum的count会加3
watch(cmpNum, (newValue, oldValue) => {cmpMsg.value = "cmpNum.cout = " + cmpNum.count;
});// 注:当监听响应式对象时,不能直接监听响应式对象的value
watch(() => cmpMsg.value,(value) => {console.log("watch cmpMsg value = ", value);}
)/** 事件回调 */
const cmpNumChange = () => {cmpNum.count = cmpNum.count + 2;console.log("cmpNum.value = ", cmpNum.count);
}
</script>
<style scoped lang="less">
.box{display: flex;flex-direction: column;margin: 10px;padding: 15px;.intro{padding: 20px;}
}
</style>
三 深层侦听器
直接给 watch()
传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发
一个小栗子 :当点击button时,会在回调事件中改变person的属性,从而触发侦听器watch
在使用时,主要是在代码中加入:{deep: true}
<template><div class="box content"><div class="intro"><el-button type="primary" @click="changePersonName">person name is {{ state.person.name }}</el-button></div></div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
import { getCurrentInstance } from 'vue';const person = {name: "Pem", age: 20};
const state = ref({person: person});// 使用deep:true属性,进行对象的深层监听
watch (() => state.value.person,(newValue, oldValue) => {console.log("deep newValue = ", newValue);console.log("deep oldValue = ", oldValue);},{deep: true}
)/** 事件回调 */
const changePersonName = () => {state.value.person.name = input.value + ".Pem";
}
</script>
<style scoped lang="less">
.box{display: flex;flex-direction: column;margin: 10px;padding: 15px;.intro{padding: 20px;}
}
</style>
四 即时回调的侦听器
watch在默认情况下是懒加载的,仅在数据源发生变化时才会触发。但在某些场景下,我们希望在创建watch时立即执行一次回调。
我们可以通过传入 immediate: true
选项来强制侦听器的回调立即执行。
一个小栗子:
<template><div class="box content"><div class="intro"><el-input v-model="immediateInput"></el-input></div></div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';const immediateInput = ref("");// 即使回调的侦听器
/*
watch默认是懒执行的:仅当数据变化时,才会执行回调。但在某些场景中,我们希望在创建某些侦听器时,
立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据
在下面的例子中,可以看到在页面第一次渲染出来后就可以看到在watch中设置的初始值,说明这个watch
被执行了一次
*/
watch (() => immediateInput.value,(newValue, oldValue) => {console.log("new value = ", newValue);if (newValue === "") {getStartValue();}},{immediate: false} //这里需要加入这句
)
function getStartValue(){immediateInput.value = "start base value";console.log("getStartValue");
}
</script>
<style scoped lang="less">
.box{display: flex;flex-direction: column;margin: 10px;padding: 15px;.intro{padding: 20px;}
}
</style>