【譯】VueJS 最佳實踐

原文地址: Vue.js best practices ✓ – Noteworthy - The Journal Blog
原文做者: Riccardo Polacci
譯者: amandakelake

各位開發小夥伴們好!  javascript

通過一段時間對VueJs官方文檔以及網上其餘相關vue資源的研究,我整理了一份最佳實踐和樣式指南列表,方便你們寫出更正確、更容易讓小夥伴接受的vue代碼。  html

如下有幾點是一些功能/優化相關,其餘是VueJs命名約定和元素排序相關。更多詳細信息能夠直接到最下方的總結中查看。
vue


在組件銷燬時用 $off 清除事件監聽

當咱們使用$on進行事件監聽時,要記住在destroyed()鉤子中用$off移除事件監聽,能夠有效防止內存泄漏。
java

使用短橫線分隔的形式命名事件

觸發/監聽自定義事件時,應該始終使用短橫線分隔。爲何呢?由於不管如何最後事件名都會被自動轉換爲短橫線分隔的形式。咱們不該該用駝峯命名或者首字母大寫的形式給監聽事件命名,而是使用一種更清晰有意義的方式來聲明一個事件:短橫線分隔git

// Emitting
this.$emit('my-event') // instead of myEvent
// Listening
v-on:my-event
複製代碼

不要在created生命週期和watch中調用同一個方法

若是咱們須要在組件初始化以及偵聽屬性變化時調用同一個方法,一般的作法像下面這樣
github

watch: {
  myProperty() {
    this.doSomething();
  }
},
created() {
  this.doSomething();
},
methods: {
  doSomething() {
     console.log('doing something...');
  }
},
複製代碼

儘管上面這段代碼看起來沒什麼問題,但created鉤子裏面執行的方法是多餘的。咱們能夠把所須要執行的方法放到watch裏面,避免在created鉤子裏寫重複代碼,那將會在組件實例化的時候觸發多一次。 好比像下面這樣:
數組

watch: {
  myProperty: {
    immediate: true, // 該回調將會在偵聽開始以後被當即調用
    handler() {
      this.doSomething();
    }
  }
},
methods: {
  doSomething() {
     console.log('doing something...');
  }
},

// 更好的方案
watch: {
  myProperty: {
    immediate: true,
    handler() {
      console.log('doing something...'); // 只用一次的方法不必在methods裏面聲明瞭
    }
  }
},
複製代碼

不要忘記在 v-for 循環中使用 key 

最多見的作法是始終在模板循環中添加:key鍵。沒有:key鍵的v-for循環在錯誤定位的時候比較麻煩,特別是動畫相關
bash

使用$_做爲mixins的私有屬性前綴

Mixins在代碼複用上是個不錯的方法,它能夠將重複代碼組合成一個單獨的模塊,而後按需引入。可是(極大可能),會出現一些問題。下面,咱們重點解決屬性名重複衝突的問題。框架

當咱們將mixin混入組件時,也就是將mixin內的代碼與組件自身的代碼進行合併,若是碰到同名屬性,會發生什麼?組件優先級更高,組件屬性的優先級天然更高。async

若是我想讓mixin代碼的優先級更高,應該怎麼辦?咱們沒法分配優先級,但能夠經過正確的命名規範來避免屬性重疊或者覆蓋。

爲了區分mixin屬性和組件的屬性,咱們一般使用`$_`做爲屬性前綴,爲何呢?主要有下面幾個緣由:

  1. 來自VueJs風格指南的建議 
  2. Vue 使用_前綴來定義其自身的私有屬性
  3. $是Vue生態系統暴露給用戶的特殊實例屬性 

風格指南 — Vue.js中,他們建議像這樣給mixin添加屬性名稱:$_myMixin_updateUser 

相對於可讀性,我發現給mixin添加名稱有時候也會產生一些混淆。但這也取決於mixin自己代碼,特殊狀況或者開發人員自己。 

經過添加一個簡單的$_,就像$_updateUser同樣,代碼更具可讀性,能夠輕鬆分辨出組件私有屬性和mixin的屬性。

mixin中使用的方法或者屬性應該直接在mixin中讀取

mixin上一點,還有另外一點要注意的。

假設咱們建立了一個mixin,它使用了this.language屬性,但這個屬性並非在mixin內部定義或獲取的,那麼混入了這個mixin的組件就必須包含這個language屬性。  

正如你已經知道的,這很是容易出錯。爲了提早避免錯誤的發生,mixin內使用到的屬性或者方法最好只在mixin內部定義獲取。沒必要擔憂重複獲取屬性的問題,由於VueJs在這點上很聰明,若是檢測到重複讀取屬性,將會自動處理(大部分狀況下是直接從Vuex裏直接讀取)。

使用首字母大寫或者短橫線分隔命名單文件組件

編輯器對首字母大寫命名的集成度更好,對在經常使用IDE中實現自動完成/導入功能更友好。  

若是咱們想要避免文件系統大小寫不敏感的問題,那麼最好選擇短橫線分隔

給基礎組件名加前綴

對於展現組件、純組件,應該給它們加上前綴,以區別於其餘的非純組件。這能夠大大提升項目可讀性,提升團隊協同開發體驗。 

使用首字母大寫命名命名JS中的組件

在JavaScript中,類和原型構造函數有默認約定使用首字母大寫命名,在Vue組件中使用首字母大寫命名有相同的意義。 若是咱們只經過`Vue.component`使用全局組件定義,建議使用短橫線分隔命名

聲明 prop 名時使用駝峯命名,但在模板中應使用短橫線分隔命名

遵循每種語言的慣例:JavaScript(駝峯)和HTML(短橫線分割),在JS中定義prop時用駝峯命名,在HTML中用於短橫線分割命名。

遵循樣式指南中的組件選項順序

這樣作可能看起來有點死板,可是在整個項目中對組件的全部選項執行相同的順序,在查找內容和建立新組件時有很大幫助。

 VueJs樣式指南能夠查看這裏風格指南 — Vue.js

不要在使用v-for的同一元素上使用v-if

這種作法堪稱性能殺手,列表數據越大,這種作法對性能的影響越大。

用代碼來看下問題吧,看如下場景:

<ul>
  <li
    v-for="game in games"
    v-if="game.isActive"
    :key="game.slug"
  >
    {{ game.title }}
  <li>
</ul>

複製代碼

相似於執行下面的代碼:

this.games.map(function (game) {
  if (game.isActive) {
    return game.title
  }
})
複製代碼

咱們能夠在這裏看到,咱們將不得不迭代整個games數組,不管game.isActive是否已經改變

在像Angular這樣的其餘框架中,這種作法不會被編譯(`* ngIf`不能進入有`* ngFor`的同一元素)


Actions必須有返回值

這跟async/await和 Vuex的 actions有關

看如下例子:

// Store
[SOME_ACTION] () {
   // 作點什麼,須要一段時間才能執行完
   console.log('Action done');
}
// Consuming action
async doSomething() {
  await dispatch(SOME_ACTION);
  console.log('Do stuff now');
}
This will output:
// Do stuff now
// Action done
複製代碼

發生這種狀況是由於await不知道要等待什麼,相反,若是咱們實際上返回了Promise.resolve(),則await將等待解析,而後再繼續

// Store
[SOME_ACTION] () {
   // 作點什麼,須要一段時間才能執行完
   console.log('Action done');
   Promise.resolve();
}
// Consuming action
async doSomething() {
  await dispatch(SOME_ACTION);
  console.log('Do stuff now');
}
This will output:
// Action done
// Do stuff now
複製代碼

在actions和getters中使用選擇器

建立選擇器時,不單只是在應用邏輯中使用,還要在Vuex store中使用

直接用代碼會更容易解釋: 

// 假設咱們讀取如下language屬性
export const language = (state) => state.userConfig.language;
// 在其中一個actions中, 須要用到language:

// 很差的例子
[GET_GAMES]({ commit, rootState }) {
   const lang = rootState.userConfig.language;
   // Do stuff...
}

// 正確的例子
[GET_GAMES]({ commit, rootState }) {
   const lang = language(rootState);
   // Do stuff...
}
複製代碼

總結

  1. 不要忘記在v-for循環中使用key
  2. 使用$_做爲mixins的私有屬性前綴
  3. mixin中使用的方法或者屬性應該直接在mixin中讀取
  4. 使用首字母大寫或者短橫線分隔命名單文件組件
  5. 給基礎組件名加前綴
  6. 使用首字母大寫命名命名JS中的組件
  7. 聲明 prop名時使用駝峯命名,但在模板中應使用短橫線分隔命名
  8. 遵循樣式指南中的組件選項順序
  9. 不要在使用v-for的同一元素上使用v-if
  10. Actions必須有返回值
  11. actionsgetters中使用選擇器

來源

  • https://vuejs-tips.github.io/cheatsheet/
  • https://learn-vuejs.github.io/vue-patterns/patterns/
  • https://vuejs.org/v2/style-guide/

感謝

這篇文章是由多個在同一項目中使用VueJs的開發人員合做完成的,遵循這份樣式指南和最佳實踐有助於讓每一個新開發人員都能儘快熟悉並上手項目代碼。 

若是你有什麼意見或者更好的提議,歡迎隨時評論。

相關文章
相關標籤/搜索