第十三節:帶你梳理Vue2 : watch偵聽器

官方解釋:> 觀察 Vue 實例變化的一個表達式或計算屬性函數。回調函數得到的參數為新值和舊值。表達式只接受監督的鍵路徑。對于更復雜的表達式,用一個函數取代<br/>## 1.  偵聽器的基本使用偵聽器可以監聽data對象屬性或者計算屬性的變化watch是觀察屬性的變化所以watch的屬性名必須要與觀察人的名字保持一致;只要觀察的值發生了變化才會觸發,```html
<div id="app"><!-- 監聽器 --><input type="text" v-model="msg">
</div><script>   const vm = new Vue({el: "#app",data: {msg:""},watch:{msg(){console.log("數據發生了變化")console.log(arguments)}}})
</script>

通過這個理解,我們就會發現, 只要數據一但發生變化,那么監聽函數msg就會被觸發, 監聽函數中接受兩個參數,第一個參數是數據變化后的新值, 第二個參數是數據變化后的舊值


盡管大部分時間我們用不到偵聽器, 但偵聽器對于處理異步操作非常適合,

例如我們需要將用戶輸入的內容延遲5秒后現在在頁面上

<div id="app"><!-- 監聽器 --><input type="text" v-model="msg">{{showMsg}}
</div><script>   const vm = new Vue({el: "#app",data: {msg:"",showMsg: ""},watch:{msg(){let newValue = this.msgsetTimeout(() => {this.showMsg = newValue},5000)}}})
</script>

2. 獲取舊值

偵聽器在數據發生變化的時候就會觸發,觸發時,數據已經更新,我們那到就是新值,那么我們如何獲取之前的舊值呢

其實當監聽的屬性發生變化時,偵聽器會被傳入兩個參數

第一個參數:偵聽器所監聽屬性的當前值,即更新后的值

第二個參數: 原來舊值

<div id="app"><!-- 監聽器 --><input type="text" v-model="msg">
</div><script>   const vm = new Vue({el: "#app",data: {msg:"",},watch:{msg(val, oldval){console.log(val);console.log(oldval);            }}})
</script>

3. 監聽data對象中某個對象的屬性

data屬性中的數據值除了是基本數據類型的數據外,還有可能是對象類型,那么我們如何監聽對象數據的屬性的

<div id="app"><!-- 監聽器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"蘋果",price: 20},},watch:{fruit(val, oldval){console.log(val);console.log(oldval);            }}})
</script>

如果我們按照之前的監聽方式, 那么我們就會發現,當我們修改fruit屬性值的時候,偵聽器不會被觸發, 偵聽器會在fruit對象整體被修改時觸發.


為了監聽對象里某個特定屬性的變化,可以在偵聽器的名稱中使用.操作符, 就像訪問這個對象的屬性

<div id="app"><!-- 監聽器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"蘋果",price: 20},},watch:{"fruit.price"(val, oldval){console.log(val);console.log(oldval);            }}})
</script>

4. 深度監聽

通過上面的例子,我們知道,我們可以監聽對象的特定屬性的變化,可以我們想監聽整個對象的所有屬性的變化就需要給對象所有的屬性添加監聽就不是特別的好,如果我們只是單純的監聽對象,那么屬性的變化并不會觸發監聽器,只有整個對象被替換時才會觸發

所以我們可以通過deep屬性來開啟對象的深度監聽,

4.1 deep 選項

為了發現對象內部值的變化,可以在選項參數中指定 deep: true。注意監聽數組的變更不需要這么做。

如果需要開啟深度監聽,那么監聽器將不再是一個函數,而需要寫成一個對象,對象中配置deep屬性

<div id="app"><!-- 監聽器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"蘋果",price: 20},},watch:{fruit:{// 此時fruite 就是一個配置對象,里面的屬性都是配置選項// handler 就是原來的監聽函數, 當數據變化是執行的函數handler(val,oldval){console.log(val);console.log(oldval);            },// 深度監聽選項deep:true}}})
</script>

此時我們就做到了即監聽這整個對象的變化, 也簡體對象里面所有的屬性的變化,


4.2 immediate選項

監聽除了deep選項外,還有immediate選項

指定 immediate: true 將立即以表達式的當前值觸發回調,

watch:{fruit:{// 此時fruite 就是一個配置對象,里面的屬性都是配置選項// handler 就是原來的監聽函數, 當數據變化是執行的函數handler(val,oldval){console.log(val);console.log(oldval);            },// 深度監聽選項deep:true,immediate: true  // 理解執行監聽函數handler}
}

5. 引用類型深度監聽后,屬性變化,獲取新舊值問題

但是細心的朋友就會發現我們在改變對象屬性的時候,雖然觸發了偵聽器,但是我沒發獲取舊值了,我們拿到的兩個形參的值都是對象更改后的新值.

出于某種原因沒有深入過濾對象的每個屬性,那么只能監聽到對象的變化,而JavaScript里對象的賦值是引用賦值,雖然屬性變化了,但是它引用的地址卻一直沒有變化,這樣的話,當對象的屬性值改變了,Vue雖然知道它改變了,但也只能循著引用地址去獲得對象,可此時對象的屬性的值已經改變了,因此Vue并不能得到變異之前的值。

示例:

<div id="app"><!-- 監聽器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"蘋果",price: 20},},watch:{fruit:{handler(val,oldval){console.log(11)console.log(val);console.log(oldval);            },deep:true}},})
</script>

此時當數據發生變化是, 查看handler 兩個參數值

監聽屬性.png


5.1 解決方案: 利用計算屬性

官方方案: 觀察 Vue 實例變化的一個表達式或計算屬性函數。回調函數得到的參數為新值和舊值。表達式只接受監督的鍵路徑。對于更復雜的表達式,用一個函數取代


既然 watch無法在變異對象或數組時監聽新舊值,那么我們可以先使用JSON.parse()來淺復制一遍data對象,然后在復制的對象上修改,完了重新賦值給該data對象,這樣變化前后兩個對象是完全不一樣的,因為它們的引用地址完全不一樣,Vue可以循著兩個引用地址獲得新舊兩個

<div id="app"><!-- 監聽器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"蘋果",price: 20},},watch:{fruitNew:{handler(val,oldval){console.log(11)console.log(val);console.log(oldval);            },deep:true}},computed:{fruitNew(){return JSON.parse(JSON.stringify(this.fruit));}},})
</script>

6. 可以通過Vue是實例對象的$watch屬性來監聽

除了 watch 選項之外,您還可以使用命令式的 vm.$watch ,通過Vue實例對象來監聽數據


6.1 普通監聽

可以通過實例對象調用$watch設置監聽

<!-- 監聽字符變化-->
<div id="app"><!-- 監聽器 --><input type="text" v-model="msg"></div><script>   const vm = new Vue({el: "#app",data: {msg:'你好'}})// $watch 是一個實例方法vm.$watch("msg",(val,newVal) => {console.log(val)console.log(newVal);       })
</script>

6.2 監聽配置

<div id="app"><!-- 監聽器 --><input type="text" v-model.number="fruit.price">
</div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"蘋果",price: 20`在這里插入代碼片`},}})// $watch 是一個實例方法vm.$watch("fruit",(val,newVal) => {console.log(val)console.log(newVal);       },{deep: true})
</script>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/14934.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/14934.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/14934.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

現代C++ 如何使用 Lambda 使代碼更具表現力、更容易理解?

使用 Lambda 使代碼更具表現力 一、Lambda VS. 仿函數二、總結 一、Lambda VS. 仿函數 Lambda 是 C11 中最引人注目的語言特性之一。它是一個強大的工具&#xff0c;但必須正確使用才能使代碼更具表現力&#xff0c;而不是更難理解。 首先&#xff0c;要明確的是&#xff0c;…

向npm發布自己寫的vue組件,使用vite創建項目

向npm發布自己寫的vue組件&#xff0c;使用vite創建項目 創建項目 pnpm create vite輸入項目名稱 由于我的組件是基于 ant-design-vue和vue的&#xff0c;需要解析.vue文件&#xff0c;我又安裝了下面4個。 然后執行 pnpm i安裝依賴 vite.config.ts import { defineC…

防范TOCTOU競態條件攻擊

防范TOCTOU競態條件攻擊 在軟件開發過程中&#xff0c;我們常常會遇到需要在使用資源之前檢查其狀態的情況。然而&#xff0c;如果資源的狀態在檢查和使用之間發生了變化&#xff0c;那么檢查的結果可能會失效&#xff0c;導致軟件在資源處于非正常狀態時執行無效操作。這種時…

[datawhale202405]從零手搓大模型實戰:TinyAgent

結論速遞 TinyAgent項目實現了一個簡單的Agent智能體&#xff0c;主要是實現了ReAct策略&#xff08;推理調用工具的能力&#xff09;&#xff0c;及封裝了一個Tool。 項目實現有一定的疏漏。為了正確運行代碼&#xff0c;本次對代碼Agent部分進行了簡單修改&#xff08;完善…

windows安裝rocketmq

1.下載連接 https://rocketmq.apache.org/download/ 2.解壓到D盤下&#xff08;其他位置也可以&#xff09; 3.配置環境變量 需要有jdk環境 新建ROCKETMQ_HOME&#xff0c;剛剛解壓的位置 編輯Path&#xff0c;新增%ROCKETMQ_HOME%\bin 4.啟動mqnameserver 進入安裝bin目錄下…

ERC314協議

314協議功能詳解 這兩天花時間研究了一下314協議&#xff0c;總體感覺還不錯&#xff0c;有創新。 功能亮點 314協議作為一種創新的代幣標準&#xff0c;致力于降低用戶交易成本與簡化授權流程&#xff0c;通過“轉賬即交易”模式革新傳統Swap體驗。此協議簡化了買賣代幣的過程…

什么是react

React 是一個用于構建用戶界面的 JavaScript 庫&#xff0c;由 Facebook&#xff08;現在的 Meta&#xff09;開發和維護。它首次發布于2013年&#xff0c;并迅速成為最受歡迎的前端庫之一。React 的主要目標是提供一種高效、靈活的方式來構建用戶界面&#xff0c;特別是在大型…

gc和gccgo編譯器

Go 語言有兩個主要的編譯器&#xff0c;分別是 Go 編譯器&#xff08;通常簡稱為 gc&#xff09;和 GCCGO。它們之間有一些重要的異同點&#xff1a; gc 編譯器&#xff1a; gc 是 Go 語言的官方編譯器&#xff0c;由 Go 語言的開發團隊維護。它是 Go 語言最常用的編譯器&#…

PHP代碼審計前期準備

1 php代碼審計的意義 1.1 什么是代碼審計 就是獲取目標的代碼&#xff0c;這個目標可以是一個網站&#xff0c;也可以是一個手機app 1.2 黑盒測試與白盒測試的區別 在代碼審計中黑盒和白盒的主要區別就在于是否可以拿到源代碼&#xff0c;黑盒是拿不到源代碼的&#xff0c;…

交叉編譯——

什么是交叉編譯 交叉編譯 是在一個平臺上生成臨海一個平臺可執行代碼. eg.在windows上面編寫C51代碼&#xff0c;并編譯生成可執行代碼。如xx.hex 我們在Ubuntu上編寫樹莓派的代碼&#xff0c;并編譯成可執行代碼。a.out. 是在樹莓派上運行&#xff0c;不在Ubuntu Linux上面運…

便攜式iv測試儀特點

TH-PV30便攜式IV測試儀是一種用于測量半導體器件電學特性的設備&#xff0c;它具有體積小、重量輕、便于攜帶等特點&#xff0c;廣泛應用于半導體行業、科研實驗室以及教育領域。 該測試儀的工作原理基于四探針法&#xff0c;通過在半導體器件表面放置四個金屬探針&#xff0c…

【vs2022】安裝copilot和reshaper

直接安裝新版vs 17.10 自帶集成的copilot支持安裝resharper 可以跳過市場里的reshper安裝好后依然可以直接使用vs。 resharper 2024.1.2 市場里還是i老版本&#xff1a; copilot 不兼容,這個是之前市場安裝的版本 官方建議用vs intall 安裝 安裝 GitHub Copilot GitHub.Co…

詳解http協議

什么是HTTP協議 定義 Http協議即超文本傳送協議 (HTTP-Hypertext transfer protocol) 。 它定義了瀏覽器&#xff08;即萬維網客戶進程&#xff09;怎樣向萬維網服務器請求萬維網文檔&#xff0c;以及服務器怎樣把文檔傳送給瀏覽器。從層次的角度看&#xff0c;HTTP是面向&am…

第四十一天 | 62.不同路徑 63.不同路徑|| 343.整數拆分 96.不同的二叉搜索樹

題目&#xff1a;62.不同路徑 1.二維dp數組dp[i][j]含義&#xff1a;到達&#xff08;i&#xff0c;j&#xff09;位置有dp[i][j]種方法。 2.動態轉移方程&#xff1a;dp[i][j] dp[i - 1][j] dp[i][j - 1] 3.初始化&#xff1a;dp[0][j] 1, dp[i][0] 1 &#xff08;第一…

Vue3設置緩存:storage.ts

在vue文件使用&#xff1a; import { Local,Session } from //utils/storage; // Local if (!Local.get(字段名)) Local.set(字段名, 字段的值);// Session Session.getToken()storage.ts文件&#xff1a; import Cookies from js-cookie;/*** window.localStorage 瀏覽器永…

uniapp 安卓 Pc端真機瀏覽器調試

下載插件:真機模擬瀏覽器 1. 安裝, 每次啟用時使用usb 線連接電腦, 并且打開手機或者POS (調試設備)開發者模式, 比如我的是pos 機 則在系統設置中找到版本號,點擊多次就會觸發開發者模式 2.打開真機模擬軟件,打開后會打開一個瀏覽器,如果想要模擬google的瀏覽器則 在瀏覽器地…

精準鍵位提示,鍵盤盲打輕松入門

在說明精準鍵位提示之前&#xff0c;我們先來看一張圖&#xff1a; 這是一張標準的基準鍵位圖&#xff0c;也就是打字時我們雙手的8個手指放在基準鍵位上&#xff0c;在打不同的字母時&#xff0c;我們的手指以基準鍵位為中心&#xff0c;或上、或下、或左、或右&#xff0c;在…

202109青少年軟件編程(Python)等級考試試卷(四級)

第 1 題 【單選題】 執行如下 Python 代碼后, 結果是?( ) def inverse(s,n=0): while s:n = n * 10 + s % 10s = s // 10return nprint

《拯救大學生課設不掛科第二期之Windows11下安裝VC6.0(VC++6.0)與跑通Hello,World!程序教程》【官方筆記】

背景與目標人群&#xff1a; 大學第一次學C語言的時候&#xff0c;大部分老師會選擇VC6這個編輯器。 但由于很多人是新手&#xff0c;第一次上大學學C語言。 老師要求VC6.0&#xff08;VC6.0&#xff09;寫C語言跑程序可能很多人還是第一次接觸電腦。 需要安裝VC6這個編輯器…

Docker常用軟件安裝

文章目錄 1.安裝Tomcat1.docker hub查找鏡像并復制拉取鏡像命令2.拉取鏡像到本地1.執行官網命令2.查看是否拉取成功 3.啟動tomcat4.退出和重啟1.由于是以交互方式啟動的&#xff0c;所以不方便&#xff0c;直接ctrl c退出2.查看當前的容器3.使用docker start 命令啟動容器&…