管理系统的前端项目中,表格是一个重要的功能,利用element-ui可以快速的开发。
el-table示例
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</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 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>
根据element-ui的官方demo可以快速实现一个表格,但是在实际开发中如果后续需求需要增加列,不仅要在数据中增加列的字段,还需要在html中增加<el-table-column></el-table-column>
,维护起来不太方便。
利用v-for遍历列
<el-table-column v-for="(col,index) in tableData" :key="index" :prop="col.prop" :label="col.label" :formatter="tableFormatter"></el-table-column>
tableData:[{
label: '姓名',
prop:'name'
},{
label: '性别',
prop: 'sex'
}]
利用v-for遍历可以大大简化html结构,增加新列可以只在数据中增加,而且也不影响数据的格式化
tableFormatter(row, column, cellValue){
if (column.property === 'sex') {
return cellValue === 0 ? '男' : '女'
}else{
return cellValue
}
}
但是这种方式缺点也很明显,formatter只能返回字符串,假如某列需要一个Switch
开关或者燃尽图
遍历则没有办法实现。
那么是否有一种既可以实现功能又利于维护的方式?
利用render函数和el-table的自定义列
el-table
自定义列demo
<el-table-column label="姓名" width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ scope.row.name }}</p>
<p>住址: {{ scope.row.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
如demo中的示例,el-table的自定义列使用scope传递参数,scope.row为数据,scope.$index为索引。
我们可以在列的数据中加入自定义的参数,将所有的列都视为自定义列,如果存在自定义的参数则渲染我们自定义的参数,否则让此列展示默认的数据。
封装的table组件
<template>
<el-table :data="data">
<el-table-column v-for="(col, index) in rowHeader" :key="index" :prop="col.prop" :label="col.label">
<template slot-scope="scope">
<ex-slot v-if="col.render" :render="col.render" :row="scope.row" :index="scope.$index" :column="col"></ex-slot>
<span v-else>
{{scope.row[col.prop]}}
</span>
</template>
</el-table-column>
</el-table>
</template>
<script>
// 自定义内容的组件
var exSlot = {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
}
},
render: (h, data) => {
const params = {
row: data.props.row,
index: data.props.index
}
if (data.props.column) params.column = data.props.column
return data.props.render(h, params)
}
}
export default {
components: {
'ex-slot': exSlot
},
props: {
// 表格数据
data: {
type: Array,
default: () => {
return []
}
},
// 表头数据
rowHeader: {
type: Array,
default: () => {
return []
}
}
}
}
</script>
使用
<my-table :data="tableData" :rowHeader="rowHeader"></my-table>
<script>
export default{
data(){
return:{
tableData:[
{
name: '老王',
sex: 0,
age: 18,
score: 60
}
],
rowHeader:[
// 未做任何格式化处理的数据
{
prop: 'name',
label: '姓名'
},
// 格式化为字符串
{
prop: 'sex',
label: '性别',
render: (h, params) => {
return params.row.sex === 0 ? '男' : '女'
}
},
{
prop: 'age',
label: '年龄',
render: (h, params) => {
return params.row.age + '岁'
}
},
// 插入组件或标签内容(例:进度条组件)
{
prop: 'score',
label: '分数',
render: (h, params) => {
return h('el-progress', {
props: {
textInside: true,
strokeWidth: 18,
percentage: params.row.score
}
})
}
},
// 添加操作按钮
{
prop: '',
label: '操作’,
render: (h, params) => {
return h('el-button', '删除', {
prop:{
type: 'primary'
},
on:{
click: () => {
console.log('删除')
}
}
})
}
}
]
}
}
}
</script>
封装的table组件中可以传入min-width,align等属性,当然element-ui的table组件有几时个api不可能通过我们自己二次封装的table全部传递,但是大多常用的table列表都可以用这种方式实现,如果是特别复杂的还是建议用el-table。