上一篇里演示了計算屬性的優點,但是,computed和data里的屬性還是有區別的,computed的一個弱點就在於依賴於data屬性的更新,才能觸發視圖更新。
舉個例子:
上個例子中談到用v-for來加載妹子圖片,現在我想在原先的基礎上,添加兩個按鈕,一個用來增加一個妹子,一個用來減少一個妹子:
html:
<div id="vfor"> <template v-for="mm in mms"> <span>{{mm.name}}</span> <image :src="mm.location"></image> </template> <button @click="addM">增加一個mm</button> <button v-on:click="removeM">減少一個mm</button> </div>
js:
1 var app14 = new Vue({ 2 el: "#vfor", 3 data: { 4 mms: [ 5 { 6 name: "mm1", 7 location: "http://image.zhangxinxu.com/image/study/s/s128/mm1.jpg" 8 }, 9 { 10 name: "mm2", 11 location: "http://image.zhangxinxu.com/image/study/s/s128/mm2.jpg" 12 }, 13 { 14 name: "mm3", 15 location: "http://image.zhangxinxu.com/image/study/s/s128/mm3.jpg" 16 }, 17 { 18 name: "mm4", 19 location: "http://image.zhangxinxu.com/image/study/s/s128/mm4.jpg" 20 } 21 ] 22 }, 23 methods: { 24 addM: function() { 25 //增加一個MM 26 var len = this.mms.length; 27 function mmCreate(i) { 28 var mmX = {}; 29 mmX.name = "mm" + i; 30 mmX.location = 31 "http://image.zhangxinxu.com/image/study/s/s128/mm" + i + ".jpg"; 32 return mmX; 33 } 34 this.mms.push(mmCreate(len)) 35 }, 36 removeM: function() { 37 //減少一個MM 38 this.mms.pop(); 39 } 40 } 41 });
可以到這里查看demo,這里通過button分別觸發addM()和removeM()方法,分別為mms數組增加一個元素和減少一個元素,實現了視圖上的MM的增加和減少。
使用computed屬性
現在,我覺得初始化data里的mms屬性太麻煩,所以准備在computed里面,用一個循環來初始化mms:
js:
computed: { mms: function(){ return [1,2,3,4].map(i => ({ name: "mm" + i, location: `http://image.zhangxinxu.com/image/study/s/s128/mm${i}.jpg` })) } }
通過一個函數返回arr。注意這里的computed屬性沒有依賴任何的data屬性。
這樣做,對於初始化mms來說是沒問題的。但是當點擊增加一個mm按鈕時,視圖並沒有更新,盡管mms數組發生了變化。原因就是上面所說的
computed properties are cached based on their dependencies. A computed property will only re-evaluate when some of its dependencies have changed.