原文地址: Vue.js best practices ✓ – Noteworthy - The Journal Blog
原文做者: Riccardo Polacci
譯者: amandakelake
各位開發小夥伴們好! javascript
通過一段時間對VueJs官方文檔以及網上其餘相關vue資源的研究,我整理了一份最佳實踐和樣式指南列表,方便你們寫出更正確、更容易讓小夥伴接受的vue代碼。 html
如下有幾點是一些功能/優化相關,其餘是VueJs命名約定和元素排序相關。更多詳細信息能夠直接到最下方的總結中查看。
vue
當咱們使用$on
進行事件監聽時,要記住在destroyed()
鉤子中用$off
移除事件監聽,能夠有效防止內存泄漏。
java
觸發/監聽自定義事件時,應該始終使用短橫線分隔。爲何呢?由於不管如何最後事件名都會被自動轉換爲短橫線分隔的形式。咱們不該該用駝峯命名或者首字母大寫的形式給監聽事件命名,而是使用一種更清晰有意義的方式來聲明一個事件:短橫線分隔git
// Emitting
this.$emit('my-event') // instead of myEvent
// Listening
v-on:my-event
複製代碼
若是咱們須要在組件初始化以及偵聽屬性變化時調用同一個方法,一般的作法像下面這樣
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裏面聲明瞭
}
}
},
複製代碼
最多見的作法是始終在模板循環中添加:key
鍵。沒有:key
鍵的v-for
循環在錯誤定位的時候比較麻煩,特別是動畫相關
bash
Mixins
在代碼複用上是個不錯的方法,它能夠將重複代碼組合成一個單獨的模塊,而後按需引入。可是(極大可能),會出現一些問題。下面,咱們重點解決屬性名重複衝突的問題。框架
當咱們將mixin
混入組件時,也就是將mixin
內的代碼與組件自身的代碼進行合併,若是碰到同名屬性,會發生什麼?組件優先級更高,組件屬性的優先級天然更高。async
若是我想讓mixin
代碼的優先級更高,應該怎麼辦?咱們沒法分配優先級,但能夠經過正確的命名規範來避免屬性重疊或者覆蓋。
爲了區分mixin
屬性和組件的屬性,咱們一般使用`$_`做爲屬性前綴,爲何呢?主要有下面幾個緣由:
_
前綴來定義其自身的私有屬性$
是Vue生態系統暴露給用戶的特殊實例屬性 在風格指南 — Vue.js中,他們建議像這樣給mixin
添加屬性名稱:$_myMixin_updateUser
相對於可讀性,我發現給mixin
添加名稱有時候也會產生一些混淆。但這也取決於mixin
自己代碼,特殊狀況或者開發人員自己。
經過添加一個簡單的$_
,就像$_updateUser
同樣,代碼更具可讀性,能夠輕鬆分辨出組件私有屬性和mixin
的屬性。
繼mixin
上一點,還有另外一點要注意的。
假設咱們建立了一個mixin
,它使用了this.language
屬性,但這個屬性並非在mixin
內部定義或獲取的,那麼混入了這個mixin
的組件就必須包含這個language
屬性。
正如你已經知道的,這很是容易出錯。爲了提早避免錯誤的發生,mixin
內使用到的屬性或者方法最好只在mixin
內部定義獲取。沒必要擔憂重複獲取屬性的問題,由於VueJs在這點上很聰明,若是檢測到重複讀取屬性,將會自動處理(大部分狀況下是直接從Vuex裏直接讀取)。
編輯器對首字母大寫命名的集成度更好,對在經常使用IDE中實現自動完成/導入功能更友好。
若是咱們想要避免文件系統大小寫不敏感的問題,那麼最好選擇短橫線分隔
對於展現組件、純組件,應該給它們加上前綴,以區別於其餘的非純組件。這能夠大大提升項目可讀性,提升團隊協同開發體驗。
在JavaScript中,類和原型構造函數有默認約定使用首字母大寫命名,在Vue組件中使用首字母大寫命名有相同的意義。 若是咱們只經過`Vue.component`使用全局組件定義,建議使用短橫線分隔命名
遵循每種語言的慣例:JavaScript(駝峯)和HTML(短橫線分割),在JS中定義prop
時用駝峯命名,在HTML中用於短橫線分割命名。
這樣作可能看起來有點死板,可是在整個項目中對組件的全部選項執行相同的順序,在查找內容和建立新組件時有很大幫助。
VueJs樣式指南能夠查看這裏風格指南 — Vue.js
這種作法堪稱性能殺手,列表數據越大,這種作法對性能的影響越大。
用代碼來看下問題吧,看如下場景:
<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`的同一元素)
這跟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
複製代碼
建立選擇器時,不單只是在應用邏輯中使用,還要在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...
}
複製代碼
v-for
循環中使用key
$_
做爲mixins
的私有屬性前綴mixin
中使用的方法或者屬性應該直接在mixin
中讀取prop
名時使用駝峯命名,但在模板中應使用短橫線分隔命名v-for
的同一元素上使用v-if
Actions
必須有返回值actions
和getters
中使用選擇器這篇文章是由多個在同一項目中使用VueJs的開發人員合做完成的,遵循這份樣式指南和最佳實踐有助於讓每一個新開發人員都能儘快熟悉並上手項目代碼。
若是你有什麼意見或者更好的提議,歡迎隨時評論。