常常使用 element-ui 的小伙伴应该对 el-table
组件很是熟悉,一般它长下面这个样子:vue
<template>
<el-table :data="tableData">
<el-table-column
prop="date"
label="日期">
</el-table-column>
<el-table-column
prop="name"
label="姓名">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template>
<script>
export default {
data () {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}]
}
}
}
</script>复制代码
上面代码很是正确,但总觉的少了点什么?element-ui
没错,模版中 el-table-column
几乎一致,重复写了数组
下面是采用 v-for
的版本,将每一列做为一个配置项传入:bash
<template>
<el-table :data="tableData">
<el-table-column
v-for="{ prop, label } in colConfigs"
:key="prop"
:prop="prop"
:label="label">
</el-table-column>
</el-table>
</template>
<script>
export default {
data () {
this.colConfigs = [
{ prop: 'date', label: '日期' },
{ prop: 'name', label: '姓名' },
{ prop: 'address', label: '地址' }
]
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}]
}
}
}
</script>复制代码
这样作的好处在于,若是想再增长一列,彻底能够不用动 template
,只须要简单的在 this.colConfigs
这个数组中增长一个配置项 { prop: 'xxx', label: 'xxx' }
便可优化
虽然这样加个配置很是简单,扩展性也比以前直接写模版好,可是若是我有一列是要渲染几个按钮,上面的方式就不起做用了ui
换句话说,咱们即想要简单的属性能够直接加个配置项渲染出来,又但愿复杂的渲染能在模版中写出来,要怎么实现呢?this
咱们先来看一下封装的组件 my-table
:spa
// my-table.vue
<template>
<el-table :data="data">
<template v-for="colConfig in colConfigs">
<slot v-if="colConfig.slot" :name="colConfig.slot">
<el-table-column v-bind="colConfig"></el-table-column>
</template>
</el-table>
</template>
<script>
export default {
props: ['colConfigs', 'data']
}
</script>复制代码
这个封装实际上就是把前面的 colConfigs
做为一个 prop
传入,可是跟上面例子有一点不一样的是,配置项中多了一个 slot
属性,经过这个属性,咱们就能够像文章最开始那样在模版中写了,用法以下:.net
<template>
<my-table
:data="tableData"
:col-configs="colConfigs">
<!-- slot="opt" 不能省略,须要与下面配置项中的对应 -->
<el-table-column slot="opt">
<el-button size="mini" slot-scope="{ row }">查看</el-button>
</el-table-column>
</my-table>
</template>
<script>
export default {
data () {
this.colConfigs = [
{ prop: 'date', label: '日期' },
{ prop: 'name', label: '姓名' },
{ prop: 'address', label: '地址' },
// 模版中的元素须要对应的有 slot="opt" 属性
{ slot: 'opt' }
]
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}]
}
}
}
</script>复制代码
如今咱们想要增长一个列,只要加个配置项,或者加个 slot ,完美~code
等等,假设个人 table 中有几列渲染比较复杂,那几列又都比较类似,像下面这种:
<template>
<my-table
:data="tableData"
:col-configs="colConfigs">
<el-table-column label="变化" slot="change">
<span :slot-scope="row">
{{ row['change'] > 0 ? '+' + row['change']: row['change'] }}
</span>
</el-table-column>
<el-table-column label="趋势" slot="trend">
<span :slot-scope="row">
{{ row['trend'] > 0 ? '+' + row['trend']: row['trend'] }}
</span>
</el-table-column>
</my-table>
</template>复制代码
又重复写模版了...
咱们能够为配置项再增长一个属性 component
, 用户能够指定 component
属性来特殊处理某列,实现以下:
// my-table.vue
<template>
<el-table :data="data">
<template v-for="colConfig in colConfigs">
<slot v-if="colConfig.slot" :name="colConfig.slot">
<component
v-else-if="colConfig.component"
:is="config.component"
:col-config="colConfig">
</component>
<el-table-column v-else v-bind="colConfig"></el-table-column>
</template>
</el-table>
</template>
<script>
export default {
props: ['colConfigs', 'data']
}
</script>复制代码
而后上面的例子就能够改写成:
<template>
<my-table
:data="tableData"
:col-configs="colConfigs">
</my-table>
</template>
<script>
const PrefixPlusText = {
props: ['colConfig'],
template: `
<el-table-column :label="colConfig.label">
<span :slot-scope="{ row }">
{{ parseInt(row[colConfig.prop]) > 0 ? '+' + row[colConfig.prop] : row[colConfig.prop] }}
</span>
</el-table-column>
`
}
export default {
data () {
this.colConfigs = [
{ prop: 'change', label: '变化' component: PrefixPlusText },
{ prop: 'name', label: '趋势', component: PrefixPlusText },
]
return {
tableData: [{
change: '12%',
trend: '10% }, { change: '-12%', trend: '-10%' }] } } } </script>复制代码
table 做为数据展现组件,在平常开发中常常被用到,经过这篇文章,能够看到结合 vue
的 slot/component
特性,作一层封装,能够大大简化 table 的使用,大部分时候只需写一个配置属性就能够了。
最后给一个小 demo