Vue 響應式短文
故事前言
工作碰上一個問題,就是我在模擬一份資料。這份資料長度不明,但我會需要自己新增屬性。問題在於,如果我想更改狀態,啥都沒有。因為想先快回家,所以這個問題只好留著不解決(我的頭……)。
你怎麼了?
程式如下:
<div v-for="(odd, idx) in i.odds">
<div id="app" v-bind:class="{ active : foobar( input ) , box : true }">
<div v-on:click="fbz( input )"> <!-- active -->
<p> {{ idx + 1 }} </p>
<p class=""> {{ odd }} </p>
</div>
</div>
</div>
var app = new Vue({
el:"#app",
data: { odds:[] },
methods: {
foobar: function(x,y){},
fbz: function(x,y){}
},
computed: {
other_methods: function(x,y){}
},
mounted: function() {
// AJAX
app.odds = AJAX.recived;
app.odds.forEach( (el,idx) => { app.odds[idx].b = false; } )
}
});
/*
我想透過點選 fbz 函式變換 #app 的 input 狀態,再透過 .active 參照 #app 的狀態。
但是我發現 .active 無論選 fbz 還是 other_methods 如何都不會變動……
*/
回去看資料,發現有人想用 watch 解決。不過我看不懂程式碼,所以決定先放著。
直到我看見 Github 的某人提出 issue 才發現曙光。
簡單來說,你有什麼發現?
關鍵字是 Reactivity。解法是 .$set
。
所以我說為什麼?
問題是在「自己新增屬性」這點,因為 Vue「不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property。)」。所以我想透過 mounted
新增屬性會變得徒勞無功。
另外我也很好奇:Vue 官方說明之所以有這麼詭異的問題,是「受现代 JavaScript 的限制 (以及废弃 Object.observe)」。但,那個「限制」是什麼?可能要看 getter setter 了。
那怎麼辦?
在 mounted
新增屬性時設定 .$set
。上例就是改為 app.odds.forEach( (el,idx) => { this.$set( this.odds[idx] , 'b', false); )
:
mounted: function() {
// AJAX
app.odds = AJAX.recived;
app.odds.forEach( (el,idx) => { this.$set( this.odds[idx] , 'b', false); } )
}
後記
幹,我頭超級痛。我覺得我好像要看醫生。
20180701 增筆
我想起有人告訴我:「你可以用 computed
實例,這樣的話就能響應了。」——但是我最後沒有採用 computed
實例,理由是 computed
實例無法傳送參數。這樣的話 computed
對上例就無能為力。
可以看看 Stack Overflow 還有 Laracasts 上面的回答。