Vue中的computed

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ū)別

  1. computed具有響應(yīng)式(雙向數(shù)據(jù)綁定),以屬性方式調(diào)用被啼,如:this.reversedMessage

  2. methods需以函數(shù)方式調(diào)用帜消,如:this.reversedMessage()

  3. 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ā)變化條件

  1. 觸發(fā)條件是內(nèi)部計(jì)算的數(shù)據(jù)發(fā)生改變
  2. 內(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é):

  1. computed用來監(jiān)控自己定義的變量倍踪,該變量不在data里面聲明系宫,直接在computed里面定義,然后就可以在頁面上進(jìn)行雙向數(shù)據(jù)綁定展示出結(jié)果或者用作其他處理建车;
  2. 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ì)算是最好的選擇
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嫉到,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子月洛,更是在濱河造成了極大的恐慌何恶,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膊存,死亡現(xiàn)場離奇詭異导而,居然都是意外死亡忱叭,警方通過查閱死者的電腦和手機(jī)隔崎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來韵丑,“玉大人爵卒,你說我怎么就攤上這事∧斐梗” “怎么了钓株?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵实牡,是天一觀的道長。 經(jīng)常有香客問我轴合,道長创坞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任受葛,我火速辦了婚禮题涨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘总滩。我一直安慰自己纲堵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布闰渔。 她就那樣靜靜地躺著席函,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冈涧。 梳的紋絲不亂的頭發(fā)上茂附,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音炕舵,去河邊找鬼何之。 笑死,一個(gè)胖子當(dāng)著我的面吹牛咽筋,可吹牛的內(nèi)容都是我干的溶推。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼奸攻,長吁一口氣:“原來是場噩夢啊……” “哼蒜危!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睹耐,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤辐赞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后硝训,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體响委,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年窖梁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赘风。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纵刘,死狀恐怖邀窃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情假哎,我是刑警寧澤瞬捕,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布鞍历,位于F島的核電站,受9級特大地震影響肪虎,放射性物質(zhì)發(fā)生泄漏劣砍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一扇救、第九天 我趴在偏房一處隱蔽的房頂上張望秆剪。 院中可真熱鬧,春花似錦爵政、人聲如沸仅讽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洁灵。三九已至,卻和暖如春掺出,著一層夾襖步出監(jiān)牢的瞬間徽千,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工汤锨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留双抽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓闲礼,卻偏偏與公主長得像牍汹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子柬泽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345