[譯] VueJs 最佳實踐✓

原文連接javascript

開發者們,大家好。html

通過網上的一段搜索以及查閱Vue.js的文檔,我寫下了本文中關於Vue的最佳實踐以及風格指南,從而能夠更正確,更優雅的使用Vue.js。vue

下面的要點指出了其中一些功能/優化相關,其餘是VueJs命名約定和元素排序。 更詳細的信息能夠在連接中找到。java

題圖

在組件銷燬以後使用$off清除事件監聽器

當咱們在使用$on監聽事件的時候,老是須要在事件銷燬(destroyed())的時候使用$off清除事件監聽,這樣能夠有效防止內存泄漏。git

事件名稱使用短橫線式命名(kebab-case)

在派發/監聽事件的時候,咱們應該始終使用短橫線式命名(kebab-case),這是由於事件最終會被自動轉換爲該命名方式。咱們監聽的時間格式不能是駝峯式以及Pascal式,所以在聲明時間的時候,最好就講時間命名爲短橫線式。例如:github

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

避免在created以及watch中調用相同的method

若是咱們須要觸發組件初始化和屬性更改的方法,一般的作法是執行如下操做: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是一個最佳實踐,不包含:keyv-for循環會致使很難以查出的bug,尤爲是在動畫效果裏面。app

爲混入屬性(mixins properties)使用$_符號標記

Mixins 是是將重複代碼放入一個塊並將其導入屢次的好方法,但不少狀況下,這可能會致使一些問題。 在這一點上,咱們將解決重疊屬性的問題。框架

當咱們講一個mixin導入到咱們的組件當中時,其實是在吧minxin的代碼和組件中本來的代碼合併(merge)起來,那麼同名的屬性會呈現什麼樣呢?通常來講,組件的優先級更高,而且會覆蓋mixin。

那麼我要是須要mixin有更高的優先級,該怎麼辦呢?開發過程當中並不能聲明優先級,可是你能夠避免屬性的疊加,而且使用合適的命名方式來規避屬性的重寫。

In order to differentiate mixin properties from Component properties we use $_. Why these symbols? Well, several reasons: 爲了將Mixin的屬性與組件的屬性相區分,咱們使用$_,緣由以下:

  1. 這是Vuejs傳統風格
  2. _在Vuejs中表示私有屬性
  3. $屬於Vue的保留字

風格指南能夠看到官方推薦的Mixin命名:$_myMixin_updateUser

我發現添加mixin名稱會產生比可讀性更多的混亂。 但這也取決於mixin,狀況和開發人員。

經過在Mixin以前添加$_,例如$_updateUser,我發現代碼更具可讀性,能夠輕鬆區分Component和Mixin。

在Mixin中使用的屬性必須所有包含在Mixin之中

繼上一點以後,mixins還有另一個問題:mixin不夠獨立。

若是咱們建立一個使用的mixin,比方說,this.language並無從mixin中的store中定義或獲取此屬性,那麼定義mixin的Component必須包含language屬性。

正如您已經知道的那樣,這很是容易出錯。 爲了不這些錯誤,咱們在mixin裏面獲取全部須要的數據。 不要擔憂,若是咱們兩次獲取數據,VueJs是聰明的,若是檢測到從store獲取到相同的東西,將不會作雙重工做(由於大多數狀況下會從Vuex獲取數據)

對單文件組件使用PascalCase或kebab-case

PascalCase與編輯器具備更好的集成,並容許在經常使用IDE中實現更好的自動完成/導入功能。

若是咱們想要避免使用不區分大小寫的文件系統的問題,那麼就應該使用kebab-case。

基礎組件名稱以前加前綴

裝飾性、基礎組件應該有一個前綴,以區別於其餘複雜組件。 這大大提升了項目的可讀性以及團隊和開發人員之間的合做效率。

JS組件需以PascalCase 命名

在JavaScript中,類和原型構造方法通常使用PascalCase 命名,而且Vue組件也須要按此方式命名。

若是咱們只經過Vue.component使用全局組件,那可使用kebab-case。

Prop 在聲明時須要按照CamelCase命名,可是在模板中須要改爲kebab-case

HTML 中的特性名是大小寫不敏感的,因此瀏覽器會把全部大寫字符解釋爲小寫字符。這意味着當你使用 DOM 中的模板時,camelCase (駝峯命名法) 的 prop 名須要使用其等價的 kebab-case (短橫線分隔命名) 命名。

按照風格指南設置組件內部選項順序

這看起來沒什麼意義,可是按此規則寫成的組件更適合於大型多人開發項目,而且方便往後的擴展。

詳情在[風格指南]vuejs.org/v2/style-gu…)

不在同一個元素上同時使用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是否改變其活動狀態,咱們每一次都須要遍歷整個games列表。

在Angular等其餘框架中,這樣寫不能經過編譯:

(**ngIf* can't go in the same element where there is an **ngFor*)*。

Actions必需要有返回值

這是Vuex的actions和async/await的衝突形成的,請看這個例子:

// 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不知道要等待什麼,相反,若是咱們實際返回Promise.resolve(),則await將等待解析而後才繼續。

// 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
複製代碼

在actions和getters內部使用選擇器

咱們建立選擇器是不只要在app過程當中使用,還要在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清除事件監聽器 source
  2. 事件名稱使用短橫線式命名(kebab-case) source
  3. 避免在created以及watch中調用相同的method source
  4. **老是在v-for循環中使用 :keysource
  5. 爲混入屬性(mixins properties)使用$_符號標記 source
  6. 在Mixin中使用的屬性必須所有包含在Mixin之中
  7. 對單文件組件使用PascalCase或kebab-case source
  8. 基礎組件名稱以前加前綴 source
  9. JS組件需以PascalCase 命名 source
  10. **Prop 在聲明時須要按照CamelCase命名,可是在模板中須要改爲kebab-casesource
  11. 按照風格指南設置組件內部選項順序 source
  12. 不在同一個元素上同時使用v-if和v-for source
  13. Actions必需要有返回值
  14. 在actions和getters內部使用選擇器

參考文獻

後記

這篇文章是在使用VueJs以後完成的。 遵循這些風格指南和最佳實踐有助於讓每一個新開發者都有賓至如歸的感受,並當即投入到工做中!

翻譯後記

這篇文章着重於代碼風格,良好的代碼風格是優秀代碼的必要條件,也是多人合做過程當中必不可少的一部分,以前閱讀過阿里的Java手冊,深感一個龐大的項目,除了語法以外,也必須在開發以前對於全體開發者的代碼風格進行約束,雖然目前有了Eslint之類的風格檢查工具,可是諸如命名等仍是須要統一約束。

文章還對一些會影響性能以及容易報錯的寫法進行了糾正。整體來講值得一讀,也值得翻譯過來給你們看看😉

相關文章
相關標籤/搜索