Vue3中watch監(jiān)聽(tīng)的五種情況詳解
一、watch
1.1. 監(jiān)聽(tīng)ref定義的基本類型數(shù)據(jù)
監(jiān)視
ref
定義的【基本類型】數(shù)據(jù):直接寫數(shù)據(jù)名即可,監(jiān)視的是其value
值的改變。
1.1.1. 單個(gè)監(jiān)聽(tīng)
let num = ref(1); watch(num, (newValue, oldValue) => { console.log(newValue, oldValue); });
1.1.2. 多個(gè)監(jiān)聽(tīng)
import { ref, watch } from "vue"; let num1 = ref(1); let num2 = ref(2); watch([num1, num2], ([newNum1, newNum2], [oldNum1, oldNum2]) => { console.log(newNum1, newNum2, oldNum1, oldNum2); });
1.2. 監(jiān)聽(tīng)ref定義的對(duì)象類型數(shù)據(jù)
監(jiān)視ref
定義的【對(duì)象類型】數(shù)據(jù):直接寫數(shù)據(jù)名
注意:
- 監(jiān)視的是對(duì)象的【地址值】,若想監(jiān)視對(duì)象內(nèi)部的屬性,需要手動(dòng)開(kāi)啟深度監(jiān)視。
- 若修改的是ref定義的對(duì)象中的屬性,因?yàn)樗鼈兪峭粋€(gè)對(duì)象(內(nèi)存地址不變),所以newValue 和 oldValue 都是新值。
- 若修改整個(gè)ref定義的對(duì)象,newValue 是新值, oldValue 是舊值,因?yàn)椴皇峭粋€(gè)對(duì)象了。
<script setup> import { ref, watch } from "vue"; let person = ref({ name: "zs", age: 13, }); function updateName() { person.value.name += "~"; } function updatePerson() { person.value = { name: "ls", age: 18, }; } watch( person, (newValue, oldValue) => { console.log(newValue, oldValue); }, { deep: true, } ); </script> <template> <h1>姓名: {{ person.name }}</h1> <h1>年齡: {{ person.age }}</h1> <button @click="updateName">修改姓名</button> <button @click="updatePerson">修改整個(gè)人</button> </template>
1.3. 監(jiān)聽(tīng)reactive定義的對(duì)象類型數(shù)據(jù)
reactive
不能定義基本類型數(shù)據(jù)
監(jiān)視reactive
定義的【對(duì)象類型】數(shù)據(jù),且默認(rèn)開(kāi)啟了深度監(jiān)視,并且是不可關(guān)閉的深度監(jiān)聽(tīng)。數(shù)據(jù)中的任何一點(diǎn)蛛絲馬跡的變化,都會(huì)被監(jiān)聽(tīng)到。
<script setup> // 監(jiān)視`reactive`定義的【對(duì)象類型】數(shù)據(jù),且默認(rèn)開(kāi)啟了深度監(jiān)視。 import { reactive, watch } from "vue"; let person = reactive({ name: "zs", age: 18, car: { c1: "c1", c2: "c2", }, }); function updateName() { person.name += "~"; } function updatePerson() { person = Object.assign(person, { name: "lisi", age: 13, }); } function updateCar() { person.car.c1 += "1"; } watch(person, (newValue, oldValue) => { console.log("person變化了", newValue); }); </script> <template> <h1>姓名: {{ person.name }}</h1> <h1>年齡: {{ person.age }}</h1> <h1>car: {{ person.car.c1 + "--" + person.car.c2 }}</h1> <button @click="updateName">修改姓名</button> <button @click="updatePerson">修改整個(gè)人</button> <button @click="updateCar">修改car</button> </template>
1.4. 監(jiān)聽(tīng)ref或reactive定義的數(shù)據(jù)中的某個(gè)屬性
監(jiān)視ref
或reactive
定義的【對(duì)象類型】數(shù)據(jù)中的某個(gè)屬性,注意點(diǎn)如下:
- 若該屬性值不是【對(duì)象類型】,需要寫成函數(shù)形式。
- 若該屬性值是依然是【對(duì)象類型】,可直接編,也可寫成函數(shù),建議寫成函數(shù)。
注意點(diǎn): 若是對(duì)象,則監(jiān)視的是地址值,需要關(guān)注對(duì)象內(nèi)部,需要手動(dòng)開(kāi)啟深度監(jiān)視。
<script setup> // 監(jiān)視`reactive`定義的【對(duì)象類型】數(shù)據(jù),且默認(rèn)開(kāi)啟了深度監(jiān)視。 import { reactive, watch } from "vue"; let person = reactive({ name: "zs", age: 18, car: { c1: "c1", c2: "c2", }, }); function updateName() { person.name += "~"; } function updatePerson() { person = Object.assign(person, { name: "lisi", age: 13, }); } function updateCar() { person.car.c1 += "1"; } watch( () => person.name, (newValue, oldValue) => { console.log("person.name變化了", newValue); } ); watch( () => person.car, (newValue, oldValue) => { console.log("person.car變化了", newValue); }, { deep: true, } ); </script> <template> <h1>姓名: {{ person.name }}</h1> <h1>年齡: {{ person.age }}</h1> <h1>car: {{ person.car.c1 + "--" + person.car.c2 }}</h1> <button @click="updateName">修改姓名</button> <button @click="updatePerson">修改整個(gè)人</button> <button @click="updateCar">修改car</button> </template>
1.5. 組合監(jiān)聽(tīng)多個(gè)數(shù)據(jù)
<template> <h1>sum: {{ sum }}</h1> <h1>name: {{ person.name }}</h1> <button @click="updateSum">修改sum</button> <button @click="updateName">修改name</button> </template> <script lang="ts" setup> import { ref, reactive, watch } from "vue"; let sum = ref(0); let person = reactive({ name: "zs", }); function updateName() { person.name += "~"; } function updateSum() { sum.value += 1; } watch([sum, person], ([sumNew, personNew], [sumOld, personOld]) => { console.log(sumNew, personNew, sumOld, personOld); }); </script>
1.6. 清除watch副作用
watch 的第二個(gè)參數(shù)是數(shù)據(jù)發(fā)生變化時(shí)執(zhí)行的回調(diào)函數(shù)。
這個(gè)回調(diào)函數(shù)接受三個(gè)參數(shù):新值、舊值,以及一個(gè)用于清理副作用的回調(diào)函數(shù)。該回調(diào)函數(shù)會(huì)在副作用下一次執(zhí)行前調(diào)用,可以用來(lái)清除無(wú)效的副作用,如等待中的異步請(qǐng)求:
const id = ref(1) const data = ref(null) watch(id, async (newValue, oldValue, onCleanup) => { const { response, cancel } = doAsyncWork(id.value) // `cancel` 會(huì)在 `id` 更改時(shí)調(diào)用 // 以便取消之前未完成的請(qǐng)求 onCleanup(cancel) data.value = await response.json() })
watch 的返回值是一個(gè)用來(lái)停止該副作用的函數(shù):
const unwatch = watch(() => {}) // ...當(dāng)該偵聽(tīng)器不再需要時(shí) unwatch()
以上就是Vue3中watch監(jiān)聽(tīng)的五種情況詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue3 watch監(jiān)聽(tīng)情況的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 一文詳解Vue3的watch是如何實(shí)現(xiàn)監(jiān)聽(tīng)的
- vue3中watch監(jiān)聽(tīng)的四種寫法
- Vue3.0監(jiān)聽(tīng)器watch與watchEffect詳解
- Vue3中watch無(wú)法監(jiān)聽(tīng)的解決辦法
- Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽(tīng)無(wú)效
- 詳解Vue3中Watch監(jiān)聽(tīng)事件的使用
- vue3界面使用router及使用watch監(jiān)聽(tīng)router的改變
- Vue3中watch監(jiān)聽(tīng)使用詳解
- 詳解vue3中watch監(jiān)聽(tīng)的幾種情況
相關(guān)文章
Vue?Mock.js介紹和使用與首頁(yè)導(dǎo)航欄左側(cè)菜單搭建過(guò)程
Mock.js是一個(gè)模擬數(shù)據(jù)的生成器,用來(lái)幫助前端調(diào)試開(kāi)發(fā)、進(jìn)行前后端的原型分離以及用來(lái)提高自動(dòng)化測(cè)試效率,這篇文章主要介紹了Vue?Mock.js介紹和使用與首頁(yè)導(dǎo)航欄左側(cè)菜單搭建,需要的朋友可以參考下2023-09-09詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法
本篇文章主要介紹了詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法,在VUE開(kāi)發(fā)時(shí),數(shù)據(jù)可以使用jquery和vue-resource來(lái)獲取數(shù)據(jù),有興趣的可以了解一下。2017-01-01Vue elementui字體圖標(biāo)顯示問(wèn)題解決方案
這篇文章主要介紹了Vue elementui字體圖標(biāo)顯示問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08解決@vue/cli安裝成功后,運(yùn)行vue -V報(bào):不是內(nèi)部或外部命令的問(wèn)題
這篇文章主要介紹了解決@vue/cli安裝成功后,運(yùn)行vue -V報(bào):不是內(nèi)部或外部命令的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Vue-Element-Admin集成自己的接口實(shí)現(xiàn)登錄跳轉(zhuǎn)
關(guān)于這個(gè)Vue-element-admin中的流程可能對(duì)于新的同學(xué)不是很友好,所以本文將結(jié)合實(shí)例代碼,介紹Vue-Element-Admin集成自己的接口實(shí)現(xiàn)登錄跳轉(zhuǎn),感興趣的小伙伴們可以參考一下2021-06-06