method和computed都是我們在vue項(xiàng)目中很常用的兩個(gè)屬性榴啸,相信大家對method不是很陌生但對computed卻是了解的不多(至少我是這樣的),今天剛好和同事聊到這個(gè),所以本篇文章主要來講講compued這個(gè)屬性恬砂,小伙伴們可以進(jìn)行參考學(xué)習(xí)蛤铜。
computed定義
計(jì)算屬性可用于快速計(jì)算視圖(View)中顯示的屬性。這些計(jì)算將被緩存荞彼,并且只在需要時(shí)更新冈敛。computed設(shè)置的初衷是能夠解決復(fù)雜的計(jì)算,而不是直接在模板字符串里進(jìn)行運(yùn)算鸣皂∽デ矗可以看以下的例子:
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 計(jì)算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 實(shí)例
return this.message.split('').reverse().join('')
}
}
})
在這里相信大家會(huì)發(fā)現(xiàn),這個(gè)computed和method的功能一樣寞缝,也是一個(gè)函數(shù)癌压;對的,我們用method也可以實(shí)現(xiàn)這種效果荆陆。例如:
<div id="example">
<p>Computed reversed message: "{{ reversedMessage() }}"</p>
/* 直接對函數(shù)進(jìn)行調(diào)用*/
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
可以看到二者的效果是一樣的滩届,但是其實(shí)二者還是有區(qū)別的
computed和method的區(qū)別
computed具有響應(yīng)式(雙向數(shù)據(jù)綁定),以屬性方式調(diào)用被啼,如:this.reversedMessage
methods需以函數(shù)方式調(diào)用帜消,如:this.reversedMessage()
-
computed具有緩存功能,只要里面的數(shù)據(jù)不發(fā)生改變浓体,就不會(huì)重新計(jì)算泡挺;methods每次調(diào)用都重新計(jì)算一次,也就是說使用了computed只有它們計(jì)算依賴的值發(fā)生變化的時(shí)候才會(huì)進(jìn)行重新計(jì)算命浴,這樣大大提高了性能娄猫。相比之下,每當(dāng)觸發(fā)重新渲染時(shí)生闲,method將總會(huì)再次執(zhí)行函數(shù)媳溺。
這里要注意的一點(diǎn)是,Date.now()將會(huì)在執(zhí)行一次以后失去作用
computed: { now: function () { return Date.now() } }
computed的觸發(fā)變化條件
- 觸發(fā)條件是內(nèi)部計(jì)算的數(shù)據(jù)發(fā)生改變
- 內(nèi)部的數(shù)據(jù)必須是響應(yīng)式的數(shù)據(jù)碍讯,普通數(shù)據(jù)vue無法知道是否有變化
例子1:
<template>
<div @click="change">{悬蔽}</div>
</template><script>
let a = {value: 1};
export default {
computed: {
b() {
return a.value;
}
},
methods: {
change() {
a.value = 2;
}
},
}
</script>
在點(diǎn)擊之后會(huì)返回什么值?
答案:點(diǎn)擊前是1捉兴,點(diǎn)擊后也是1
? 原因很簡單屯阀,a不是一個(gè)響應(yīng)式的值缅帘,沒有被vue劫持,所有數(shù)據(jù)改變時(shí)vue并不知道难衰,所已沒有觸發(fā)b的更新
例子2:
<template>
<div @click="change">{钦无}</div>
</template>
<script>
export default {
data() {
return {
a: {value: 1}
}
},
computed: {
b() {
return this.a.value;
}
},
methods: {
change() {
this.a.value = 2;
}
},
}
</script>
答案:點(diǎn)擊后,觸發(fā)了change盖袭,把a(bǔ).value改為2失暂,因?yàn)閍是在data函數(shù)里,data函數(shù)里的數(shù)據(jù)是被vue劫持的鳄虱,具有響應(yīng)式弟塞,所以會(huì)觸發(fā)計(jì)算屬性b的更新。
computed的settter
在computed屬性中同樣為我們提供了setter-getter方法
/*來自官方文檔的例子*/
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
簡單理解就是:
setter():用來設(shè)置成員變量拙已,可以在方法里面過濾掉一些不合理的值
- 必須是對象方法
- 返回值類型為void
- 方法名以set開頭
- 必須提供一個(gè)參數(shù)决记,參數(shù)類型必須與所對應(yīng)的成員變量的類型一致
getter():為調(diào)用者返回對象內(nèi)部的成員變量的值
- 必須是對象方法
- 必須有返回值,返回值的類型和成員變量的類型一致
- 方法名必須是成員變量去掉下劃線
- 一定是沒有參數(shù)的
例子:
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
可以看到getter只是對原本值的處理后返回;而setter則會(huì)重新設(shè)置值
總結(jié):
- computed用來監(jiān)控自己定義的變量倍踪,該變量不在data里面聲明系宫,直接在computed里面定義,然后就可以在頁面上進(jìn)行雙向數(shù)據(jù)綁定展示出結(jié)果或者用作其他處理建车;
- computed比較適合對多個(gè)變量或者對象進(jìn)行處理后返回一個(gè)結(jié)果值扩借,也就是數(shù)多個(gè)變量中的某一個(gè)值發(fā)生了變化則我們監(jiān)控的這個(gè)值也就會(huì)發(fā)生變化,舉例:購物車?yán)锩娴纳唐妨斜砗涂偨痤~之間的關(guān)系缤至,只要商品列表里面的商品數(shù)量發(fā)生變化潮罪,或減少或增多或刪除商品,總金額都應(yīng)該發(fā)生變化领斥。這里的這個(gè)總金額使用computed屬性來進(jìn)行計(jì)算是最好的選擇