Vue 有個官方的風格指南,我從中摘抄了些認爲比較重要、本身常忽略的點,加上一些分析列出來。也能夠直接去觀看風格指南: https://cn.vuejs.org/v2/style...
文件名要麼是單詞開頭大寫,要麼是橫線鏈接css
MyComponent.vue 或 my-component.vue
html
除了根組件或者佈局組件,都要加上 scoped 設置做用域,避免影響其它地方的樣式vue
v-for="user in users" v-if="user.isActive" /** 要換成 **/ v-for="user in activeUsers" computed () { return this.users.filter((item) => { return item.isActive }) } 好處: * 過濾後的列表_只_會在`users`數組發生相關變化時才被從新運算,過濾更高效。 * 使用`v-for="user in activeUsers"`以後,咱們在渲染的時候只遍歷活躍用戶,渲染更高效。 * 解耦渲染層的邏輯,可維護性 (對邏輯的更改和擴展) 更強。
v-for="user in users" v-if="shouldShowUsers" /** 要換成 **/ <ul v-if="shouldShowUsers"> <li v-for="user in users"></li> </ul> 好處: * 如上 * 經過將 v-if 移動到容器元素,咱們不會再對列表中的每一個用戶檢查 shouldShowUsers。取而代之的是,咱們只檢查它一次,且不會在 shouldShowUsers 爲否的時候運算 v-for。
prop 儘可能詳細,不使用數組方式,而是用對象列出更多選項,至少須要指定其類型。git
好處:github
prop 應當使用 駝峯命名法,而在模板和 JSX 中使用時,要用橫線鏈接(HTML 的約定)vuex
正確例子: <WelcomeMessage greeting-text="hi"/> props: { greetingText: String }
組件名始終應該是多個單詞,避免和未來的 HTML 元素相沖突,例如數組
export default { // name: 'Todo',不推薦 name: 'TodoItem' }
對於不包含全局狀態的(好比 vuex store)、展現類的、無邏輯或無狀態的基礎組件,例如 table、button、icon 等,應該都以一個特定的前綴開頭,統一風格且與其餘功能組件區分開來less
反例: components/ |- MyButton.vue |- VueTable.vue |- Icon.vue 正確例子: components/ |- BaseButton.vue |- BaseTable.vue |- BaseIcon.vue components/ |- AppButton.vue |- AppTable.vue |- AppIcon.vue components/ |- VButton.vue |- VTable.vue |- VIcon.vue
對於每一個頁面只使用一次、不接受任何 prop (即內容寫死了)的組件(例如頂部的公司 logo、底部的版權聲明),要以 The 前綴命名,以示其惟一性編輯器
反例: components/ |- Heading.vue |- MySidebar.vue 正確例子: components/ |- TheHeading.vue |- TheSidebar.vue
對於和父組件緊密耦合的子組件(即只在指定的父組件裏用到的),命名方式應該規範統一:父組件名+自己名字,由於編輯器一般會按字母順序組織文件,因此這樣作能夠把相關聯的文件排在一塊兒。ide
注意:這裏的父組件也是自定義組件
,例如自定義列表組件,其還有隻在其自己使用的自定義列表 item 子組件、自定義按鈕子組件,子組件命名要規範
如今一般作法(components 的父組件使用文件夾形式,包含 index.vue 和子組件文件夾): components/ |- TodoList/ |- Item/ |- index.vue |- Button.vue |- index.vue 或者單純是命名上類似: components/ |- TodoList.vue |- TodoItem.vue |- TodoButton.vue 正確例子: components/ |- TodoList.vue |- TodoListItem.vue |- TodoListItemButton.vue components/ |- SearchSidebar.vue |- SearchSidebarNavigation.vue
對於沒有內容的組件,在容許的狀況下要使用自閉合形式,以提醒使用者它們不只沒有內容,並且是刻意沒有內容,且代碼也更簡潔。
容許的狀況:單文件組件、字符串模板、JSX不容許的狀況:DOM 模板(一些 HTML 元素中,例如 <ul>、<ol>、<table> 和 <select>,由於 HTML 不支持自閉合的自定義元素)
反例: <!-- 在單文件組件、字符串模板和 JSX 中 --> <MyComponent></MyComponent> <!-- 在 DOM 模板中 --> <my-component/> 正確例子: <!-- 在單文件組件、字符串模板和 JSX 中 --> <MyComponent/> <!-- 在 DOM 模板中 --> <my-component></my-component>
模板中組件名的書寫方式,和文件的命名方式同樣,要麼是單詞開頭大寫,要麼是橫線鏈接,二者不該該混用
還要注意,在 DOM 模板中,不支持單詞大小寫方式
,由於 HTML 是大小寫不敏感的
正確例子: <!-- 在單文件組件和字符串模板中 --> <MyComponent/> <!-- 在 DOM 模板中 --> <my-component></my-component> 或者: <!-- 在全部地方 --> <my-component></my-component>
組件名應該用完整的單詞,而不是縮寫。不要爲了減小名字的長度而用縮寫(尤爲是不經常使用的縮寫),如今編輯器的自動補全功能已經讓寫長命名的代價很是低,而完整的命名帶來的明確理解性是很是寶貴的。
反例: components/ |- SdSettings.vue |- UProfOpts.vue 正確例子: components/ |- StudentDashboardSettings.vue |- UserProfileOptions.vue
元素的多個 attribute 應該分多行,每一個 attribute 一行,更易讀
反例: <img src="https://vuejs.org/images/logo.png" alt="Vue Logo"> <MyComponent foo="a" bar="b" baz="c"/> 正確例子: <img src="https://vuejs.org/images/logo.png" alt="Vue Logo" > <MyComponent foo="a" bar="b" baz="c" />
組件模板應該只包含簡單的表達式,複雜的表達式應該重構爲計算屬性或方法
反例: {{ fullName.split(' ').map(function (word) { return word[0].toUpperCase() + word.slice(1) }).join(' ') }} 正確例子: <!-- 在模板中 --> {{ normalizedFullName }} // 複雜表達式已經移入一個計算屬性 computed: { normalizedFullName: function () { return this.fullName.split(' ').map(function (word) { return word[0].toUpperCase() + word.slice(1) }).join(' ') } }
應該把複雜的計算屬性分割成儘量多的更簡單的計算屬性。這樣易於測試及閱讀,且在將來若是其中某一屬性須要被顯示,就不須要重構了
反例: computed: { price: function () { var basePrice = this.manufactureCost / (1 - this.profitMargin) return ( basePrice - basePrice * (this.discountPercent || 0) ) } } 正確例子: computed: { basePrice: function () { return this.manufactureCost / (1 - this.profitMargin) }, discount: function () { return this.basePrice * (this.discountPercent || 0) }, finalPrice: function () { return this.basePrice - this.discount } }
用 : 表示 v-bind:、用 @ 表示 v-on: 和用 # 表示 v-slot:,應該要麼都用要麼都不用。
在 scoped 的 scss/less/css 中,避免出現元素選擇器,要使用 class 類選擇器。
緣由:
爲了給樣式設置做用域,Vue 會爲元素添加一個獨一無二的 attribute,例如 data-v-f3f3eg9。而後修改選擇器,使得在匹配選擇器的元素中,只有帶這個 attribute 纔會真正生效 (好比 button[data-v-f3f3eg9])。問題在於大量的元素和 attribute 組合的選擇器 (好比 button[data-v-f3f3eg9]) 會比類和 attribute 組合的選擇器慢,因此應該儘量選用類選擇器。
反例: <template> <button>X</button> </template> <style scoped> button { background-color: red; } </style> 正確例子: <template> <button class="btn btn-close">X</button> </template> <style scoped> .btn-close { background-color: red; } </style>
應該優先經過 prop 和事件進行父子組件之間的通訊,而不是 this.$parent 或變動 prop。
若是一組 v-if + v-else 的元素類型相同
,最好使用 key (好比兩個 <div> 元素)。
默認狀況下,Vue 會盡量高效的更新 DOM。這意味着其在相同類型的元素之間切換時,會修補已存在的元素,而不是將舊的元素移除而後在同一位置添加一個新元素。若是本不相同的元素被識別爲相同,則會出現意料以外的結果。
以下代碼,在按鈕點擊切換時,不會觸發 transition 效果,由於它是在原本的 button 上進行修改,沒有進行移除新增操做。在這裏查看效果
反例: <transition> <button v-if="isEditing" v-on:click="isEditing = false"> Save </button> <button v-else v-on:click="isEditing = true"> Edit </button> </transition> <style> .v-enter-active, .v-leave-active { transition: all 1s; } .v-enter, .v-leave-to { opacity: 0; transform: translateY(30px); } .v-leave-active { position: absolute; } </style>
解決方法:
正確例子: <transition> <button v-if="isEditing" v-on:click="isEditing = false" key="save"> Save </button> <button v-else v-on:click="isEditing = true" key="edit"> Edit </button> </transition>