如何優雅的封裝vue元件
在編寫元件時,最好考慮好以後是否要進行復用。一次性元件間有緊密的耦合沒關係,但是可複用元件應當定義一個清晰的公開介面,同時也不要對其使用的外層資料作出任何假設。 Vue 元件的 API 來自三部分——prop、事件和插槽:
- Prop 允許外部環境傳遞資料給元件;
- 事件允許從元件內觸發外部環境的副作用;
- 插槽允許外部環境將額外的內容組合在元件中。
在開發過程中,結合 Vue 元件化的特性,開發通用元件是很基礎且重要的工作。通用元件必須具備==高效能、低耦合==的特性。
props(資料從父元件傳入)
通常的props是這樣定義的:
props:['data','type','state']
複製程式碼
但是通用元件的的應用場景比較複雜,對 props 傳遞的引數應該新增一些驗證規則
props:{
data:{
type: Array,
required: true
},
type: [String, Number],
state: {
type: Boolean,
default: false
}
}
複製程式碼
對於通過 props 傳入的引數,不建議對其進行操作,因為會同時修改父元件裡面的資料
// vue2.5已經針對 props 做出優化,這個問題已經不存在了
如果一定需要有這樣的操作,可以這麼寫:
let myData = JSON.stringify(this.data);
myData = JSON.parse(myData);
複製程式碼
為什麼不直接寫 let myData = this.data 呢?
因為直接賦值,並不能解除雙向繫結。改變 myData 的時候,會改變 this.data,父元件的 data 也會變
而通過 JSON 轉換之後,就能任性的操作了
在父元件處理事件
在通用元件中,通常會需要有各種事件, 比如核取方塊的 change 事件,或者元件中某個按鈕的 click 事件
這些事件的處理方法應當儘量放到父元件中,通用元件本身只作為一箇中轉
//子元件中的方法
hanleSubmit (data) {
this.$emit('submit', data);
}
複製程式碼
//在父元件中處理
<child-form @sumit='parentSubmit'></child-form>
複製程式碼
這樣既降低了耦合性,也保證了通用元件中的資料不被汙染
不過,並不是所有的事件都放到父元件處理
比如元件內部的一些互動行為,或者處理的資料只在元件內部傳遞,這時候就不需要用 $emit 了
使用插槽slot實現內容分發
一個通用元件,往往不能夠完美的適應所有應用場景
所以在封裝元件的時候,只需要完成元件 80% 的功能,剩下的 20% 讓父元件通過 solt 解決
比如一個彈框元件,彈框下班的操作按鈕,有可能是‘取消’,‘確定’,可能是‘重置’,‘提交’....按鈕的事件操作也不一樣,這種場景就適合用內容分發了。
// 子元件
<div class='modal'>
<h3>標題</h3>
<div class='con'>
.......
</div>
<div class='act-group'>
<slot name='buttonGroup'></slot>
</div>
</div>
複製程式碼
// 父元件
<modal>
<div slot='buttonGroup'>
<button>取消</button>
<button>確定</button>
</div>
</modal>
複製程式碼