iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0

前言

本章節針對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};
    }
}

原數據:
https://ithelp.ithome.com.tw/upload/images/20230912/2016019323HqmBo06T.png

一般而言 Vue中的數據若有兩層以上並有陣列的情況, 資料的異動有幾點注意事項

  • 方法 updateData()

更新後:
https://ithelp.ithome.com.tw/upload/images/20230912/20160193fNtv1RxBEb.png

第一種方式可以達到數據更新的效果
第一筆資料已從狗變成了兔子

  • 方法 updateData2()

更新後:
https://ithelp.ithome.com.tw/upload/images/20230912/20160193mMhkfKVTJy.png

第二種方式卻沒有達成效果
兔子依然沒有變成熊貓
這是為什麼呢?


https://ithelp.ithome.com.tw/upload/images/20230912/20160193TZSBhN2Lpp.png

從控制台中觀察Vue實例
可以發現animel對象是有配置get(),set()
為標準Vue對data的配置

https://ithelp.ithome.com.tw/upload/images/20230912/20160193eFcDTGythk.png

打開animel對象可以發現其prototype為一般Array陣列的配置
並且第一筆數據其實也改成了熊貓

https://ithelp.ithome.com.tw/upload/images/20230912/20160193ynD1xCMF57.png

其他未異動的數據內部各個對象都有配置get(),set()函數
然而...

https://ithelp.ithome.com.tw/upload/images/20230912/20160193Eixcdk1mdw.png

雖然第一筆數據其實已經變成了熊貓
當按下dataUpdate2()時, 資料實際上受到了異動
但事實上animel[0]這個數據
沒有配置上Vue的get(),set()方法了
結果倒是資料脫離數據代理

自然而然就脫離了Vue的掌控
Vue也沒有偵測到數據的變化,也沒有重新編譯

整理

使用 Array()的時候要注意
在使用 vue裡面的數據時要遵守其數據代理的規則
針對 vue.data中有搭配 get(), set()做調整
若對沒有配置 vue給予的函數的數據調整容易造成數據遺失
在第二種方式更新數據時,其並非調用set()
而是直接對陣列內部元素操作,並替換之

Vue-Array()

那對於Vue而言Array()的函數為window中的函數
為了讓Array()也能在Vue實例中做操作
Vue對Array()做了不分方法的覆寫
這是為了讓 Vue搭配數據代理 → Vue覆寫了原生 List對數據操作的函數方法
所以在對 List操作數據的時候可以針對這些方法運用
但要注意使用的這些方法並不是原生 List的函示, 而是 Vue所配置的

  • Array()原生方法
    https://ithelp.ithome.com.tw/upload/images/20230912/20160193lWvzCSje7F.png

  • Vue_Array()方法
    https://ithelp.ithome.com.tw/upload/images/20230912/20160193WimMVWSSD9.png

  • Vue官網對Array()的操作
    https://ithelp.ithome.com.tw/upload/images/20230912/20160193RPnlviSc7c.png


以上即是對Vue對Array的操作
圖片有點多請見諒,希望可以幫助想多了解Vue的人


上一篇
2023鐵人賽_Vue2基本使用規則(Day11)-列表渲染KEY的作用
下一篇
2023鐵人賽_Vue2基本使用規則(Day13)-SET函數
系列文
Vue2 初步認識以及基本使用規則 && 了解 Vue2 的基本原理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言