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