VueJs best practices [譯]

前言:

最近開始學習使用 Vue,在看完一遍官方文檔,實踐的過程當中發現有不少約定,特別是命名和引用組件的時候組件的名字,我都以爲很奇怪,在看到這篇文章以後,說實話是被標題黨了,以爲能夠經過別人總結的最佳實踐來指導 Vue 的開發,可是看完以後確實對不少不理解的事情給了一個解釋,也有不少的參考連接,下面就是原文翻譯,想看原文點擊html

正文

各位開發者你們好, 在探索了一段時間的 VueJs 文檔和 web 以後,爲了更加正確的或更廣泛易於接受的方式來使用 vuejs,建立了一個最佳實踐和樣式指南的列表。vue

下面的要點是與功能/優化相關的,其餘的是關於 VueJs 命名約定和元素排序。更詳細的信息能夠在摘要中的連接中找到。git

在組件被銷燬的時候使用 $off 清除事件監聽器

當使用 $on 監聽一個事件的時候,咱們應該始終記得在 destroyed() 方法中使用 $off 移除這個事件監聽器,這是爲了防止咱們產生內存泄漏。github

事件命名須要使用 kebab-case(短橫線命名法)命名

當發佈或者監聽一個自定義事件時,咱們應該始終使用 kebab-case(短橫線命名法),爲何?由於不管如何事件都會被自動轉換成小寫的形式,咱們永遠不會在 camelCase(駝峯式) 或 PascalCase(帕斯卡命名法) 中監聽事件,所以,以與監聽事件相同的方式(使用 kebab-case)聲明該事件更有意義。web

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

避免在 watchcreated 中調用同一個事件

若是咱們須要在組件初始化和屬性更新的時候觸發一個方法,一般的作法是執行如下操做:api

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

即便它看起來多是正確的,但在這裏使用 created()實際上是多餘的。咱們能夠將全部功能都放入 watch,所以避免了必須在 created() 中重複代碼而且依舊能夠在組件初始化的時候觸發這個方法。如:框架

watch: {
  myProperty: {
    immediate: true, // forcing handler on initial status
    handler() {
      this.doSomething();
    }
  }
},
methods: {
  doSomething() {
     console.log('doing something...');
  }
},
// Even better solution
watch: {
  myProperty: {
    immediate: true, // forcing handler on initial status
    handler() {
      console.log('doing something...'); // No need to declare a function on methods for 1 use case
    }
  }
},
複製代碼

始終要在在 v-for 循環中使用 :key

在你的模板循環中添加 :key是一個常見的最佳實踐,使用 v-for 的時候卻不使用 :key 會致使難以發現錯誤,特別是在動畫中。async

爲 Mixins 使用 $_ 前綴

Mixins 是一種將重複代碼放入一個塊並根據須要將其導入屢次的好方法,可是(並且這是一個很大的轉折),這可能會致使多個問題。從這一點講,咱們將解決重疊屬性的問題。編輯器

當咱們將一個 mixin 導入到組件中時,咱們正在將 mixin 代碼與組件代碼合併,如今,具備相同名稱的屬性會發生什麼?組件將始終佔據上風,組件的屬性具備更高的優先級。ide

若是我但願個人 mixin 擁有更高的優先級怎麼辦?您不能分配優先級,可是能夠經過選擇正確的命名約定來避免屬性重疊甚至覆蓋。 爲了區分 mixin 屬性和組件屬性,咱們使用 $_。爲何使用這些符號?好吧,有這幾個緣由:

  1. VueJs 樣式指南中的約定
  2. _ 是 Vue 的私密屬性保留字
  3. $ 是 Vue 的生態系統保留字

VueJs 風格指南中,您會發現他們建議加上 mixin 的名字,例如:$_myMixin_updateUser

我發現添加混入的名字會引發比可讀性問題以外更多的混亂。但這也取決於 mixin,上下文環境和開發人員。

經過添加一個簡單的 $_,像在 $_updateUser 中,我發現代碼可讀性更好,而且能夠輕鬆地區分組件和Mixin。

mixin 中使用的內容應被限制在 mixin

跟進上一點,mixins 還有另外一個問題:咱們忘記了內容(stuff)。

比方說,若是咱們建立一個使用 this.language 的 mixin,而且這個屬性沒有被定義或從 mixin內部的商店中獲取,則定義 mixin的組件必須包含該 language 屬性。

您已經知道,這很是容易出錯。爲了不這些錯誤,咱們在 mixin 自己內部獲取了 mixin 所需的內容。沒必要擔憂咱們要抓兩次內容, VueJs 很聰明,若是它檢測到相同的內容已經從 Store 中獲取到了,就不會作雙重工做(由於大多數狀況下都是從 Vuex 獲取內容)

對單文件組件使用 PascalCase (帕斯卡命名法)或 kebab-case(短橫線命名法)

帕斯卡命名法與編輯器具備更好的集成,並在經常使用的 IDE 之間提供了更好的自動完成/導入功能。 若是要避免在不區分大小寫的文件系統出現問題,能夠考慮採用短橫線命名法。

對基礎組件命名時使用前綴

Presentational, dumb, or pure 組件須要使用前綴來和其餘的 non pure 組件進行區分。這大大提升了項目的可讀性以及團隊和開發人員之間的知識傳遞。

使用PascalCase(帕斯卡命名法)做爲JS中的組件名稱

在JavaScript中,帕斯卡命名法是類和原型構造函數的約定,這使 Vue 組件也使用帕斯卡命名法具備了意義。

若是咱們僅經過使用全局組件定義 Vue.component,建議使用短橫線命名法。

Prop 名稱聲明期間應始終使用 camelCase(駝峯命名法),但模板中使用 kebab-case(短橫線命名法)

遵循每種語言的約定:JavaScript (駝峯命名法)和HTML(短橫線命名法),這使 prop 在 js 文件中使用駝峯命名法聲明而且在 HTML 中使用短橫線命名法具備了意義。

使用樣式指南中規定的組件選項順序

這看起來彷佛很乏味,可是在整個項目中查找組件和建立新的組件時,對整個項目中的組件的全部選項遵循相同的順序會頗有幫助。

VueJs約定能夠在樣式指南中找到。

切勿在相同的元素上使用v-if,好比 v-for

這是一個性能殺手,列表越大,這種不良實踐將使更多性能受到影響。 讓咱們用代碼來解釋,想象一下如下狀況:

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 的活動列表是否被更新。

在其餘框架中,好比說 Angular,這種操做不會被編譯(*ngIf不能在存在的同一元素中進行*ngFor)

Actions 必須有返回值

這是在學習 async/await 和 Vuex actions 後所收穫的。 請看如下示例:

// Store
[SOME_ACTION] () {
   // Doing stuff that takes a while
   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 不知道該 await 什麼,相反,若是咱們實際上返回一個 Promise.resolve()await 它將等待這個 resolve 而後繼續執行。

// Store
[SOME_ACTION] () {
   // Doing stuff that takes a while
   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
複製代碼

actionsgetters 裏面使用選擇器

咱們之因此建立選擇器,是有緣由的,它不只能夠在整個應用程序中使用,並且能夠在Vuex Store 中使用。 配合代碼更好的理解:

// We have this selector
export const language = (state) => state.userConfig.language;
// In one of our actions, we need language:
// Bad
[GET_GAMES]({ commit, rootState }) {
   const lang = rootState.userConfig.language;
   // Do stuff...
}
// Good
[GET_GAMES]({ commit, rootState }) {
   const lang = language(rootState);
   // Do stuff...
}
複製代碼

總結

  1. 在組件被銷燬的時候使用 $off 清除事件監聽器
  2. 事件命名須要使用 kebab-case(短橫線命名法)命名
  3. 避免在 watchcreated 中調用同一個事件
  4. 始終要在在 v-for 循環中使用 :key
  5. 爲 Mixins 使用 $_ 前綴
  6. mixin 中使用的內容應被限制在 mixin
  7. 對單文件組件使用 PascalCase (帕斯卡命名法)或 kebab-case(短橫線命名法)
  8. 對基礎組件命名時使用前綴
  9. 使用PascalCase(帕斯卡命名法)做爲JS中的組件名稱 10. Prop 名稱聲明期間應始終使用 camelCase(駝峯命名法),但模板中使用 kebab-case(短橫線命名法)
  10. 使用樣式指南中規定的組件選項順序
  11. 切勿在相同的元素上使用v-if,好比 v-for
  12. Actions 必須有返回值
  13. actionsgetters 裏面使用選擇器

參考連接

謝謝!

相關文章
相關標籤/搜索