本章節針對Vue在更新List數據時的一些小細節做補充
在watch中有提及,在做數據監測的時候必須用深度監視才能監測到List內的數據變化
對於Vue中,偵測到數據的異動,都會對DOM做一次編譯再將畫面呈現出來
但若對List內部的數據直接更改Vue是偵測不到的
一上一章節動物的列表沿用做範例
程式碼
<body>
<div id="root" class="m-2">
<h2>動物列表</h2>
<div>
<label>查詢 : </label>
<div class="input-group">
<input type="text" class="form-control" v-model="keyword" />
<input type="button" class="btn btn-primary" @click="sortTpe = 1" value="升序" />
<input type="button" class="btn btn-danger" @click="sortTpe = 2" value="降序" />
<input type="button" class="btn btn-primary" @click="sortTpe = 0" value="原順序" />
</div>
</div>
<ul>
<li v-for="(animel, index) of animelFilter" :key="animel.id">
{{index + 1}}.</br>
英文名:{{animel.name}}</br>
中文名:{{animel.cname}}</br>
年紀:{{animel.age}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el : "#root",
data : {
keyword : "",
sortTpe : 0,
animel : [
{id : "001" , name : "dog", cname : "狗", age : 3 },
{id : "002" , name : "cat", cname : "貓", age : 5 },
{id : "003" , name : "bird", cname : "鳥", age : 1},
{id : "004" , name : "lion", cname : "獅子", age : 8}
]
},
computed : {
animelFilter() {
var arr = this.animel.filter((a)=>{
return a.name.indexOf(this.keyword) !== -1
})
if (this.sortTpe != 0) {
arr.sort((val, val2)=>{
return this.sortTpe === 1 ?
val.age-val2.age : val2.age-val.age
})
}
return arr;
}
}
})
</script>
</body>
在Vue的配置中添加methods的配置
methods : {
updateData() {
this.animel[0].age = 7;
this.animel[0].cname = 'rabbit';
this.animel[0].name = '兔子';
},
updateData2() {
this.animel[0] = {id : "001", name : "panda", cname : "熊貓", age : 15};
}
}
原數據:
一般而言 Vue中的數據若有兩層以上並有陣列的情況, 資料的異動有幾點注意事項
更新後:
第一種方式可以達到數據更新的效果
第一筆資料已從狗變成了兔子
更新後:
第二種方式卻沒有達成效果
兔子依然沒有變成熊貓
這是為什麼呢?
從控制台中觀察Vue實例
可以發現animel對象是有配置get(),set()
為標準Vue對data的配置
打開animel對象可以發現其prototype為一般Array陣列的配置
並且第一筆數據其實也改成了熊貓
其他未異動的數據內部各個對象都有配置get(),set()函數
然而...
雖然第一筆數據其實已經變成了熊貓
當按下dataUpdate2()時, 資料實際上受到了異動
但事實上animel[0]這個數據
沒有配置上Vue的get(),set()方法了
結果倒是資料脫離數據代理
自然而然就脫離了Vue的掌控
Vue也沒有偵測到數據的變化,也沒有重新編譯
使用 Array()的時候要注意
在使用 vue裡面的數據時要遵守其數據代理的規則
針對 vue.data中有搭配 get(), set()做調整
若對沒有配置 vue給予的函數的數據調整容易造成數據遺失
在第二種方式更新數據時,其並非調用set()
而是直接對陣列內部元素操作,並替換之
那對於Vue而言Array()的函數為window中的函數
為了讓Array()也能在Vue實例中做操作
Vue對Array()做了不分方法的覆寫
這是為了讓 Vue搭配數據代理 → Vue覆寫了原生 List對數據操作的函數方法
所以在對 List操作數據的時候可以針對這些方法運用
但要注意使用的這些方法並不是原生 List的函示, 而是 Vue所配置的
Array()原生方法
Vue_Array()方法
Vue官網對Array()的操作
以上即是對Vue對Array的操作
圖片有點多請見諒,希望可以幫助想多了解Vue的人