全面分析 Vue 的 computed 和 watch 的區(qū)別

一安岂、computed介紹

computed 用來監(jiān)控自己定義的變量,該變量在 data 內(nèi)沒有聲明帆吻,直接在 computed 里面定義域那,頁(yè)面上可直接使用。

 //基礎(chǔ)使用
  {{msg}}
  <input v-model="name" />   
  //計(jì)算屬性 
  computed:{
    msg:function(){
      return this.name
    }
  }

在輸入框中猜煮,改變 name 值得時(shí)候次员,msg 也會(huì)跟著改變。這是因?yàn)?computed 監(jiān)聽自己的屬性 msg王带,發(fā)現(xiàn) name 一旦變動(dòng)淑蔚,msg 立馬會(huì)更新。

注意:msg 不可在 data 中定義愕撰,否則會(huì)報(bào)錯(cuò)刹衫。

1.1、get 和 set 用法
 <input v-model="full" ><br>
 <input v-model="first" > <br>
 <input v-model="second" > 
 data(){
    return{
       first:'美女',
       second:'姐姐'
     }
 },
 computed:{
  full:{
     get(){ //回調(diào)函數(shù) 當(dāng)需要讀取當(dāng)前屬性值是執(zhí)行搞挣,
            // 根據(jù)相關(guān)數(shù)據(jù)計(jì)算并返回當(dāng)前屬性的值
         return this.first + ' ' + this.second
      },
      set(val){ //監(jiān)視當(dāng)前屬性值的變化带迟,
                //當(dāng)屬性值發(fā)生變化時(shí)執(zhí)行,更新相關(guān)的屬性數(shù)據(jù)
         let names = val.split(' ')
         this.first = names[0]
         this.second = names[1]
       }
   }
}

get 方法:first 和 second 改變時(shí)囱桨,會(huì)調(diào)用 get 方法仓犬,更新 full 的值。
set 方法:修改 full 的值時(shí)舍肠,會(huì)調(diào)用 set 方法搀继,val 是 full 的最新值。

1.2翠语、計(jì)算屬性緩存

我們通過方法叽躯,拼接數(shù)據(jù),也可以實(shí)現(xiàn)該效果肌括,代碼如下险毁。

  <div> {{ full() }} </div>  
  data(){
    return{
      first:'美女',
     second:'姐姐'
    }
  },
  methods:{
   full(){
        return this.first + ' ' + this.second
      }
  }

一個(gè)頁(yè)面內(nèi),數(shù)據(jù)有可能多次使用,我們把 computed 和 method 兩個(gè)方法放一起實(shí)現(xiàn)畔况,并把這個(gè)數(shù)據(jù)在頁(yè)面內(nèi)多次引用鲸鹦,試看以下效果。

 <div>
  computed計(jì)算值:
   {{full}} {{full}} {{full}} {{full}}
</div>

 <div>
   methods計(jì)算值:
   {{fullt}} {{fullt}} {{fullt}} {{fullt}}
 </div>

  data(){
   return{
   first:'美女',
   second:'姐姐'
     }
  },
  computed:{
    full:function(){
     console.log('computed')
     return this.first + ' ' + this.second
    }
  },
 methods:{
     fullt(){
      console.log('method')
      return this.first + ' ' + this.second
   }
  }

運(yùn)行結(jié)果為:

根據(jù)結(jié)果跷跪,我們不難發(fā)現(xiàn)馋嗜,根據(jù)方法獲取到的數(shù)據(jù),使用幾次就需要重新計(jì)算幾次吵瞻,但計(jì)算屬性不是葛菇,而是基于它們的響應(yīng)式依賴進(jìn)行緩存的,之后依賴屬性值發(fā)生改變的時(shí)候橡羞,才會(huì)重新計(jì)算眯停。由于它計(jì)算次數(shù)少,所以性能更高些卿泽。

二莺债、watch介紹

watch 是監(jiān)測(cè) Vue 實(shí)例上的數(shù)據(jù)變動(dòng),通俗地講签夭,就是檢測(cè) data 內(nèi)聲明的數(shù)據(jù)齐邦。不僅可以監(jiān)測(cè)簡(jiǎn)單數(shù)據(jù),還可以監(jiān)測(cè)對(duì)象或?qū)ο髮傩浴?/p>

監(jiān)測(cè)簡(jiǎn)單數(shù)據(jù)
 <input v-model="first" > <br>  
  data(){
     return{
      first:'美女',
    }
  },
 watch:{
   first( newVal , oldVal ){
     console.log('newVal',newVal) // first 的最新值
     console.log('oldVal',oldVal) // first上一個(gè)值
    }
 }
 // 修改 first的值的時(shí)候第租,立馬會(huì)打印最新值  
監(jiān)測(cè)對(duì)象

監(jiān)聽對(duì)象的時(shí)候措拇,需要使用深度監(jiān)聽。

 <input v-model="per.name">  
   data(){
     return{
        per:{
          name:'倩倩',
          age:'18'
        }
    }
  },
   watch:{
     per:{
      handler(oldVal,newVal){
        console.log('newVal',newVal)
        console.log('oldVal',oldVal)
     },
     deep:true,
   }
  },

修改 per.name 的時(shí)候慎宾,發(fā)現(xiàn) newVal 和 oldVal 的值是一樣的丐吓,是因?yàn)樗麄兇鎯?chǔ)的指針指向的是同一個(gè)地方,所以深度監(jiān)聽雖然可以監(jiān)聽到對(duì)象的變化趟据,但是無法監(jiān)聽到具體的是哪個(gè)屬性發(fā)生變化了券犁。

監(jiān)聽對(duì)象的單個(gè)屬性
  // 方法1:直接引用對(duì)象的屬性
   <input v-model="per.name">  
   data(){
     return{
        per:{
         name:'倩倩',
         age:'18'
      }
     }
   },
   watch:{
   'per.name':function(newVal,oldVal){
      console.log('newVal->',newVal)
      console.log('oldVal->',oldVal)
     }
  }

也可以借助 computed 作為中間轉(zhuǎn)換,如下:

借助computed
 <input v-model="per.name">

 data(){
   return{
      per:{
         name:'倩倩',
         age:'18'
      }
    }
  },
  watch:{
   perName(){
     console.log('name改變了')
    }
 },
 computed:{
   perName:function(){
    return this.per.name
    }
 }
監(jiān)聽 props 組件傳過來的值
props:{
 mm:String
},
//不使用 immediate
watch:{
  mm(newV,oldV){
   console.log('newV',newV)
   console.log('oldV',oldV)
 }
}

//使用 immediate
watch:{
 mm:{
   immediate:true,
   handler(newV,oldV){
     console.log('newV',newV)
     console.log('oldV',oldV)
   }
 }

不使用 immediate 時(shí)之宿,第一次加載頁(yè)面時(shí)族操,watch 監(jiān)聽的 mm 中的打印并沒有執(zhí)行苛坚。

使用 immediate 時(shí)比被,第一次加載時(shí)也會(huì)打印結(jié)果:newV 11 oldV undefined。

immediate 主要作用就是組件加載時(shí)泼舱,會(huì)立即觸發(fā)回調(diào)函數(shù)等缀。

3.1、對(duì)于 computed
  • computed 監(jiān)控的數(shù)據(jù)在 data 中沒有聲明

  • computed 不支持異步娇昙,當(dāng) computed 中有異步操作時(shí)尺迂,無法監(jiān)聽數(shù)據(jù)的變化

  • computed 具有緩存,頁(yè)面重新渲染,值不變時(shí)噪裕,會(huì)直接返回之前的計(jì)算結(jié)果蹲盘,不會(huì)重新計(jì)算

  • 如果一個(gè)屬性是由其他屬性計(jì)算而來的,這個(gè)屬性依賴其他屬性膳音,一般使用 - ------computed

  • computed 計(jì)算屬性值是函數(shù)時(shí)召衔,默認(rèn)使用get方法。如果屬性值是屬性值時(shí)祭陷,屬性有一個(gè)get和set方法苍凛,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)會(huì)調(diào)用set方法

      computed:{
       //屬性值為函數(shù)
      perName:function(){
        return this.per.name
     },
      //屬性值為屬性值
     full:{
      get(){  },
       set(val){  }
     }
    },
    
3.2、對(duì)于 watch
  • 監(jiān)測(cè)的數(shù)據(jù)必須在 data 中聲明或 props 中數(shù)據(jù)

  • 支持異步操作

  • 沒有緩存兵志,頁(yè)面重新渲染時(shí)醇蝴,值不改變時(shí)也會(huì)執(zhí)行

  • 當(dāng)一個(gè)屬性值發(fā)生變化時(shí),就需要執(zhí)行相應(yīng)的操作

  • 監(jiān)聽數(shù)據(jù)發(fā)生變化時(shí)想罕,會(huì)觸發(fā)其他操作悠栓,函數(shù)有兩個(gè)參數(shù):

      immediate :組件加載立即觸發(fā)回調(diào)函數(shù)
      deep:深度監(jiān)聽,主要針對(duì)復(fù)雜數(shù)據(jù)弧呐,如監(jiān)聽對(duì)象時(shí)闸迷,添加深度監(jiān)聽,任意的 
      屬性值改變都會(huì)觸發(fā)俘枫。
      注意:對(duì)象添加深度監(jiān)聽之后腥沽,輸出的新舊值是一樣的。
    

computed 頁(yè)面重新渲染時(shí)鸠蚪,不會(huì)重復(fù)計(jì)算今阳,而 watch 會(huì)重新計(jì)算,所以 computed 性能更高些茅信。

四盾舌、應(yīng)用場(chǎng)景

當(dāng)需要進(jìn)行數(shù)值計(jì)算,并且依賴于其它數(shù)據(jù)時(shí)蘸鲸,應(yīng)該使用 computed 妖谴,因?yàn)榭梢岳?computed 的緩存特性,避免每次獲取值時(shí)都要重新計(jì)算酌摇。

當(dāng)需要在數(shù)據(jù)變化時(shí)執(zhí)行異步操作或開銷較大的操作時(shí)膝舅,應(yīng)該使用 watch,computed 不支持異步窑多。如果需要限制執(zhí)行操作的頻率仍稀,可借助 computed 作為中間狀態(tài)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末埂息,一起剝皮案震驚了整個(gè)濱河市技潘,隨后出現(xiàn)的幾起案子遥巴,更是在濱河造成了極大的恐慌,老刑警劉巖享幽,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铲掐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡值桩,警方通過查閱死者的電腦和手機(jī)迹炼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颠毙,“玉大人斯入,你說我怎么就攤上這事≈郏” “怎么了刻两?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滴某。 經(jīng)常有香客問我磅摹,道長(zhǎng),這世上最難降的妖魔是什么霎奢? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任户誓,我火速辦了婚禮,結(jié)果婚禮上幕侠,老公的妹妹穿的比我還像新娘帝美。我一直安慰自己,他們只是感情好晤硕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布悼潭。 她就那樣靜靜地躺著,像睡著了一般舞箍。 火紅的嫁衣襯著肌膚如雪舰褪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天疏橄,我揣著相機(jī)與錄音占拍,去河邊找鬼。 笑死捎迫,一個(gè)胖子當(dāng)著我的面吹牛晃酒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播立砸,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼掖疮,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼初茶!你這毒婦竟也來了颗祝?” 一聲冷哼從身側(cè)響起浊闪,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎螺戳,沒想到半個(gè)月后搁宾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡倔幼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年盖腿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片损同。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翩腐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出膏燃,到底是詐尸還是另有隱情茂卦,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布组哩,位于F島的核電站等龙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏伶贰。R本人自食惡果不足惜蛛砰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望黍衙。 院中可真熱鬧泥畅,春花似錦、人聲如沸琅翻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)望迎。三九已至障癌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辩尊,已是汗流浹背涛浙。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摄欲,地道東北人轿亮。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像胸墙,于是被迫代替她去往敵國(guó)和親我注。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容