组件需求
- 传一个columns配置文件,即可生成对应的table
- 传一个data即可渲染对应的数据
- 可通过插槽的方式对数据进行二次处理
组件设计
- columns是一个数组类型(必须)
- columns里面每一项是一个对象(必须)
columns每个对象应该包含:
- title(String):根据这个键生成的thead对应的th(必填)
- dataIndex (String): 根据这个键渲染对象的数据(这个键跟data里面的键一一对应)(必填)
- customRender(Boolean):根据这个键判断是否要分配一个对应的插槽(可选)
- data是一个数组类型(必须)
- data里面每一项是一个对象,里面的键必须跟上面的columns的dataIndex一一对应(必须)
期待的使用方式
<y-table :columns="columns" :data="data">
<template #sex="text">
{{ text === 1 ? '男': '女'}}
</template>
<template #handle="text,record">
<div style="display:flex">
<y-button type='success' @click="test(record)" style="margin-right:10px">修改</y-button>
<y-button type='danger' @click="test(record)">删除</y-button>
</div>
</template>
</y-table>
<script>
data () {
return {
columns: [
{
title: '名字',
dataIndex: 'name'
},
{
title: '年龄',
dataIndex: 'age'
},
{
title: '性别',
dataIndex: 'sex',
customRender: true
},
{
title: '操作',
dataIndex: 'handle',
customRender: true
}
],
data: [
{
name: '鸡太美',
age: 39,
sex: 1,
reload: 3
},
{
name: '鸡太美2',
age: 39,
sex: 2,
reload: 3
}
]
}
}
</script>
期待的效果
组件的实现(这里使用JXS)
首先根据上面的的需求,先定义两个props
props: {
columns: {
type: Array,
required: true
},
data: {
type: Array,
default: () => []
}
}
接着根据传进来的columns的title生成对应的thead
// 根据配置生成thead
_renderHeader (h) {
return h('thead', { class: 'y-header' }, [
h('tr', { class: 'y-header-row' }, [
this.columns.map(row => {
return h('th', { class: ['y-header-column', 'y-table-left'] }, row.title)
})
])
])
}
紧接着,根据columns的dataIndex结合data的键值对渲染对应的数据,再根据columns的customRender判断是否分配对应的插槽
// 根据配置生成tbody,再根据customRender分配作用域插槽
_renderBody (h) {
return h('tbody', {}, [
this.data.map(row => {
return h('tr', { class: 'y-body-row' }, [
this.columns.map(item => {
return h('td', { class: 'y-body-column' }, item.customRender && this.$scopedSlots[item.dataIndex]
? this.$scopedSlots[item.dataIndex](row[item.dataIndex], {
...row
}) : row[item.dataIndex])
})
])
})
])
}
这里生成的插槽是作用域插槽,有时候它是封装组件的神一样的存在,这里把当前的值传给插槽的第一参数,当前的行数据传给第二参数,所以外面就可以这样拿到数据
<template #handle="text,record">
<div style="display:flex">
<y-button type='success' @click="test(record)" style="margin-right:10px">修改</y-button>
<y-button type='danger' @click="test(record)">删除</y-button>
</div>
</template>
最后组装table,return 出去就OK了
// 组装table
_renderTable (h) {
return (
<table class='y-table'>
{this._renderHeader(h)}
{this._renderBody(h)}
</table>
)
}
render (h) {
return (
this._renderTable(h)
)
}
总结
到此,根据上面的需求已经实现了对应的可配置的table组件,比较核心的是上面两个生成方法(_renderHeader,_renderBody)大概也就20行,对于熟悉的JSX和作用域插槽的同学来说再容易不过了。
有兴趣的同学可以继续根据自己的需要拓展自己需要的table组件。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。