Vue【數據】數組操作


  例 子  

  定義數據結構,通過函數 data 返回數組 classmates,假設 classmates 數組中的每一個元素是班上的每一個同學的信息,然后通過 v-for 將每個同學的信息在頁面上輸出,p 是當前值,index 是當前索引。

<template>
    <div class="hello">
        <div v-for="(p, index) in classmates" :key="p.id">
            {{ `${index}.${p.name}` }}
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return{
            classmates: [
                {id: 1, name: "許一"},
                {id: 2, name: "許二"},
                {id: 3, name: "許三"},
            ]
        };
    }
}
</script>
View Code

 

假如班上有一個同學轉學了,同時,班上來了一個新同學。現在要修改代碼。

下面是一個錯誤示范。圈起代碼為新增代碼。

假如許二轉學走了,張三轉學來了。嘗試新增一個按鈕,點擊按鈕之后調用 change 方法,更this.classmates[1] 。預想的頁面效果是,點擊按鈕之后,“許二” 變為 “張三”。

<template>
    <div class="hello">
        <button @click="change">change</button>
        <div v-for="(p, index) in classmates" :key="p.id">
            {{ `${index}.${p.name}` }}
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return{
            classmates: [
                {id: 1, name: "許一"},
                {id: 2, name: "許二"},
                {id: 3, name: "許三"},
            ]
        };
    },
    methods: {
        change(){
            this.classmates[1] = {id: 2, name: "張三"};
        }
    }
}
</script>
View Code

  上面修改數據失敗的原因是,Vue 里的響應式依賴在 Vue2.0 版本里是通過 Object.defineProperty 實現的。在 Vue2.0 中,當我們把一個普通的 JavaScript 對象傳入 Vue 實例作為 data 選項,Vue 將遍歷此對象所有的 property,並使用 Object.defineProperty 把這些 property 全部轉為 getter/setter。getter/setter 對用戶是不可見的,但是在內部它們會讓 Vue 能夠追蹤依賴,在屬性變化和修改時進行通知,這也導致了 Vue 在操作時的一些局限性

( Vue 官網上的“ 如何追蹤變化 ”部分 : https://cn.vuejs.org/v2/guide/reactivity.html#%E5%A6%82%E4%BD%95%E8%BF%BD%E8%B8%AA%E5%8F%98%E5%8C%96 )

局限性:

1. 不能檢測對象屬性的添加刪除。對於已經創建的實例,Vue 不允許動態添加根級別的響應式 property。

2. 不能檢測到數組長度變化(通過改變 length 而增加地長度不能監測到)。

3. 不是因為 defineProperty 的局限性,而是出於性能考量的,不會對每個元素都監聽。因為對每個元素進行依賴跟蹤都是有內存消耗和性能開銷的,如果說數組是作為一個列表的遍歷來使用的話,或者說數組是一個海量的數據的話,就會耗盡資源,會降低實用性,所以不會對每個元素都監聽。在 Vue3 里使用 Proxy 來追蹤依賴情況又會不同。

 

  數組操作 

Q: 如何操作數組中響應式的數據 ?

A: Vue 提供了 Vue.set 方法,向嵌套對象去添加響應式數據,還可以通過 this.$set 實例方法去添加屬性,這是 Vue.set 全局方法的別名。刪除的解決方案是通過 Vue.delete 或者實例上的 this.$delete 進行刪除。

 

  例子  

實現點擊 “ 添加新同學 ”按鈕之后,頁面上出現新同學的序號姓名。

<template>
    <div class="hello">
        <button @click="addClassmate">增加新同學</button>
        <div v-for="(p, index) in classmates" :key="p.id">
            {{ `${index}.${p.name}` }}
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return{
            classmates: [
                {id: 1, name: "許一"},
                {id: 2, name: "許二"},
                {id: 3, name: "許三"},
            ]
        };
    },
    methods: {
        addClassmate(){
            this.$set(this.classmates, 3, 
                {id: 4, name: "張三"}
            )
        }
    }
}
</script>
View Code

通過 push 方法也能實現同樣的頁面效果。

<template>
    <div class="hello">
        <button @click="addClassmate">增加新同學</button>
        <div v-for="(p, index) in classmates" :key="p.id">
            {{ `${index}.${p.name}` }}
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return{
            classmates: [
                {id: 1, name: "許一"},
                {id: 2, name: "許二"},
                {id: 3, name: "許三"},
            ]
        };
    },
    methods: {
        addClassmate(){
            this.classmates.push(
                {id: 4, name: "張三"}
            );
        }
    }
}
</script>
View Code

通過 push 方法也能實現同樣的頁面效果。因為在 Vue2.0 里對一些數組操作的方法進行了代理包裝,在包裝的實現里面把這些函數加入了響應式跟蹤依賴,使用這些函數修改數據時會發生視圖更新。

進行了代理包裝處理的函數:push()、pop()、shift()、unshift()、splice()、sort()、reverse()

 

Prop&Data的筆記: https://www.cnblogs.com/xiaoxuStudy/p/12880361.html

計算屬性和偵聽器的筆記:https://www.cnblogs.com/xiaoxuStudy/p/13230664.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM