本規範提供了一種統一的編碼規範來編寫 Vue.js 代碼。這使得代碼具備以下的特性:javascript
本指南爲 De Voorhoede 參考 RiotJS 編碼規範 而寫。css
this
賦值給 component
變量始終基於模塊的方式來構建你的 app,每個子模塊只作一件事情。html
Vue.js 的設計初衷就是幫助開發者更好的開發界面模塊。一個模塊是應用程序中獨立的一個部分。vue
每個 Vue 組件(等同於模塊)首先必須專一於解決一個 單一的問題 , 獨立的 , 可複用的 , 微小的 and 可測試的 。java
若是你的組件作了太多的事或是變得臃腫,請將其拆分紅更小的組件並保持單一的原則。通常來講,儘可能保證每個文件的代碼行數不要超過 100 行。也請保證組件可獨立的運行。比較好的作法是增長一個單獨的 demo 示例。nginx
組件的命名需聽從如下原則:git
同時還須要注意:github
app-
前綴做爲命名空間 : 若是很是通用的話可以使用一個單詞來命名,這樣能夠方便於其它項目裏複用。<!-- 推薦 -->
<app-header></app-header> <user-list></user-list> <range-slider></range-slider> <!-- 避免 --> <btn-group></btn-group> <!-- 雖然簡短可是可讀性差. 使用 `button-group` 替代 --> <ui-slider></ui-slider> <!-- ui 前綴太過於寬泛,在這裏意義不明確 --> <slider></slider> <!-- 與自定義元素規範不兼容 -->
Vue.js 的表達式是 100% 的 Javascript 表達式。這使得其功能性很強大,但也帶來潛在的複雜性。所以,你應該儘可能 保持表達式的簡單化 。vue-cli
若是你發現寫了太多複雜並難以閱讀的行內表達式,那麼可使用 method 或是 computed 屬性來替代其功能。django
<!-- 推薦 --> <template> <h1> {{ `${year}-${month}` }} </h1> </template> <script type="text/javascript"> export default { computed: { month() { return this.twoDigits((new Date()).getUTCMonth() + 1); }, year() { return (new Date()).getUTCFullYear(); } }, methods: { twoDigits(num) { return ('0' + num).slice(-2); } }, }; </script> <!-- 避免 --> <template> <h1> {{ `${(new Date()).getUTCFullYear()}-${('0' + ((new Date()).getUTCMonth()+1)).slice(-2)}` }} </h1> </template>
雖然 Vue.js 支持傳遞複雜的 JavaScript 對象經過 props 屬性,可是你應該儘量的使用原始類型的數據。儘可能只使用 JavaScript 原始類型 (字符串、數字、布爾值) 和 函數。儘可能避免複雜的對象。
組件的每個屬性單獨使用一個 props,而且使用函數或是原始類型的值。
<!-- 推薦 -->
<range-slider :values="[10, 20]" min="0" max="100" step="5" :on-slide="updateInputs" :on-end="updateResults"> </range-slider> <!-- 避免 --> <range-slider :config="complexConfigObject"></range-slider>
在 Vue.js 中,組件的 props 即 API,一個穩定並可預測的 API 會使得你的組件更容易被其餘開發者使用。
組件 props 經過自定義標籤的屬性來傳遞。屬性的值能夠是 Vue.js 字符串( :attr="value"
或v-bind:attr="value"
)或是不傳。你須要保證組件的 props 能應對不一樣的狀況。
驗證組件 props 能夠保證你的組件永遠是可用的(防護性編程)。即便其餘開發者並未按照你預想的方法使用時也不會出錯。
type
屬性 校驗類型<template> <input type="range" v-model="value" :max="max" :min="min"> </template> <script type="text/javascript"> export default { props: { max: { type: Number, // 這裏添加了數字類型的校驗 default() { return 10; }, }, min: { type: Number, default() { return 0; }, }, value: { type: Number, default() { return 4; }, }, }, }; </script>
this
賦值給 component
變量(在 Vue.js 組件上下文中, this
指向了組件實例。所以當你切換到了不一樣的上下文時,要確保this
指向一個可用的 component
變量。
換句話說,不要在編寫這樣的代碼 const self = this;
,而是應該直接使用變量 component
。
this
賦值給變量 component
可用讓開發者清楚的知道任何一個被使用的地方,它表明的是組件實例。<script type="text/javascript"> export default { methods: { hello() { return 'hello'; }, printHello() { console.log(this.hello()); }, }, }; </script> <!-- 避免 --> <script type="text/javascript"> export default { methods: { hello() { return 'hello'; }, printHello() { const self = this; // 沒有必要 console.log(self.hello()); }, }, }; </script>
按照必定的結構組織,使得組件便於理解。
name
屬性。藉助於 vue devtools 可讓你更方便的測試組件結構化
<template lang="html"> <div class="Ranger__Wrapper"> <!-- ... --> </div> </template> <script type="text/javascript"> export default { // 不要忘記了 name 屬性 name: 'RangeSlider', // 組合其它組件 extends: {}, // 組件屬性、變量 props: { bar: {}, // 按字母順序 foo: {}, fooBar: {}, }, // 變量 data() {}, computed: {}, // 使用其它組件 components: {}, // 方法 watch: {}, methods: {}, // 生命週期函數 beforeCreate() {}, mounted() {}, }; </script> <style scoped> .Ranger__Wrapper { /* ... */ } </style>
Vue.js 提供的處理函數和表達式都是綁定在 ViewModel 上的,組件的每個事件都應該按照一個好的命名規範來,這樣能夠避免很多的開發問題,具體可見以下 ** 爲何**。
Vue.js 支持組件嵌套,而且子組件可訪問父組件的上下文。訪問組件以外的上下文違反了 基於模塊開發 的 第一原則 。所以你應該儘可能避免使用 this.$parent
。
Vue.js 支持經過 ref
屬性來訪問其它組件和 HTML 元素。並經過 this.$refs
能夠獲得組件或 HTML 元素的上下文。在大多數狀況下,經過 this.$refs
來訪問其它組件的上下文是能夠避免的。在使用的的時候你須要注意避免調用了不恰當的組件 API,因此應該儘可能避免使用 this.$refs
。
this.$refs
來實現。this..$ref
而不是 JQuery
, document.getElement*
, document.queryElement
。<!-- 推薦,並未使用 this.$refs -->
<range :max="max" :min="min" @current-value="currentValue" :step="1"></range>
<!-- 使用 this.$refs 的適用狀況-->
<modal ref="basicModal"> <h4>Basic Modal</h4> <button class="primary" @click="$refs.basicModal.close()">Close</button> </modal> <button @click="$refs.basicModal.open()">Open modal</button> <!-- Modal component --> <template> <div v-show="active"> <!-- ... --> </div> </template> <script> export default { // ... data() { return { active: false, }; }, methods: { open() { this.active = true; }, hide() { this.active = false; }, }, // ... }; </script>
<!-- 若是可經過 emited 來作則避免經過 this.$refs 直接訪問 -->
<template> <range :max="max" :min="min" ref="range" :step="1"></range> </template> <script> export default { // ... methods: { getRangeCurrentValue() { return this.$refs.range.currentValue; }, }, // ... }; </script>
Vue.js 的組件是自定義元素,這很是適合用來做爲樣式的根做用域空間。能夠將組件名做爲 css 類的命名空間。
使用組件名做爲樣式命名的前綴,可基於 BEM 或 OOCSS 範式。同時給style標籤加上 scoped 屬性。加上 scoped 屬性編譯後會給組件的 class 自動加上惟一的前綴從而避免樣式的衝突。
<style scoped> /* 推薦 */ .MyExample { } .MyExample li { } .MyExample__item { } /* 避免 */ .My-Example { } /* not scoped to component or module name, not BEM compliant */ </style>
使用 Vue.js 組件的過程當中會建立 Vue 組件實例,這個實例是經過自定義屬性配置的。爲了便於其餘開發者使用該組件,對於這些自定義屬性即組件API應該在 README.md
文件中進行說明。
README.md
是標準的咱們應該首先閱讀的文檔文件。代碼託管網站 (github/bitbucket/gitlab 等) 會默認在倉庫中展現 該文件做爲倉庫的介紹。在模塊目錄中添加 README.md
文件:
range-slider/
├── range-slider.vue ├── range-slider.less └── README.md
在 README 文件中說明模塊的功能以及使用場景。對於 vue 組件來講,比較有用的描述是組件的自定義屬性即 API 的描述介紹。
range slider 組件可經過拖動的方式來設置一個給定範圍內的數值。
該模塊使用 noUiSlider 來實現誇瀏覽器和 touch 功能的支持。
<range-slider>
支持以下的自定義屬性:
attribute | type | description |
---|---|---|
min |
Number | 可拖動的最小值. |
max |
Number | 可拖動的最大值. |
values |
Number[] optional | 包含最大值和最小值的數組. 如. values="[10, 20]" . Defaults to [opts.min, opts.max] . |
step |
Number optional | 增長減少的數值單位,默認爲 1. |
on-slide |
Function optional | 用戶拖動開始按鈕或者結束按鈕時的回調函數,函數接受 (values, HANDLE) 格式的參數。 如: on-slide={ updateInputs } , component.updateInputs = (values, HANDLE) => { const value = values[HANDLE]; } . |
on-end |
Function optional | 當用戶中止拖動時觸發的回調函數,函數接受 (values, HANDLE) 格式的參數。 |
如須要自定義 slider 的樣式可參考 noUiSlider 文檔
添加 index.html
文件做爲組件的 demo 示例,並提供不一樣配置狀況的效果,說明組件是如何使用的。
代碼校驗能夠保持代碼的統一性以及追蹤語法錯誤。.vue 文件能夠經過使用 eslint-plugin-html
插件來校驗代碼。你能夠經過 vue-cli
來開始你的項目, vue-cli
默認會開啓代碼校驗功能。
爲了校驗工具可以校驗 *.vue
文件,你須要將代碼編寫在 <script>
標籤中,並使,由於校驗工具沒法理解行內表達式,配置校驗工具能夠訪問全局變量 vue
和組件的 props
。
ESLint 須要經過 ESLint HTML 插件 來抽取組件中的代碼。
經過 .eslintrc
文件來配置 ESlint,這樣 IED 能夠更好的理解校驗配置項。 ESlint,這樣.
{
"extends": "eslint:recommended", "plugins": ["html"], "env": { "browser": true }, "globals": { "opts": true, "vue": true } }
運行 ESLint
eslint src/**/*.vue
JSHint 能夠解析 HTML (使用 --extra-ext
命令參數) 和 抽取代碼(使用 --extract=auto
命令參數).
經過 .jshintrc
文件來配置 ESlint,這樣 IED 能夠更好的理解校驗配置項。
{
"browser": true, "predef": ["opts", "vue"] }
運行 JSHint
jshint --config modules/.jshintrc --extra-ext=html --extract=auto modules/
注:JSHint 不接受 vue
擴展名的文件,只支持 html
。
本人demo地址: