对于 vxe-table 的介绍这里就不说了,常规用法也不多累赘,应该按文档撸就可以了。这里主要讲下关于自定义渲染的一些方式
熟悉 Element 的朋友可能已经发现了,这个表格里面用了相关组件,比如:
tooltip — 实现了hover气泡
el-link — 渲染了表格内容
el-dropdown — 实现下拉菜单
最后还有一个空数据的渲染 el-empty,同时细心的朋友可能也发现了,排序那里也是自定义的图标。
小总结:
我们知道了,表头的内容、单元格的内容、部分图标都可以自定义实现,进而完成我们的需求。
通过查阅文档,我们发现要是实现自定义渲染有两种方式:
1、插槽 就跟 vue 中插槽一个意思
2、渲染器 好比是注册了一个 vxe-table 的组件
插槽的方式这里不讲,应该来说都能理解到,主要示范下 渲染器 的方式 。(我推荐先大致浏览下 文档,我个人比较倾向于看 API 那栏,就可以看到自己使用的组件有哪些props和其他需要的)
声明:本人采用的 vxe-grid 组件
老规矩,看文档
可以看到,可以通过 empty-text 直接传递,也可以通过渲染器,那我们肯定是通过渲染器来搞撒(vxe 属性中带-render的通常是渲染器)
// 这样就算注册了一个渲染器 name 为 NotData
VXETable.renderer.add('NotData', {
// 空内容模板 这个函数是 vxe 固定的,渲染表格头部为 renderHeader,其他科看文档
renderEmpty () {
// 渲染器接收的返回值类型为 []vnode 因此,这样返回
return [
<el-empty description="暂时没有数据"></el-empty>
]
}
})
// 使用 直接通过 props 传入
data() {
return {
gridOptions: {
...
emptyRender: {
name: 'NotData'
}
}
}
}
可以发现,其实这就跟注册组件一样,有人可能问,那我怎么传递参数或者绑定时间呢?下面以渲染一个单元格为例
还是老规矩,先看文档
上面渲染空内容我们大概知道渲染器大致格式,xxx.add(name,option),要求我们提供一个 name ,这个name就是 prop 中渲染器参数的name选项,同时 option 选项中内置了渲染函数(也就是上图的配置参数)
对于渲染器,vxe 其实已经给你定好了,比如你想渲染空内容,就得用 empty-render ,想渲染单元格的内容,就得用cell-render…对于这个建议好好理解下,不然估计会乱用
总的来说,就是你得先知道你想自定义渲染的地方是属于哪一种渲染器,然后再去看对应文档。比如现在我们是想渲染单元格,那么就得看 cell-render,每个 render 其实提供的函数也不太一样,所以最好是仔细看
// 简单再解释下 以cell-render为例
renderHeader ---- 你想自定义渲染那一列的表头内容
renderDefault --- 你想自定义渲染那一列单元格的内容,就好比我们现在想渲染操作那一列(更多操作),就得用这个去渲染单元格
...
这些渲染函数都提供了三个参数
renderHeader (h, renderOpts, params: { column, columnIndex, columnIndex, $rowIndex, $table })
h --- 应该类似vue render 函数的 h(具体我们看)
renderOpts --- 渲染的时候传递的参数(你想传递的数据、事件等,都通过这个参数去获取)
params --- 从文档应该可以看出,大致就是些当前列的一些信息
换句话说,当我们通过自定义的方式去渲染了一个单元格,那我怎么给这个单元格传递参数?绑定事件?事件响应时如何获取当前列的信息呢?答案就是通过这些render函数提供的参数来获取
渲染器的编写:
VXETable.renderer.add('Operation', {
// Default --- 默认的表格单元格内容
renderDefault(_, renderOpts, params) {
// 直接从 renderOpts 解构出我们传递的事件、参数、包括ele组件的一些自定义事件
const { events,props: { option,command } } = renderOpts
return [
<div>
<span class="editor-box pointer" onClick={ ()=> events(params) } >编辑</span>
<span style="margin: 0 10px" > | </span>
<el-dropdown placement="bottom" oncommand={ (val) => { command(val,params.row) } } >
<span class="el-dropdown-link pointer" >
更多
</span>
<el-dropdown-menu slot="dropdown">
{
option.map((item) => {
return (
<el-dropdown-item command={item.id} >{item.text}</el-dropdown-item>
)
})
}
</el-dropdown-menu>
</el-dropdown>
</div>
]
}
})
在 props 中 columns 属性里定义我们的渲染器
// data
columns = [
{ field: 'operation', title: '操作', showOverflow: true ,fixed: 'right',width: 200,
cellRender: {
name: 'Operation',
events: (e) => { this.onTabMoreEditor(e) },
props: {
option: [
{
id: 'a',
text: '删除'
},
{
id: 'b',
text: '狮子头'
},
{
id: 'c',
text: '螺蛳粉'
}
],
command: this.onTabCommand
}
}
}
]
methods: {
/** 更多-编辑 **/
onTabMoreEditor({ row: { name } }) {
console.log(name)
},
/** 更多 **/
onTabCommand(val,row) {
switch (val) {
case 'a':
console.log('当前选择 删除')
this.gridOptions1.data = this.gridOptions1.data.filter((item) => item.id != row.id)
break;
case 'b':
console.log('当前选择 狮子头')
break;
case 'c':
console.log('当前选择 螺蛳粉')
break;
default:
break;
}
}
}
如上所示,我们编写好了渲染器,需要传递的事件和绑定的参数都可以通过渲染器提供的 props和events选项传递到渲染器组件中,进而完成业务功能
当我们需要写多个渲染器时,又懒得通过 VXETable.renderer.add 方式去挨个添加,于是有了 mixin 的用法,就跟vue全局注册组件一样
const renderMap = {
// 这种方式应该不用多说吧
MyLink: {
renderDefault (h, renderOpts, params) {
let { row, column } = params
let { events } = renderOpts
return [
<el-link type="primary" onClick={ () => events(params) } >
{row[column.property]}
</el-link>
]
}
}
}
// mixin 接收一个 map 结构
VXETable.renderer.mixin(renderMap)
渲染器