1,問題
在Vue 3.0 中我們使用 reactive()
定義的響應(yīng)式數(shù)據(jù)的時(shí)候,當(dāng)是一個(gè)數(shù)組或?qū)ο髸r(shí),我們直接進(jìn)行賦值,發(fā)現(xiàn)數(shù)據(jù)已經(jīng)修改成功,但是頁?并沒有自動(dòng)渲染成最新的數(shù)據(jù);這是為什么呢?
就如同官網(wǎng)所說的reactive存在一些局限性
:(官方的描述)
2,原因
原因就是reactive函數(shù)會(huì)返回一個(gè)Proxy
包裝的對(duì)象,所以當(dāng)我們這樣直接賦值時(shí):(看下面例子)
import { reactive } from "vue";
let userInfo = reactive([{name:'Eula'}])
console.log(userInfo) // Proxy(Array) 打印出來是一個(gè)Proxy對(duì)象 當(dāng)然具備響應(yīng)式
// 直接后端數(shù)據(jù)進(jìn)行賦值
userInfo = [{name:'優(yōu)菈'}]
console.log(userInfo) // [{name:'優(yōu)菈'}] 可以看出 就是打印出了一個(gè)普通的數(shù)組 所以不具備響應(yīng)式
這樣賦值的話,就會(huì)把Proxy對(duì)象給覆蓋掉,從而無法觸發(fā)對(duì)應(yīng)的set和get,最終就會(huì)導(dǎo)致丟失掉響應(yīng)性了;
上面的代碼 reactive([{name:'Eula'}])
創(chuàng)建了一個(gè)響應(yīng)式數(shù)組,返回一個(gè)Proxy包裝的對(duì)象由userInfo
變量進(jìn)行存放,但是后面我又把一個(gè)普通的數(shù)組(也就是后端返回的數(shù)據(jù))賦值給userInfo
,注意這時(shí)userInfo
這個(gè)變量存放的已經(jīng)是一個(gè)普通的數(shù)組了,當(dāng)然也就不具備響應(yīng)式了;
所以:對(duì)于reactive
創(chuàng)建的響應(yīng)式數(shù)據(jù)應(yīng)該避免直接使用=
號(hào)進(jìn)行賦值;會(huì)覆蓋響應(yīng)式;
3,解決方案
一、再封裝一層數(shù)據(jù),即定義屬性名,在后期賦值的時(shí)候,對(duì)此屬性進(jìn)行直接賦值
再封裝一層數(shù)據(jù),注意myRenderList
這個(gè)屬性就是新增的屬性用來存放列表數(shù)據(jù),就是比較麻煩了一些。
<script setup>
import { reactive, ref } from "vue";
// 定義響應(yīng)式
let list1 = reactive({myRenderList:[]});
// 請(qǐng)求的數(shù)據(jù)
let newList1 = [
{ name: "Eula", age: "18", isActive: false },
{ name: "Umbra", age: "17", isActive: false },
]
// 更改數(shù)據(jù)
const setList1 = () => {
list1.myRenderList = newList1
}
</script>
三、使用數(shù)組的splice來直接更改原數(shù)組
還是用reactive
來定義響應(yīng)式數(shù)據(jù),只不過改數(shù)據(jù)的方式變了,使用數(shù)組的原生方法splice()
來更改原數(shù)組,不是直接覆蓋所以并不會(huì)影響響應(yīng)式;
splice
有三個(gè)參數(shù)時(shí),可以對(duì)數(shù)組進(jìn)行修改, 第一項(xiàng)是起始索引, 第二項(xiàng)是長度, 第三項(xiàng)是新插入的元素,可以有多個(gè);
下面的代碼是把之前數(shù)組的每一項(xiàng)刪除掉,然后插入新的數(shù)據(jù)newList1
,使用...
擴(kuò)展符進(jìn)行展開每一項(xiàng);
list1.splice(0,list1.length,...newList1)
當(dāng)然,push()
方法也是可以觸發(fā)響應(yīng)式的,只不過只能在后面新增數(shù)據(jù)。還有pop,shift,unshift等方法(用的不多)
<script setup>
import { reactive, ref } from "vue";
// 定義響應(yīng)式
let list1 = reactive([]);
// 請(qǐng)求的數(shù)據(jù)
let newList1 = [
{ name: "Eula", age: "18", isActive: false },
{ name: "Umbra", age: "17", isActive: false },
]
// 更改數(shù)據(jù)
const setList1 = () => {
// splice三個(gè)參數(shù)時(shí) 第一項(xiàng)是起始索引 第二項(xiàng)是長度 第三項(xiàng)是新插入的元素,可以有多個(gè)
list1.splice(0,list1.length,...newList1)
}
</script>
三、使用 ref 來定義數(shù)據(jù)
復(fù)雜數(shù)據(jù)類型也可以使用ref
進(jìn)行定義,而且數(shù)據(jù)都是響應(yīng)式的;原理就有點(diǎn)像第一種方式,重新包裝了一層value;每次使用的時(shí)候都要寫.value
;文章來源:http://www.zghlxwxcb.cn/news/detail-638012.html
ref實(shí)際就是對(duì)一個(gè)普通值做了一層包裝,包裝成一個(gè)對(duì)象,并通過其get和set實(shí)現(xiàn)依賴收集和更新,其實(shí)現(xiàn)原理類似于computed;文章來源地址http://www.zghlxwxcb.cn/news/detail-638012.html
<script setup>
import { reactive, ref } from "vue";
// 定義響應(yīng)式
let list1 = ref([]);
// 請(qǐng)求的數(shù)據(jù)
let newList1 = [
{ name: "Eula", age: "18", isActive: false },
{ name: "Umbra", age: "17", isActive: false },
]
// 更改數(shù)據(jù)
const setList1 = () => {
list1.value = newList1;
}
</script>
到了這里,關(guān)于vue3 - 使用reactive定義響應(yīng)式數(shù)據(jù)進(jìn)行列表賦值時(shí),視圖沒有更新的解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!