理解computed并不難,但是我認(rèn)為結(jié)合methods和watch去理解的話,會(huì)更透徹更有條理,所以整理了下面的知識(shí):
我的其他文章,也可以了解一下:
【使用vue-cli(vue腳手架)快速搭建項(xiàng)目】:http://www.itdecent.cn/p/1ee1c410dc67
【vue之父子組件間通信實(shí)例講解(props、ref 、 emit )】:
http://www.itdecent.cn/p/91416e11f012
【vue之將echart封裝為組件】:
http://www.itdecent.cn/p/ec39019e2141
【理解vue實(shí)例的生命周期和鉤子函數(shù)】:
http://www.itdecent.cn/p/98517bd49179
【vue之事件修飾符的使用】:
http://www.itdecent.cn/p/cbe77baee153
1. 從methods的角度理解
我們可以在模板內(nèi)使用表達(dá)式進(jìn)行簡(jiǎn)單的計(jì)算:
<template>
<div> Reversed message: "{{ message + 'OPQ'}}"</div>
</template>
但是對(duì)于相對(duì)復(fù)雜一點(diǎn)的邏輯,我們一般會(huì)調(diào)用方法處理然后再返回結(jié)果:
<template>
<div> Reversed message: "{{revMessage()}}"</div>
</template>
<script type="text/javascript">
export default {
data() {
return {
message: "ABCDEFG"
}
},
methods: {
revMessage: function () {
return this.message.split('').reverse().join('')
}
}
}
</script>

methods很好的處理了這些相對(duì)復(fù)雜的邏輯計(jì)算,但是methods有兩個(gè)特性:
- methods是交互方法,需要主動(dòng)去觸發(fā)
- methods每次計(jì)算后都會(huì)把變量回收,再次訪問(wèn)的時(shí)候會(huì)重新計(jì)算。
如果想緩存計(jì)算結(jié)果,這個(gè)時(shí)候就可以用到computed了:
<template>
<div> Reversed message: "{{revMessage}}"</div>
</template>
<script type="text/javascript">
export default {
data() {
return {
message: "ABCDEFG"
}
},
computed: {
revMessage: function () {
return this.message.split('').reverse().join('')
}
}
}
</script>

為了更理解computed的特性,我們通過(guò)調(diào)試臺(tái)改變message的值:

我們可以看到,在改變message的值之前,使用methods和computed得到的結(jié)果是一樣,而當(dāng)我們?nèi)ジ淖僲essage的值以后會(huì)自動(dòng)觸發(fā)revMessage,對(duì)字符串進(jìn)行翻轉(zhuǎn)。
通過(guò)上面的例子,應(yīng)該能大概理解computed相對(duì)于methods的一些特性了,下面我還是進(jìn)行一下總結(jié):
- methods是交互方法需要主動(dòng)去觸發(fā),而computed則是在檢測(cè)到data數(shù)據(jù)變化時(shí)自動(dòng)觸發(fā)的。
- methods是一次性無(wú)緩存的計(jì)算,computed則是有緩存的。methods每次計(jì)算后都會(huì)把變量回收,再次訪問(wèn)的時(shí)候會(huì)重新計(jì)算。而computed則是依賴數(shù)據(jù)的,數(shù)據(jù)占用內(nèi)存是不會(huì)被回收掉的,再次訪問(wèn)的時(shí)候不會(huì)重新計(jì)算,而是返回上次計(jì)算的值,當(dāng)依賴的數(shù)據(jù)發(fā)生改變時(shí)才會(huì)再次計(jì)算。
2. 從watch的角度理解
理解了methods和computed兩者的區(qū)別以后,熟悉AngularJS或者Avalon.js的人可能會(huì)發(fā)現(xiàn),其實(shí)computed和watch迷之相似,都是在關(guān)注一個(gè)數(shù)據(jù),并在數(shù)據(jù)發(fā)生變化的時(shí)候做出反應(yīng)。沒(méi)錯(cuò),很相像,但是vue認(rèn)為大部分時(shí)候使用計(jì)算屬性,會(huì)比使用watch監(jiān)聽(tīng)更優(yōu),我們看看下面兩個(gè)的例子:
//watch的例子
<template>
<div>message: {{all}}</div>
</template>
<script type="text/javascript">
export default {
data() {
return {
all:'ABCEFG',
message1:'ABC',
message2:'EFG'
}
},
watch: {
message1: function (val) {
this.all = val+ this.message2
},
message2: function (val) {
this.all = this.message1+ val
}
},
mounted(){
window.vue = this
}
}
</script>
//computed的例子
<template>
<div>message: {{all}}</div>
</template>
<script type="text/javascript">
export default {
data() {
return {
message1:'ABC',
message2:'EFG'
}
},
computed: {
all: function () {
return this.message1 + this.message2
},
},
mounted(){
window.vue = this
}
}
</script>
這兩段代碼都是在做同一件事,監(jiān)聽(tīng)message1和message2,在任何一個(gè)數(shù)據(jù)有變化的時(shí)候觸發(fā)回調(diào),更新兩者合并的值。但是可以看到,使用watch的話需要分開(kāi)兩次去監(jiān)聽(tīng),然后再分開(kāi)兩邊執(zhí)行回調(diào),相比之下使用computed簡(jiǎn)練的多了。
當(dāng)然,不是所有情況下使用computed都會(huì)更優(yōu),可以看看官網(wǎng)的解釋:#watch偵聽(tīng)器#