ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
计算属性与监视就是回调函数,`computed`是计算属性函数、`watch`/`watchEffect`是监视函数,它们都可以监控一个数据的变化,当这个数据发送变化后进行相应的后续处理。 [TOC] # 1. `computed`计算属性 **1. 调用语法** ```js /* 语法1 */ //当只传入一个回调函数时,该回调函数默认为get函数 //当targetValue发送变化时,computed能够监视到数据的变化,并将变化后的值返回 //computed函数返回一个ComputedRef对象,是一个响应式的对象 const returnVal = computed(() => { return targetValue }) /* 语法2 */ //当需要get与set函数时,应该传入一个对象 //当returnVal发送改变时,val就是returnVal改变后的值 const returnVal = computed({ get() { return targetValue } set(val) { targetValue = val } }) ``` **语法1:演示示例** ```html <template> <fieldset> <legend>改变数据</legend> <!-- 4. 在这里让user.firstName发生改变 --> firstName: <input type="text" placeholder="firstName" autocomplete="off" v-model="user.firstName" /><br /> lastName: <input type="text" placeholder="lastName" autocomplete="off" v-model="user.lastName" /> </fieldset> <fieldset> <legend>改变数据后的数据</legend> <!-- 5. 在这里展示发生变化后的数据 --> <input type="text" placeholder="fullName1" autocomplete="off" v-model="fullName1" /> </fieldset> </template> <script lang="ts"> //1. 引入计算属性与监视 import { computed, defineComponent, reactive, ref, watch, watchEffect } from 'vue' export default defineComponent({ setup() { //2. 定义了一个响应式的对象 const user = reactive({ firstName: '东方', lastName: '不败' }) //3. 只监视user.firstName属性,当user.firstName属性值发生变化后,返回它变化后的值 //只监视user.firstName属性,所以user.lastName发生变化时不会被执行 const fullName1 = computed(() => { return user.firstName }) return { user, fullName1, } } }) </script> ``` ![](https://img.kancloud.cn/28/28/2828aac1e4124352f8dc299091ee2281_1262x211.gif) **语法2:演示示例** ```html <template> <fieldset> <legend>改变数据</legend> <!-- 4. 在这里让user.firstName发生改变 --> firstName: <input type="text" placeholder="firstName" autocomplete="off" v-model="user.firstName" /><br /> lastName: <input type="text" placeholder="lastName" autocomplete="off" v-model="user.lastName" /> </fieldset> <fieldset> <legend>改变数据后的数据</legend> <!-- 5. 在这里让fullName2.value发生改变 --> <input type="text" placeholder="fullName2" autocomplete="off" v-model="fullName2" /> </fieldset> </template> <script lang="ts"> //1. 引入计算属性与监视 import { computed, defineComponent, reactive, ref, watch, watchEffect } from 'vue' export default defineComponent({ setup() { //2. 定义了一个响应式的对象 const user = reactive({ firstName: '东方', lastName: '不败' }) //3. 只监视user.firstName属性 const fullName2 = computed({ //当user.firstName属性值发生变化后,返回它变化后的值 get() { return user.firstName }, //当fullName2发生变化后,获取发生变化后的数据并赋值给user.firstName set(val: string) { user.firstName = val } }) return { user, fullName2, } } }) </script> </script> ``` ![](https://img.kancloud.cn/6c/6d/6c6d766f0443cd8e2751ed48a39d9250_1262x211.gif) <br/> # 2. `watch`监视 **1. 调用语法** ```js /* 语法1:只监视一个数据 */ //data:被监视的数据 //(val) => {}:当data发生变化时该回调函数就会被调用 //val:就是data发生变化后的新数据 //immediate:true则默认自动执行一次,因为当obj发生变化时回调才会被调用,newObj才有值, // 但是首次初始化obj时obj并没有发生变化,newObj就是一个空对象。 //deep:true则进行深度监视,即obj可能有多层嵌套,每一层都会被监视;false则只监视obj对象的第一层 watch(data, (val) => {}, {immediate: true, deep: true}) //如果data是一个对象{lastName: '', firstName: ''},也可以如下写 watch(data, ({lastName, firstName}) => {}, {immediate: true, deep: true}) /* 语法2:监视多个数据 */ //当 obj.val1 不是响应式数据时,需要以 ()=>obj.val1 声明才能被监视到 //vals是一个数组,顺序就是 [()=>obj.val1, ()=>obj.val2] 的顺序 watch([()=>obj.val1, ()=>obj.val2], (vals) => {}) ``` **语法1:只监视一个数据演示示例** ```html <template> <fieldset> <legend>改变数据</legend> <!-- 5. 在这里让user发生改变 --> firstName: <input type="text" placeholder="firstName" autocomplete="off" v-model="user.firstName" /><br /> lastName: <input type="text" placeholder="lastName" autocomplete="off" v-model="user.lastName" /> </fieldset> <fieldset> <legend>改变数据后的数据</legend> <!-- 6. 在这里让fullName3.value发生改变 --> <input type="text" placeholder="fullName3" autocomplete="off" v-model="fullName3" /> </fieldset> </template> <script lang="ts"> //1. 引入计算属性与监视 import { computed, defineComponent, reactive, ref, watch, watchEffect } from 'vue' export default defineComponent({ setup() { //2. 定义了一个响应式的对象 const user = reactive({ firstName: '东方', lastName: '不败' }) const fullName3 = ref('') //3. 监视user对象,当user任何一个属性发生变化时都会被执行 //虽然我在这里只写了一个firstName,但是改变lastName时回调也会被执行 //当user任何一个属性发生变化时将变化后的firstName赋值给fullName3.value watch(user, ({ firstName }) => { fullName3.value = firstName }, { immediate: true, deep: true }) //4. 监视fullName3,val就是发生改变后的fullName3.value watch(fullName3, (val) => { user.firstName = val }) return { user, fullName3, } } }) </script> ``` ![](https://img.kancloud.cn/81/5b/815b8601b40267a7efa104b4f73cabad_1262x205.gif) **语法2:监视多个数据演示示例** ```html <template> <fieldset> <legend>改变数据</legend> <!-- 4. 在这里让user发生改变 --> firstName: <input type="text" placeholder="firstName" autocomplete="off" v-model="user.firstName" /><br /> lastName: <input type="text" placeholder="lastName" autocomplete="off" v-model="user.lastName" /> </fieldset> <fieldset> <legend>改变数据后的数据</legend> <!-- 5. 在这里让fullName4.value发生改变 --> <input type="text" placeholder="fullName4" autocomplete="off" v-model="fullName4" /> </fieldset> </template> <script lang="ts"> //1. 引入计算属性与监视 import { computed, defineComponent, reactive, ref, watch, watchEffect } from 'vue' export default defineComponent({ setup() { //2. 定义了一个响应式的对象 const user = reactive({ firstName: '东方', lastName: '不败' }) const fullName4 = ref(1) //3. 监视user.firstName、user.lastName、fullName4 //虽然user是响应式数据,但是user.firstName、user.lastName不是是响应式数据需要以 () => user.firstName 被监听 //fullName4本身就是一个响应式数据,直接放到数组中即可 watch([() => user.firstName, () => user.lastName, fullName4], (vals) => { console.log(vals) }, { immediate: true, deep: true }) return { user, fullName4, } } }) </script> ``` ![](https://img.kancloud.cn/db/07/db0721cc6aff6f41f347e399674729f3_1262x434.gif) <br/> # 3. `watchEffect`监视 `watchEffect`与`watch`的区别是:`watchEffect`不需要配置`{ immediate: true, deep: true }`,默认初始化时就执行一次并可以深层监视。 **1. 调用语法** ```js //直接将targetObj放入回调函数就可以监视targetObj对象的变化了 watchEffect(() => { targetObj }) ``` **2. 演示示例** ```html <template> <fieldset> <legend>改变数据</legend> <!-- 5. 在这里让user.firstName发生改变 --> firstName: <input type="text" placeholder="firstName" autocomplete="off" v-model="user.firstName"/><br/> lastName: <input type="text" placeholder="lastName" autocomplete="off" v-model="user.lastName"/> </fieldset><fieldset> <legend>改变数据后的数据</legend> <!-- 6. 在这里让fullName5.value发生改变 --> <input type="text" placeholder="fullName5" autocomplete="off" v-model="fullName5"/> </fieldset> </template> <script lang="ts"> //1. 引入计算属性与监视 import { computed, defineComponent, reactive, ref, watch, watchEffect } from 'vue' export default defineComponent({ setup() { //2. 定义了一个响应式的对象 const user = reactive({ firstName: '东方', lastName: '不败' }) const fullName5 = ref('') //3. 监视user.firstName属性,当user.firstName值发生变化时则将它变化后的值赋值给fullName5.value //这里只监视user.firstName属性,如果user没有被监视的属性也发生变化不会被调用 watchEffect(() => { fullName5.value = user.firstName }) //4. 监视fullName5.value,当fullName5.value发生变化时则将变化后的值赋值给user.firstName watchEffect(() => { user.firstName = fullName5.value }) return { user, fullName5 } } }) </script> ``` ![](https://img.kancloud.cn/6b/32/6b324aa0a0b2ad973253a87ef6422640_1262x211.gif)