曾經(jīng),我在封裝ui庫的組件時都是這樣的:

然后為了能夠使代碼更簡潔,同時能在父組件隨意傳入自定義的屬性,我設想過使用jsx,因為我見過公司有react項目,里面使用了擴展運算符來傳入元素的屬性,可惜當時試了一下在vue的render里面這么用結果失敗了。直到今天我在瀏覽文章的時候偶然發(fā)現(xiàn)了一個在vue里面我從未使用過的知識點:inheritAttrs,官方文檔上是這樣介紹的:
如果你不希望組件的根元素繼承 attribute,你可以在組件的選項中設置 inheritAttrs: false...這尤其適合配合實例的$attrsproperty使用,該 property 包含了傳遞給一個組件的 attribute 名和 attribute 值,有了 inheritAttrs: false 和 $attrs,你就可以手動決定這些 attribute 會被賦予哪個元素。
之后我查閱資料發(fā)現(xiàn)簡單來說就是通過設置inheritAttrs: false使得最終的html元素不會繼承父組件傳入的屬性,然后再給子組件設置v-bind直接綁定父組件傳入的屬性,這樣就可以做到父組件的屬性直接綁定到ui庫組件上,而不需要在子組件中周轉一下,另外在子組件上使用v-on="$listeners"也可以將ui組件的事件直接傳入父組件,這樣一來二去代碼可以說是簡潔多了。
附上基于iview二次封裝的table組件的基礎代碼
<template>
<Table
:data="data"
:loading="status.loading"
v-bind="customAttrs"
v-on="$listeners"
>
</Table>
</template>
<script>
export default {
name: 'BaseTable',
inheritAttrs: false,
props: {
data: {
type: Array,
default: () => []
},
// table的props 以及其它自定義屬性
config: {
type: Object,
default: () => {
return {
tableProps: {}, // iview-table的屬性放入此對象(剔除了data和一些狀態(tài)屬性如loading)
};
}
},
status: {
type: Object,
default: () => {
return {
loading: false
};
}
}
},
data() {
return {
};
},
computed: {
// 獲取從父組件直接傳入iview的屬性
customAttrs() {
return {
...this.config.tableProps
};
},
},
};
</script>
父組件調用這個組件之后只需在config.tableProps中按照ui庫的文檔寫上自己的屬性即可,另外我將loading狀態(tài)和data單獨抽離便于管理,然后ui組件的事件直接在父組件上監(jiān)聽就行。
之后我在此封裝的基礎上又過濾出了自定義列模板的項并進行處理,完整代碼見
https://github.com/dwtom/vue2x-playground
其中的views/iview/TableComponent就是了。