Vue動態添加屬性到data的實現

一、場景例子

<body>
    <div id="app">
        <p v-for="(value,key) in item" :key="key">
            {{value}}
        </p>
        <button @click="addProperty">動態添加新屬性</button>
    </div>
</body>
</html>
<script>
    new Vue({
        el:'#app',
        data:{
            item:{
                oldProperty:"舊屬性"
            }
        },
        methods: {
            addProperty(){
                this.item.newProperty = "新屬性";
                console.log(this.item);
            }
        },
    })
</script>

效果:點擊按鈕後,輸出的結果中有新添加的新屬性,但是頁面沒有顯示新屬性。

二、原理分析

vue2使用Object.defineProperty實現數據響應式;

const obj = {}
Object.defineProperty(obj, 'foo', {
        get() {
            console.log(`get foo:${val}`);
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                console.log(`set foo:${newVal}`);
                val = newVal
            }
        }
    })
}
  • 當訪問foo屬性,或者設置foo值的時候都能觸發setter與getter;
  • 但是為obj添加新屬性的時候,卻無法觸發事件屬性的攔截
bj.bar = '新屬性'

原因是一開始obj的foo屬性被設成瞭響應式數據,而bar是後面新增的屬性,並沒有通過Object.defineProperty設置成響應式數據

三、解決方案

有三種解決方案:

  • Vue.set()
  • Object.assign()
  • $forcecUpdated()

常用的就是Vue.set(),語法為:Vue.set( target, propertyName/index, value )

<script>
    new Vue({
        el:'#app',
        data:{
            item:{
                oldProperty:"舊屬性"
            }
        },
        methods: {
            addProperty(){
                Vue.set(this.item,"newProperty","新屬性")
                console.log(this.item);
            }
        },
    })
</script>

到此這篇關於Vue動態添加屬性到data的實現的文章就介紹到這瞭,更多相關Vue動態添加屬性內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: