簡體   English   中英

如何讓 Vue.js 對動態添加的數組屬性的更改做出反應?

[英]How can I get Vue.js to be reactive for changes to dynamically added array properties?

在 Vue.js 中,我有一個帶有動態添加/編輯屬性的數據對象,這些屬性本身就是數組。 例如,屬性開始如下:

data: function () {
    return {
        vals: {}
    };
}

隨着時間的推移,通過各種按鈕點擊等, vals可能如下所示(實際的屬性名稱和值是 100% 動態的,基於多種因素):

vals: {
    set1: [
        {
            prop1: 123,
            prop2: 'hello'
        },
        {
            prop1: 456,
            prop2: 'bye'
        }
    ],
    set2: [
        {
            prop3: 'Why?!',
            prop4: false
        }
    ]
}

隨着數組屬性(即set1set2 )的更改,我希望能夠對這些更改做出反應。

例如,我可能會在我的代碼中執行以下操作:

var prop = 'set1';

this.vals[prop].push({
    {
        prop1: 789,
        prop2: 'hmmm...'
    }
});

但是,當我這樣做時,組件並沒有更新(我推測是因為我將一個對象推到對象的子數組的末尾;而 Vue.js 似乎沒有跟蹤這些更改)。

我已經能夠通過這樣做來強制組件反應this.$forceUpdate(); 在上述push之后,但我想必須有一種更雄辯的方式來讓 Vue.js 在對象被推送到對象子數組的末尾時具有反應性。

有誰知道更好的方法來嘗試做我想要實現的目標? 謝謝你。

每當您向對象添加新屬性或更改數組中的值時,都需要使用Vue.set()

Vue.set(this.vals, prop, [ /* ... */ ])

理想情況下,您應該預先定義所有屬性,這樣 Vue 就不必根據您的數據模型的形狀使計算屬性無效。 即使您將它們設置為null ,您也應該嘗試繪制出您希望組件需要的所有屬性。

此外,在您的第一個代碼塊中,您在return:后有一個冒號,這將評估為一個標簽,這意味着您的數據函數沒有返回任何內容。

您可以使用lodashdeep watcher來嘗試這樣的事情。

更多關於deep watcher的信息

 new Vue({ el: "#app", methods: { setValue() { this.oldPeople = _.cloneDeep(this.people); } }, mounted() { this.setValue(); }, el: "#app", data: { changed: null, people: [ { id: 0, name: "Bob", age: 27 }, { id: 1, name: "Frank", age: 32 }, { id: 2, name: "Joe", age: 38 } ], oldPeople: [] }, watch: { people: { deep: true, handler(after, before) { // Return the object that changed let vm = this; let changed = after.filter(function(p, idx) { return Object.keys(p).some(function(prop) { return p[prop] !== vm.oldPeople[idx][prop]; }); }); vm.setValue(); this.changed = changed; }, } } });
 input { display: block; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script> <script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script> <div id="app"> <div> <input type="text" v-for="(person, index) in people" v-model="people[index].age" /> <div v-if="changed !== null"> You changed:<br/>{{ changed }} </div> </div> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM