<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          10個(gè)Vue開(kāi)發(fā)技巧助力成為更好的工程師

          共 8710字,需瀏覽 18分鐘

           ·

          2020-12-17 13:52

          你的關(guān)注意義重大!


          作者 /?chanwahfung

          ? ? ? ?? 閱讀本文需要?3分鐘

          優(yōu)雅更新props

          更新?prop?在業(yè)務(wù)中是很常見(jiàn)的需求,但在子組件中不允許直接修改?prop,因?yàn)檫@種做法不符合單向數(shù)據(jù)流的原則,在開(kāi)發(fā)模式下還會(huì)報(bào)出警告。因此大多數(shù)人會(huì)通過(guò)?$emit?觸發(fā)自定義事件,在父組件中接收該事件的傳值來(lái)更新?prop

          child.vue:

          export?defalut?{
          ????props:?{
          ????????title:?String??
          ????},
          ????methods:?{
          ????????changeTitle(){
          ????????????this.$emit('change-title',?'hello')
          ????????}
          ????}
          }

          parent.vue:

          <child?:title="title"?@change-title="changeTitle">child>
          export?default?{
          ????data(){
          ????????return?{
          ????????????title:?'title'
          ????????}??
          ????},
          ????methods:?{
          ????????changeTitle(title){
          ????????????this.title?=?title
          ????????}
          ????}
          }

          這種做法沒(méi)有問(wèn)題,我也常用這種手段來(lái)更新?prop。但如果你只是想單純的更新?prop,沒(méi)有其他的操作。那么?sync?修飾符能夠讓這一切都變得特別簡(jiǎn)單。

          parent.vue:

          <child?:title.sync="title">child>

          child.vue:

          export?defalut?{
          ????props:?{
          ????????title:?String??
          ????},
          ????methods:?{
          ????????changeTitle(){
          ????????????this.$emit('update:title',?'hello')
          ????????}
          ????}
          }

          只需要在綁定屬性上添加?.sync,在子組件內(nèi)部就可以觸發(fā)?update:屬性名?來(lái)更新?prop。可以看到這種手段確實(shí)簡(jiǎn)潔且優(yōu)雅,這讓父組件的代碼中減少一個(gè)“沒(méi)必要的函數(shù)”。

          參考文檔

          provide/inject

          這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在其上下游關(guān)系成立的時(shí)間里始終生效。

          簡(jiǎn)單來(lái)說(shuō),一個(gè)組件將自己的屬性通過(guò)?provide?暴露出去,其下面的子孫組件?inject?即可接收到暴露的屬性。

          App.vue:

          export?default?{
          ????provide()?{
          ????????return?{
          ????????????app:?this
          ????????}
          ????}?
          }

          child.vue:

          export?default?{
          ????inject:?['app'],
          ????created()?{
          ????????console.log(this.app)?//?App.vue實(shí)例
          ????}
          }

          在 2.5.0+ 版本可以通過(guò)設(shè)置默認(rèn)值使其變成可選項(xiàng):

          export?default?{
          ????inject:?{
          ????????app:?{
          ????????????default:?()?=>?({})
          ????????}
          ????},
          ????created()?{
          ????????console.log(this.app)?
          ????}
          }

          如果你想為?inject?的屬性變更名稱,可以使用?from?來(lái)表示其來(lái)源:

          export?default?{
          ????inject:?{
          ????????myApp:?{
          ????????????//?from的值和provide的屬性名保持一致
          ????????????from:?'app',
          ????????????default:?()?=>?({})
          ????????}
          ????},
          ????created()?{
          ????????console.log(this.myApp)?
          ????}
          }

          需要注意的是?provide?和?inject?主要在開(kāi)發(fā)高階插件/組件庫(kù)時(shí)使用。并不推薦用于普通應(yīng)用程序代碼中。但是某些時(shí)候,或許它能幫助到我們。

          參考文檔

          小型狀態(tài)管理器

          大型項(xiàng)目中的數(shù)據(jù)狀態(tài)會(huì)比較復(fù)雜,一般都會(huì)使用?vuex?來(lái)管理。但在一些小型項(xiàng)目或狀態(tài)簡(jiǎn)單的項(xiàng)目中,為了管理幾個(gè)狀態(tài)而引入一個(gè)庫(kù),顯得有些笨重。

          在 2.6.0+ 版本中,新增的?Vue.observable?可以幫助我們解決這個(gè)尷尬的問(wèn)題,它能讓一個(gè)對(duì)象變成響應(yīng)式數(shù)據(jù):

          //?store.js
          import?Vue?from?'vue'

          export?const?state?=?Vue.observable({?
          ??count:?0?
          })

          使用:

          <div?@click="setCount">{{?count?}}div>
          import?{state}?from?'../store.js'

          export?default?{
          ????computed:?{
          ????????count()?{
          ????????????return?state.count
          ????????}
          ????},
          ????methods:?{
          ????????setCount()?{
          ????????????state.count++
          ????????}
          ????}
          }

          當(dāng)然你也可以自定義?mutation?來(lái)復(fù)用更改狀態(tài)的方法:

          import?Vue?from?'vue'

          export?const?state?=?Vue.observable({?
          ??count:?0?
          })

          export?const?mutations?=?{
          ??SET_COUNT(payload)?{
          ????if?(payload?>?0)?{
          ????????state.count?=?payload
          ????}?
          ??}
          }

          使用:

          import?{state,?mutations}?from?'../store.js'

          export?default?{
          ????computed:?{
          ????????count()?{
          ????????????return?state.count
          ????????}
          ????},
          ????methods:?{
          ????????setCount()?{
          ????????????mutations.SET_COUNT(100)
          ????????}
          ????}
          }

          參考文檔

          卸載watch觀察

          通常定義數(shù)據(jù)觀察,會(huì)使用選項(xiàng)的方式在?watch?中配置:

          export?default?{
          ????data()?{
          ????????return?{
          ????????????count:?1??????
          ????????}
          ????},
          ????watch:?{
          ????????count(newVal)?{
          ????????????console.log('count 新值:'+newVal)
          ????????}
          ????}
          }

          除此之外,數(shù)據(jù)觀察還有另一種函數(shù)式定義的方式:

          export?default?{
          ????data()?{
          ????????return?{
          ????????????count:?1??????
          ????????}
          ????},
          ????created()?{
          ????????this.$watch('count',?function(){
          ????????????console.log('count 新值:'+newVal)
          ????????})
          ????}
          }

          它和前者的作用一樣,但這種方式使定義數(shù)據(jù)觀察更靈活,而且?$watch?會(huì)返回一個(gè)取消觀察函數(shù),用來(lái)停止觸發(fā)回調(diào):

          let?unwatchFn?=?this.$watch('count',?function(){
          ????console.log('count 新值:'+newVal)
          })
          this.count?=?2?// log: count 新值:2
          unwatchFn()
          this.count?=?3?//?什么都沒(méi)有發(fā)生...

          $watch?第三個(gè)參數(shù)接收一個(gè)配置選項(xiàng):

          this.$watch('count',?function(){
          ????console.log('count 新值:'+newVal)
          },?{
          ????immediate:?true?//?立即執(zhí)行watch
          })

          參考文檔

          巧用template

          相信?v-if?在開(kāi)發(fā)中是用得最多的指令,那么你一定遇到過(guò)這樣的場(chǎng)景,多個(gè)元素需要切換,而且切換條件都一樣,一般都會(huì)使用一個(gè)元素包裹起來(lái),在這個(gè)元素上做切換。

          <div?v-if="status==='ok'">
          ????<h1>Titleh1>
          ????<p>Paragraph?1p>
          ????<p>Paragraph?2p>
          div>

          如果像上面的 div 只是為了切換條件而存在,還導(dǎo)致元素層級(jí)嵌套多一層,那么它沒(méi)有“存在的意義”。

          我們都知道在聲明頁(yè)面模板時(shí),所有元素需要放在?