ElementUI是所有Vue組件庫中比較優(yōu)秀的一個杨赤,至今已經(jīng)在github收獲了44.3k個star茧痕,公司幾乎所有的Vue項目都是使用ElementUI作為基礎組件庫,其豐富的組件足以應付大部分交互場景恼除,但是碰到特殊的需求組件庫內(nèi)的組件沒法滿足應用場景我們該怎么辦呢踪旷?這個時候就需要我們動手擴展當前的組件庫來滿足我們的應用場景。
擴展組件庫可能遇到的問題
試想這樣一個場景豁辉,現(xiàn)在項目中要用到日期范圍組件令野,要求開始日期和結束日期可以分別選擇,并且能夠?qū)δ承┤掌谶M行禁用徽级,組件庫里面并沒有這樣的組件气破,你會怎樣實現(xiàn)這樣的需求?
- 實現(xiàn)這樣一個表單控件餐抢,如何進行表單的驗證现使?
你需要從element-ui/src/mixins/emitter
引入Emitter這個事件分發(fā)的mixin,當值變化的時候調(diào)用this.dispatch("ElFormItem", "el.form.change", value)
來觸發(fā)表單的校驗 - 組件原有的屬性我該如何在新的組件上繼承使用旷痕?
這個涉及到組件的屬性值穿透問題碳锈,Vue給我們提供了$attrs,在實際使用過程中欺抗,有些屬性我們并不想從父級作用域傳遞下來售碳,這時候你可以聲明一個計算屬性,對$attrs進行處理绞呈,刪除或者增加你想要的屬性 - 組件原有的事件偵聽器我該如何在新的組件上繼承使用贸人?
Vue給我們提供了$listeners,在用法上和屬性基本一致 - 想讓我們封裝的組件支持v-model命令該怎么做呢佃声?
可以設置model: { prop: 'value', event: 'change' },
當你調(diào)用this.$emit('change',value)
的時候艺智,value的值就會被改變,你可以watch這個value屬性秉溉,當值發(fā)生變化的時候力惯,對當前組件的data進行一些操作來滿足一些需求 - 開發(fā)過程中需要表單組件的一些屬性該怎么辦?
如果你看過Form組件的源碼召嘶,你會發(fā)現(xiàn)它使用了Vue的provide
,inject
屬性父晶,對于多層級嵌套的組件,這兩個屬性是很有用的弄跌,可以完成跨多層級的值傳遞甲喝,在我們自己的組件上,下面這段代碼展示了inject有哪些用處 - 有些時候我們開發(fā)的組件有層級關系铛只,跨組件通信怎么搞定埠胖?
如果我們自定義的組件相互之間有層級嵌套關系糠溜,可能以slot的形式嵌套,那么除了給組件設置name屬性之外直撤,還需要設置componentName非竿,這個屬性是為了使用broadcast 和 dispatch
方法來通信用的
export default {
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
computed: {
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
validateState() {
return this.elFormItem ? this.elFormItem.validateState : '';
},
needStatusIcon() {
return this.elForm ? this.elForm.statusIcon : false;
},
inputSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
inputDisabled() {
return this.disabled || (this.elForm || {}).disabled;
},
},
我們可以從父級組件拿到表單的狀態(tài),比如大小谋竖,是否禁用
- 如何暴露我們的組件以Vue.use的形式來使用
MyComponent.install = function(Vue,options){
Vue.component(MyComponent,MyComponent.name)
}
export default MyComponent
我們可以這樣使用
Vue.use(MyComponent,options)
結語
擴展組件開發(fā)红柱,需要特別熟悉組件的用法,有些需要深入源碼了解原理蓖乘,根據(jù)原理制定開發(fā)方案锤悄,在探索的過程中,我們會遇到很多問題嘉抒,這時可以去好好看看源碼零聚,或者去github issue列表尋找答案