vue3.0 Reactive數(shù)據(jù)更新頁(yè)面沒有刷新的問(wèn)題
vue3.0 Reactive數(shù)據(jù)更新頁(yè)面沒有刷新
vue 3.0 ref 和 Reactive 數(shù)據(jù)響應(yīng)式,以及使用 Reactive 數(shù)據(jù)已更新但頁(yè)面沒有同步刷新異常
Vue 3.0 中我們使用 reactive() 定義的響應(yīng)式數(shù)據(jù)的時(shí)候,當(dāng)我們對(duì)象再次賦值,我們發(fā)現(xiàn)數(shù)據(jù)已經(jīng)修改成功,但是頁(yè)?并沒有自動(dòng)渲染成最新的數(shù)據(jù);
這時(shí)我們可以改成 ref () 或者對(duì) reactive() 綁定的數(shù)據(jù)類型下點(diǎn)功夫;
- ref()
ref() 接受一個(gè)內(nèi)部值并返回一個(gè)響應(yīng)式且可變的 ref 對(duì)象。ref 對(duì)象僅有一個(gè) .value property,指向該內(nèi)部值
<template> ? <div> ? ? <button @click="changeMsg">更改數(shù)據(jù)</button> ? ? <div>{{ message }}</div> ? </div> </template> <script setup lang="ts"> import {ref} from 'vue' /** ?* ? ref() 基礎(chǔ)用法 ?*/ ? let message = ref<string | number>("測(cè)試數(shù)據(jù)") /** ?* ? 更改 ref 數(shù)據(jù) ?*/ ?? const changeMsg = () => { ? ?message.value = "更改測(cè)試數(shù)據(jù)" } </script>
- reactive()
reactive() 主要時(shí)用來(lái)綁定一些復(fù)雜的數(shù)據(jù)類型,比如(對(duì)象、數(shù)組) ;它不可以綁定普通的數(shù)據(jù)類型,否則會(huì)報(bào)錯(cuò);如果我們需要綁定普通的數(shù)據(jù)類型,建議使用上面的 ref()
<template> ? <div> ? ? <button @click="changeObj">更改數(shù)據(jù)</button> ? ? <div> {{obj.data}} </div> ? ? <div> {{obj.dataBoolean}} </div> ? ? <div> {{obj.dataArr}} </div> ? </div> </template> <script setup lang="ts"> import {reactive} from 'vue' /** ?* ? reactive() 基礎(chǔ)用法 ?*/ ? const obj = reactive({ ? ? data: '', ? ? dataBoolean: false, ? ? dataArr: <number[]>[], }) /** ?* ? 更改 reactive() 數(shù)據(jù) ?*/ ?const changeObj = () => { ? ? ?obj .data = '測(cè)試數(shù)據(jù)' ? ? ?obj .dataBoolean = true ? ? ?obj .dataArr = [1, 2, 3, 4, 5, 6] ?} </script>
vue3.0中的reactive用法
reactive 是 Vue3 中提供的實(shí)現(xiàn)響應(yīng)式數(shù)據(jù)的方法。
在 Vue2 中響應(yīng)式數(shù)據(jù)是通過(guò) defineProperty 來(lái)實(shí)現(xiàn)的,
在 Vue3 中響應(yīng)式數(shù)據(jù)是通過(guò) ES6 的 Proxy來(lái)實(shí)現(xiàn)的。
reactive 參數(shù)必須是對(duì)象 (json / arr)
如果給 reactive 傳遞了其它對(duì)象
- 默認(rèn)情況下,修改對(duì)象無(wú)法實(shí)現(xiàn)界面的數(shù)據(jù)綁定更新。
- 如果需要更新,需要進(jìn)行重新賦值。(即不允許直接操作數(shù)據(jù),需要放個(gè)新的數(shù)據(jù)來(lái)替代原數(shù)據(jù))
在 reactive 使用基本類型參數(shù)
基本類型(數(shù)字、字符串、布爾值)在 reactive 中無(wú)法被創(chuàng)建成 proxy 對(duì)象,也就無(wú)法實(shí)現(xiàn)監(jiān)聽。
<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ā)生了變化,只不過(guò)這種變化并沒有反饋到界面上,也就是說(shuō)并沒有實(shí)現(xiàn)雙向數(shù)據(jù)綁定。當(dāng)然,如果是 ref
的話,就不存在這樣的問(wèn)題。而如果要使用 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ì)象,他通過(guò)劫持對(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ù)在 reactive
使用 Date
參數(shù)
如果參數(shù)不是數(shù)組、對(duì)象,而是稍微奇怪一點(diǎn)的數(shù)據(jù)類型,例如說(shuō) Date
,那么麻煩又來(lái)了。
<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è)特殊處理就是重新賦值(,而不是直接修改原來(lái)的值)。
<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)。
響應(yīng)式代理 vs. 原始對(duì)象
值得注意的是,reactive()
返回的是一個(gè)源對(duì)象的 Proxy,它和源對(duì)象是不相等的:
const raw = {} const proxy = reactive(raw) // 代理和原始對(duì)象不是全等的 console.log(proxy === raw) // false
只有代理是響應(yīng)式的,更改原始的對(duì)象不會(huì)觸發(fā)更新。因此,使用 Vue 的響應(yīng)式系統(tǒng)的最佳實(shí)踐是 僅使用代理作為狀態(tài)。
為保證訪問(wèn)代理的一致性,對(duì)同一個(gè)對(duì)象調(diào)用 reactive()
會(huì)總是返回同樣的代理,而對(duì)代理調(diào)用 reactive()
則會(huì)返回它自己:
// 在同一個(gè)對(duì)象上調(diào)用 reactive() 會(huì)返回相同的代理 console.log(reactive(raw) === proxy) // true // 在一個(gè)代理上調(diào)用 reactive() 會(huì)返回它自己 console.log(reactive(proxy) === proxy) // true
這個(gè)規(guī)則對(duì)深層級(jí)的對(duì)象也適用。依靠深層響應(yīng)性,響應(yīng)式對(duì)象內(nèi)的深層級(jí)對(duì)象依然是代理:
const proxy = reactive({}) const raw = {} proxy.nested = raw console.log(proxy.nested === raw) // false
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
npm install報(bào)錯(cuò)缺少python問(wèn)題及解決
這篇文章主要介紹了npm install報(bào)錯(cuò)缺少python問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06vue通過(guò)路由實(shí)現(xiàn)頁(yè)面刷新的方法
本篇文章主要介紹了vue通過(guò)路由實(shí)現(xiàn)頁(yè)面刷新的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01vue 彈出框 引入另一個(gè)vue頁(yè)面的示例代碼
這篇文章主要介紹了vue 彈出框引入另一個(gè)vue頁(yè)面,這種方式適用于在一個(gè)頁(yè)面邏輯比較多的時(shí)候,可以搞多個(gè)頁(yè)面,防止出錯(cuò),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08vue在html標(biāo)簽{{}}中調(diào)用函數(shù)的方法總結(jié)及對(duì)比
這篇文章主要給大家介紹了關(guān)于vue在html標(biāo)簽{{}}中調(diào)用函數(shù)的方法總結(jié)及對(duì)比,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-03-03antd form表單使用setFildesValue 賦值失效的解決
這篇文章主要介紹了antd form表單使用setFildesValue 賦值失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2023-04-04vue中{__ob__: observer}對(duì)象轉(zhuǎn)化為數(shù)組進(jìn)行遍歷方式
這篇文章主要介紹了vue中{__ob__: observer}對(duì)象轉(zhuǎn)化為數(shù)組進(jìn)行遍歷方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue3安裝vant實(shí)現(xiàn)按需引入和全局引入
本文主要介紹了vue3安裝vant實(shí)現(xiàn)按需引入和全局引入,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04