最近開始學習使用 Vue,在看完一遍官方文檔,實踐的過程當中發現有不少約定,特別是命名和引用組件的時候組件的名字,我都以爲很奇怪,在看到這篇文章以後,說實話是被標題黨了,以爲能夠經過別人總結的最佳實踐來指導 Vue 的開發,可是看完以後確實對不少不理解的事情給了一個解釋,也有不少的參考連接,下面就是原文翻譯,想看原文點擊html
各位開發者你們好, 在探索了一段時間的 VueJs 文檔和 web 以後,爲了更加正確的或更廣泛易於接受的方式來使用 vuejs,建立了一個最佳實踐和樣式指南的列表。vue
下面的要點是與功能/優化相關的,其餘的是關於 VueJs 命名約定和元素排序。更詳細的信息能夠在摘要中的連接中找到。git
$off
清除事件監聽器當使用 $on
監聽一個事件的時候,咱們應該始終記得在 destroyed()
方法中使用 $off
移除這個事件監聽器,這是爲了防止咱們產生內存泄漏。github
當發佈或者監聽一個自定義事件時,咱們應該始終使用 kebab-case(短橫線命名法),爲何?由於不管如何事件都會被自動轉換成小寫的形式,咱們永遠不會在 camelCase(駝峯式) 或 PascalCase(帕斯卡命名法) 中監聽事件,所以,以與監聽事件相同的方式(使用 kebab-case)聲明該事件更有意義。web
// Emitting
this.$emit('my-event') // instead of myEvent
// Listening
v-on:my-event
複製代碼
watch
和 created
中調用同一個事件若是咱們須要在組件初始化和屬性更新的時候觸發一個方法,一般的作法是執行如下操做: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 是一種將重複代碼放入一個塊並根據須要將其導入屢次的好方法,可是(並且這是一個很大的轉折),這可能會致使多個問題。從這一點講,咱們將解決重疊屬性的問題。編輯器
當咱們將一個 mixin
導入到組件中時,咱們正在將 mixin 代碼與組件代碼合併,如今,具備相同名稱的屬性會發生什麼?組件將始終佔據上風,組件的屬性具備更高的優先級。ide
若是我但願個人 mixin
擁有更高的優先級怎麼辦?您不能分配優先級,可是能夠經過選擇正確的命名約定來避免屬性重疊甚至覆蓋。 爲了區分 mixin
屬性和組件屬性,咱們使用 $_
。爲何使用這些符號?好吧,有這幾個緣由:
VueJs
樣式指南中的約定在 VueJs 風格指南中,您會發現他們建議加上 mixin
的名字,例如:$_myMixin_updateUser
。
我發現添加混入的名字會引發比可讀性問題以外更多的混亂。但這也取決於 mixin
,上下文環境和開發人員。
經過添加一個簡單的 $_
,像在 $_updateUser
中,我發現代碼可讀性更好,而且能夠輕鬆地區分組件和Mixin。
mixin
中使用的內容應被限制在 mixin
中跟進上一點,mixins 還有另外一個問題:咱們忘記了內容(stuff)。
比方說,若是咱們建立一個使用 this.language
的 mixin,而且這個屬性沒有被定義或從 mixin
內部的商店中獲取,則定義 mixin
的組件必須包含該 language
屬性。
您已經知道,這很是容易出錯。爲了不這些錯誤,咱們在 mixin
自己內部獲取了 mixin
所需的內容。沒必要擔憂咱們要抓兩次內容, VueJs
很聰明,若是它檢測到相同的內容已經從 Store
中獲取到了,就不會作雙重工做(由於大多數狀況下都是從 Vuex 獲取內容)
帕斯卡命名法與編輯器具備更好的集成,並在經常使用的 IDE 之間提供了更好的自動完成/導入功能。 若是要避免在不區分大小寫的文件系統出現問題,能夠考慮採用短橫線命名法。
Presentational, dumb, or pure 組件須要使用前綴來和其餘的 non pure 組件進行區分。這大大提升了項目的可讀性以及團隊和開發人員之間的知識傳遞。
在JavaScript中,帕斯卡命名法是類和原型構造函數的約定,這使 Vue 組件也使用帕斯卡命名法具備了意義。
若是咱們僅經過使用全局組件定義 Vue.component
,建議使用短橫線命名法。
Prop
名稱聲明期間應始終使用 camelCase(駝峯命名法),但模板中使用 kebab-case(短橫線命名法)遵循每種語言的約定:JavaScript (駝峯命名法)和HTML(短橫線命名法),這使 prop
在 js 文件中使用駝峯命名法聲明而且在 HTML 中使用短橫線命名法具備了意義。
這看起來彷佛很乏味,可是在整個項目中查找組件和建立新的組件時,對整個項目中的組件的全部選項遵循相同的順序會頗有幫助。
VueJs約定能夠在樣式指南中找到。
這是一個性能殺手,列表越大,這種不良實踐將使更多性能受到影響。 讓咱們用代碼來解釋,想象一下如下狀況:
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
複製代碼
actions
和 getters
裏面使用選擇器咱們之因此建立選擇器,是有緣由的,它不只能夠在整個應用程序中使用,並且能夠在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...
}
複製代碼
$off
清除事件監聽器watch
和 created
中調用同一個事件v-for
循環中使用 :key
$_
前綴mixin
中使用的內容應被限制在 mixin
中Prop
名稱聲明期間應始終使用 camelCase(駝峯命名法),但模板中使用 kebab-case(短橫線命名法)Actions
必須有返回值actions
和 getters
裏面使用選擇器