Vue3初探之ref、reactive以及改變數(shù)組的值
概況
Vue3 里要實(shí)現(xiàn)數(shù)據(jù)的響應(yīng)式監(jiān)聽一共有兩種方式既:ref 和 reactive
他們既有區(qū)別又有聯(lián)系。
ref()
ref數(shù)據(jù)響應(yīng)式監(jiān)聽。ref 函數(shù)傳入一個(gè)值作為參數(shù),一般傳入基本數(shù)據(jù)類型,返回一個(gè)基于該值的響應(yīng)式Ref對(duì)象,該對(duì)象中的值一旦被改變和訪問,都會(huì)被跟蹤到,就像我們改寫后的示例代碼一樣,通過修改 count.value 的值,可以觸發(fā)模板的重新渲染,顯示最新的值
reactive()
reactive
reactive 是 Vue3 中提供的實(shí)現(xiàn)響應(yīng)式數(shù)據(jù)的?法。
在 Vue2 中響應(yīng)式數(shù)據(jù)是通過 defineProperty 來實(shí)現(xiàn)的,在 Vue3 中響應(yīng)式數(shù)據(jù)是通過 ES6 的 Proxy 來實(shí)現(xiàn)的。具體參照,。
reactive 參數(shù)必須是對(duì)象 (json / arr)
本質(zhì): 就是將傳?的數(shù)據(jù)包裝成?個(gè)Proxy對(duì)象
如果給 reactive 傳遞了其它對(duì)象(如Date對(duì)象)
默認(rèn)情況下,修改對(duì)象?法實(shí)現(xiàn)界?的數(shù)據(jù)綁定更新。
如果需要更新,需要進(jìn)?重新賦值。(即不允許直接操作數(shù)據(jù),需要放個(gè)新的數(shù)據(jù)來替代原數(shù)據(jù))
在 reactive 使?基本類型參數(shù)
基本類型(數(shù)字、字符串、布爾值)在 reactive 中?法被創(chuàng)建成 proxy 對(duì)象,也就?法實(shí)現(xiàn)監(jiān)聽。?法實(shí)現(xiàn)響應(yīng)式
<template> <div> <p>{{msg}}</p> <button @click="c">button</button> </div> </template> <script> import { reactive } from 'vue' export default { name: 'App', setup() { let msg = reactive(0) function c() { console.log(msg); msg ++; } return { msg, c }; } } </script>
點(diǎn)擊 button ,我們期望的結(jié)果是數(shù)字從 0 變成 1,然?實(shí)際上界?上的數(shù)字并沒有發(fā)?任何改變。
查看控制臺(tái),它的輸出是這樣的(我點(diǎn)了 3 次)
出現(xiàn)提?
value cannot be made reactive: 0
?輸出的值確實(shí)發(fā)?了變化,只不過這種變化并沒有反饋到界?上,也就是說并沒有實(shí)現(xiàn)雙向數(shù)據(jù)綁定。當(dāng)然,如果是 ref 的話,就不存在
這樣的問題。?如果要使? reactive ,我們需要將參數(shù)從 基本類型 轉(zhuǎn)化為 對(duì)象。
<template> <div> <p>{{msg.num}}</p> <button @click="c">button</button> </div> </template> <script> import { reactive } from 'vue' export default { name: 'App', setup() { let msg = reactive({ num: 0 }) function c() { console.log(msg); msg.num ++; } return { msg, c }; } } </script>
將參數(shù)替換成了對(duì)象 {num: 0},此時(shí),點(diǎn)擊按鈕界?就會(huì)產(chǎn)?改變(我點(diǎn)了 3 次)。
在控制臺(tái)打印消息
可以看到,msg 成功被創(chuàng)建成了 proxy 對(duì)象,他通過劫持對(duì)象的 get 和 set ?法實(shí)現(xiàn)了對(duì)象的雙向數(shù)據(jù)綁定。
深層的、對(duì)象內(nèi)部的變化也能被察覺到(注意下?代碼中的 inner )
<template> <div> <p>{{msg.num.inner}}</p> <button @click="c">button</button> </div> </template> <script> import { reactive } from 'vue' export default { name: 'App', setup() { let msg = reactive({ num: { inner: 0 } }) function c() { console.log(msg); msg.num.inner ++; } return { msg, c }; } } </script>
數(shù)組變化也不在話下。
<template> <div> <p>{{msg}}</p> <button @click="c">button</button> </div> </template> <script> import { reactive } from 'vue' export default { name: 'App', setup() { let msg = reactive([1, 2, 3]) function c() { console.log(msg); msg[0] += 1; msg[1] = 5; } return { msg, c }; } } </script>
在 reactive 使? Date 參數(shù)
如果參數(shù)不是數(shù)組、對(duì)象,?是稍微奇怪?點(diǎn)的數(shù)據(jù)類型,例如說 Date ,那么?煩?來了。
<template> <div> <p>{{msg}}</p> <button @click="c">button</button> </div> </template> <script> import { reactive } from 'vue' export default { name: 'App', setup() { let msg = reactive(new Date()) function c() { console.log(msg); msg.setDate(msg.getDate() + 1); console.log(msg); } return { msg, c }; } } </script>
這?我先打印了 msg 兩次,可以看到,點(diǎn)擊?次 button ,msg 的數(shù)據(jù)是存在變化的,但界?并未發(fā)?變化,同時(shí)我們發(fā)現(xiàn)在控制臺(tái)
?,msg 并未被識(shí)別成 proxy。
就算我們把 Date 放在對(duì)象?,就像這樣
<template> <div> <p>{{msg.date}}</p> <button @click="c">button</button> </div> </template> <script> import { reactive } from 'vue' export default { name: 'App', setup() { let msg = reactive({ date: new Date() }); function c() { console.log(msg); msg.date.setDate(msg.date.getDate() + 1); console.log(msg); } return { msg, c }; } } </script>
也仍然不起效果。
顯然,對(duì)于這種數(shù)據(jù)類型,我們需要做特殊處理。
這個(gè)特殊處理就是重新賦值(,?不是直接修改原來的值)。
<template> <div> <p>{{msg.date}}</p> <button @click="c">button</button> </div> </template> <script> import { reactive } from 'vue' export default { name: 'App', setup() { let msg = reactive({ date: new Date() }); function c() { console.log(msg); msg.date.setDate((msg.date.getDate() + 1)); msg.date = new Date(msg.date); console.log(msg); } return { msg, c }; } } </script>
這?我采?了拷貝的?案重新賦值了 msg.date,界?成功發(fā)?了變化(?期 + 1)。
vue3中改變數(shù)組的值
let arr = reactive([{id:1},{id:2}])
不可行:arr=[], arr = reactive([])
可行:arr.splice(0,arr.length)
arr.length = 0
原因:前者創(chuàng)建了新對(duì)象,頁(yè)面渲染的原對(duì)象還是沒有改變;后者改變的是原頁(yè)面對(duì)象
總結(jié)
到此這篇關(guān)于Vue3初探之ref、reactive以及改變數(shù)組值的文章就介紹到這了,更多相關(guān)Vue3 ref reactive及改變數(shù)組值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vite+vue3項(xiàng)目解決低版本兼容性問題解決方案(Safari白屏)
這篇文章主要介紹了vite+vue3項(xiàng)目解決低版本兼容性問題(Safari白屏),使用官方插件 @vitejs/plugin-legacy 為打包后的文件提供傳統(tǒng)瀏覽器兼容性支持,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03前端Vue手機(jī)號(hào)校驗(yàn)以及后端Java手機(jī)號(hào)校驗(yàn)例子
接收一個(gè)輸入的手機(jī)號(hào),判斷輸入的手機(jī)號(hào)是否正確是一個(gè)很常見的功能,這篇文章主要給大家介紹了關(guān)于前端Vue手機(jī)號(hào)校驗(yàn)以及后端Java手機(jī)號(hào)校驗(yàn)的相關(guān)資料,需要的朋友可以參考下2023-11-11解決VUE-Router 同一頁(yè)面第二次進(jìn)入不刷新的問題
這篇文章主要介紹了解決VUE-Router 同一頁(yè)面第二次進(jìn)入不刷新的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07cesium開發(fā)之如何在vue項(xiàng)目中使用cesium,使用離線地圖資源
這篇文章主要介紹了cesium開發(fā)之如何在vue項(xiàng)目中使用cesium,使用離線地圖資源問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Vue3項(xiàng)目打包后部署到服務(wù)器 請(qǐng)求不到后臺(tái)接口解決方法
在本篇文章里小編給大家整理了關(guān)于Vue3項(xiàng)目打包后部署到服務(wù)器 請(qǐng)求不到后臺(tái)接口解決方法,有需要的朋友們可以參考下。2020-02-02vue 點(diǎn)擊展開顯示更多(點(diǎn)擊收起部分隱藏)
這篇文章主要介紹了vue 點(diǎn)擊展開顯示更多(點(diǎn)擊收起部分隱藏),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04