看了老外的一篇關於組件開發的建議(強烈建議閱讀英文原版),感受不錯翻譯一下加深理解。javascript
這篇文章制定一個統一的規則來開發你的vue程序,以致於達到一下目的。
1.讓開發者和開發團隊更容易發現一些事情。
2.讓你更好的利用你的IDE.
3.讓你更加容易的使用打包工具
4.讓你的代碼更容易碎片化以達到複用的目的。css
用一些功能單一的小模塊來組織你的應用html
對於你本身和你團隊的人來講較小的模塊更容易看懂 維護 複用和調試。vue
每一個組件應該保持單一 獨立 可複用 可測試
把你很大的組件拆分紅功能單一的小組件,儘可能不讓一個組件的代碼超過100行,保持組件獨立。最好是寫個組件應用的小demojava
組件命名應該聽從如下幾點原則jquery
vue組件也應該遵循如下原則git
<!-- 建議這樣 --> <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。當着這些js頗有效,可是也很複雜。所以你應該保持行內表達式簡潔github
把複雜的語法移動到methods或者計算屬性中api
<!-- recommended --> <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> <!-- avoid --> <template> <h1> {{ `${(new Date()).getUTCFullYear()}-${('0' + ((new Date()).getUTCMonth()+1)).slice(-2)}` }} </h1> </template>
儘管vue支持經過props傳遞複雜的object,可是你要儘可能保持props傳遞的數據簡單,儘可能只傳遞基本數據類型(strings, numbers, booleans)app
vue component 只傳遞簡單數據類型或者函數以下
<!-- recommended --> <range-slider :values="[10, 20]" min="0" max="100" step="5" :on-slide="updateInputs" :on-end="updateResults"> </range-slider> <!-- avoid --> <range-slider :config="complexConfigObject"></range-slider>
vue 組件中props就是api,健壯且可預測的api讓別人更容易使用你的組件
組件的props經過html屬性來編寫,這些值能夠是vue的簡答字符串(:attr="value" or v-bind:attr="value")也能夠不寫。你應該對props作一些限制
對props作一些限制保證你的組件正常工做,即便別人沒有按照你預想的方式調用你的組件。
<template> <input type="range" v-model="value" :max="max" :min="min"> </template> <script type="text/javascript"> export default { props: { max: { type: Number, // [1*] This will validate the 'max' prop to be a Number. default() { return 10; }, }, min: { type: Number, default() { return 0; }, }, value: { type: Number, default() { return 4; }, }, }, }; </script>
在組件內部上下文中,this指的是vue組件實例,所以在其餘上下文中使用它的時候保證'this'在組件中可使用
換句話說,不要這樣寫 const self = this;
this
分配給會改變名字的組件,告訴開發者this是一個組件實例。讓你的組件代碼按照必定的順序編寫
name
屬性,這樣再使用vue devtools時便於開發測試。<template lang="html"> <div class="Ranger__Wrapper"> <!-- ... --> </div> </template> <script type="text/javascript"> export default { // Do not forget this little guy name: 'RangeSlider', // compose new components extends: {}, // component properties/variables props: { bar: {}, // Alphabetized foo: {}, fooBar: {}, }, // variables data() {}, computed: {}, // when component uses other components components: {}, // methods watch: {}, methods: {}, // component Lifecycle hooks beforeCreate() {}, mounted() {}, }; </script> <style scoped> .Ranger__Wrapper { /* ... */ } </style>
vue提供的vue處理函數和表達式是嚴格綁定在vm上的。每一個組件事件應該遵循一個良好的命名規範從而避免開發中出現的問題。
vue支持組件嵌套,子組件得到父組件上下文,可是得到外部上下文違反了組件獨立的規定,全部不要使用this.$patent
this.$refs
vue 支持組件經過 this.$refs
來得到組件或者dom元素的上下文,大部分狀況下這中用法應該被禁止。當你用他的時候也應該謹慎防止錯誤的組件api。
this.$refs
this.$refs
是比jquery和document.getElement*
好一些的選擇<!-- good, no need for ref --> <range :max="max" :min="min" @current-value="currentValue" :step="1"></range>
<!-- good example of when to use 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>
<!-- avoid accessing something that could be emitted --> <template> <range :max="max" :min="min" ref="range" :step="1"></range> </template> <script> export default { // ... methods: { getRangeCurrentValue() { return this.$refs.range.currentValue; }, }, // ... }; </script>
vue 組件的名字做爲css根做用域類名是極好的。
把組件名做爲css命名空間依賴BEM和OOCSS(面向對象css)。在style標籤上加scoped。加了scoped告訴vue在編譯時給每一個類名都加一個後綴,從而避免污染其他組件或者全局樣式。
<style scoped> /* recommended */ .MyExample { } .MyExample li { } .MyExample__item { } /* avoid */ .My-Example { } /* not scoped to component or module name, not BEM compliant */ </style>
一個vue實例經過實例化應用中的組件而來。這個實例經過組件屬性配置而來。若是組件要提供給其餘開發者使用,這些定製的屬性也就是組件的api應該寫在readme.md中。
README.md
是一個文檔應該先被閱讀的。github等代碼倉庫經過README.md 來展現代碼內容給一個組件增長README.md
range-slider/ ├── range-slider.vue ├── range-slider.less └── README.md
其他還包括給你的組件寫小demo,對組件作eslint代碼審查。。