原由:
在使用 element-ui table組件時,因爲表列比較多一個個寫特別麻煩,因此想經過將全部表頭定義成一個數組,經過遍歷多方式去實現。這樣解決了手寫不少 el-table-column 的狀況。
障礙:
相似於下面自定義表列的樣式,它是經過 slot-scope 去覆蓋 el-table-column 內部slot的樣式實現的。那咱們在遍歷表頭數組的時候如何實現呢? html
demo:
codepen demo地址react
const columns = [
{
title: 'Name',
dataIndex: 'name',
render: (text, row, index) => {
if (index < 4) {
return <a>{text}</a>;
}
return {
children: <a>{text}</a>,
props: {
colSpan: 5,
},
};
},
}]
const const data = [
{
key: '1',
name: 'John Brown',
age: 32,
tel: '0571-22098909',
phone: 18889898989,
address: 'New York No. 1 Lake Park',
}]
ReactDOM.render(<Table columns={columns} dataSource={data} bordered />, mountNode);
複製代碼
接下來咱們要實現下圖的table的樣式,可是這一次咱們採用 render 傳參數的方式element-ui
有了上面的思路,去實現子組件。咱們須要知道一點,每一個 el-table-column 只是定義了一列的表頭和數據,而 :data="tableList" 中的每項值是定義了一行的數據。因此 el-table-column 是按列來分,data 是按行來分數組
<template>
<el-table :data="tableList" style="width:500px">
<template v-for="item in propList">
<slot :content="item">
<el-table-column :key="item.id" :prop="item.prop" :label="item.label"></el-table-column>
</slot>
</template>
</el-table>
</template>
<script>
export default {
props:{
propList:{
type:Array,
default:()=>[]
},
tableList:{
type:Array,
default:()=>[]
},
}
}
</script>
複製代碼
父組件經過 slot-scope 來接受到子組件傳遞過來的數據,而後判斷是否有 render 屬性來肯定是否用要去自定義樣式覆蓋默認的 slotbash
首先看傳遞給子組件的表頭數據,能夠看到,第二,三行列表中有一個render屬性,它是一個函數並返回一個 html 的字符串。babel
tableList就是普通的數據,也就是數據的 key 值去渲染對應的數據antd
圖片這列舉例子,當父組件經過 props 將 {label,prop,id,render} 傳遞給子組件後,子組件有經過 slot 將值傳遞迴父組件。antdesign
爲何這裏有兩個 slot-scope ,第一個是 slot-item 的,組件內部經過 slot-scope 將值傳遞出來。而第二個是 el-table-item 的,ui組件內部一樣將數據經過 slot-scope 傳遞傳來。函數
經過第一個 slot-scope 拿到 propList 中的定義的 render 函數,經過第二個 slot-scope 拿到 table 組件內部傳遞出來的數據,將數據傳遞給 render 函數去生成自定義模版post
最終經過 v-html 去解析生成的字符串模版
<slot-item :propList="propList" :tableList="tableList">
<template slot-scope="{content}" v-if="content.render">
<el-table-column :label="content.label">
<template slot-scope="{$index,row}">
<div v-html="content.render(row)"></div>
</template>
</el-table-column>
</template>
</slot-item>
export default {
components:{
SlotItem
},
data () {
return {
propList:[
{label:'姓名',prop:'name',id:1},
{label:'圖片',prop:'pic',id:2,render:({pic})=>{
return `<img style="width:30px;height:30px" src='${pic}' />`
}},
{label:'操做',prop:'operate',id:3,render:({text})=>{
return `<div style="color:#999">${text}</div>`
}},
],
tableList:[
{name:'章三',pic:'https://zh-static-files.oss-cn-hangzhou.aliyuncs.com//karazhan/content/poster/2019/11/16e30c192f6.png',text:'新增'},
{name:'里斯',pic:'https://zh-static-files.oss-cn-hangzhou.aliyuncs.com//karazhan/content/poster/2019/11/16e30c2797e.png',text:'刪除'},
{name:'網舞',pic:'https://zh-static-files.oss-cn-hangzhou.aliyuncs.com//karazhan/content/poster/2019/11/16e30c33144.png',text:'跳轉'},
]
}
}
}
</script>
複製代碼
有了render屬性,能夠想 ant-design 那樣簡潔的屬性 ui組件模版了!