正常情况下,如果需要自定义一个单元格显示模板,通常是使用 formatter 来格式化为字符串内容,虽然基本可以满足需求;
<vxe-table
border
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name"></vxe-column>
<vxe-column field="sex" title="Sex"></vxe-column>
<vxe-column field="time" title="Time" :formatter="formatTime"></vxe-column>
</vxe-table>
export default {
data () {
return {
tableData: []
}
},
created () {
this.tableData = [
{ name: 'Name111', sex: '1', time: 1571323971250 },
{ name: 'Name222', sex: '0', time: 1573940857260 },
{ name: 'Name333', sex: '1', time: 1575121185280 }
]
},
methods: {
formatTime ({ cellValue, row, column }) {
return XEUtils.toDateString(cellValue, 'yyyy-MM-dd HH:ss:mm')
}
}
}
但如果需要显示自定义的 html 内容就无法满足需求了;这时候就必须通过 slot 插槽模板来渲染;
<vxe-table
border
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name">
<template v-slot="{ row }">
<a class="my-link" :href="row.link">{{ row.time }}</a>
</template>
</vxe-column>
<vxe-column field="sex" title="Sex"></vxe-column>
<vxe-column field="time" title="Time"></vxe-column>
</vxe-table>
但是通过插槽来渲染复用性太差,到处是冗余代码,这时就需要用 渲染器 + jsx 来抽象可复用的单元格渲染;
// 创建一个超链接渲染器
VXETable.renderer.add('MyLink', {
// 默认显示模板
renderDefault (h, cellRender, params) {
let { row, column } = params
return [
<a class="my-link" href={ row.link }>{row[column.property]}</a>
]
}
})
<vxe-table
border
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name" :cell-render="{name: 'MyLink'}"></vxe-column>
<vxe-column field="sex" title="Sex"></vxe-column>
<vxe-column field="time" title="Time"></vxe-column>
</vxe-table>
这样就抽象完成!一切渲染都可以配置化;
先来看一个最简单的筛选配置
<vxe-table
border
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name"></vxe-column>
<vxe-column field="sex" title="Sex" :filters="selList"></vxe-column>
<vxe-column field="time" title="Time"></vxe-column>
</vxe-table>
export default {
data () {
return {
tableData: [],
selList: [
{label: '1', value: '男'},
{label: '0', value: '女'}
]
}
},
created () {
this.tableData = [
{ name: 'Name111', sex: '1', time: 1571323971250 },
{ name: 'Name222', sex: '0', time: 1573940857260 },
{ name: 'Name333', sex: '1', time: 1575121185280 }
]
}
}
但如果需要显示自定义的 html 内容就无法满足需求了;这时候就必须通过 slot 插槽模板来渲染;
上下文函数 context.changeOption(event, checked, option) 是在选项值发生改变是需要调用该方法,用于更新内部值
<vxe-table
border
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name"></vxe-column>
<vxe-column field="sex" title="Sex">
<template v-slot="{ row }">
<div v-for="(option, index) in column.filters" :key="index">
<input type="type" v-model="option.data" @input="context.changeOption($event, !!option.data, option)">
</div>
</template>
</vxe-column>
<vxe-column field="time" title="Time"></vxe-column>
</vxe-table>
通过插槽来渲染复用性太差,到处是冗余代码,这时使用 渲染器 + jsx 来抽象可复用的筛选渲染;
// 创建一个支持输入的筛选器(仅用于简单示例,实际开发中应该封装成一个组件,不应该把复杂的渲染逻辑写在渲染器中)
VXETable.renderer.add('MyFilter', {
// 筛选模板
renderFilter (h, filterRender, params, context) {
let { column } = params
return column.filters.map(option => {
return <input type="text" v-modal={ option.data } onInput={ evnt => { context.changeOption(evnt, !!option.data, option) } }/>
})
},
// 筛选方法
filterMethod ({ option, row, column }) {
let cellValue = XEUtils.get(row, column.property)
return cellValue == option.data
}
})
<vxe-table
border
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name"></vxe-column>
<vxe-column field="sex" title="Sex" :filters="[{data: null}]" :filter-render="{name: 'MyFilter'}"></vxe-column>
<vxe-column field="time" title="Time"></vxe-column>
</vxe-table>
先来看一下简单可编辑表格使用
<vxe-table
border
:edit-config="{trigger: 'click', mode: 'cell'}"
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name" :edit-render="{name: 'input', attrs: { type: 'text' }}"></vxe-column>
<vxe-column field="sex" title="Sex" :edit-render="{name: 'input', attrs: { type: 'text' }}"></vxe-column>
<vxe-column field="time" title="Time" :edit-render="{name: 'input', attrs: { type: 'text' }}"></vxe-column>
</vxe-table>
export default {
data () {
return {
tableData: []
}
},
created () {
this.tableData = [
{ name: 'Name111', sex: '1', time: 1571323971250 },
{ name: 'Name222', sex: '0', time: 1573940857260 },
{ name: 'Name333', sex: '1', time: 1575121185280 }
]
}
}
还是老问题,如果需要显示自定义的 html 内容就无法满足需求了;这时候就必须通过 slot 插槽模板来渲染;
<vxe-table
border
:edit-config="{trigger: 'click', mode: 'cell'}"
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name" :edit-render="{name: 'input'}">
<template v-slot:edit="{ row }">
<input type="text" v-model="row.name" class="custom-input">
</template>
</vxe-column>
<vxe-column field="sex" title="Sex" :edit-render="{name: 'input'}">
<template v-slot:edit="{ row }">
<input type="text" v-model="row.sex" class="custom-input">
</template>
</vxe-column>
<vxe-column field="time" title="Time" :edit-render="{name: 'input'}">
<template v-slot:edit="{ row }">
<input type="text" v-model="row.time" class="custom-input">
</template>
</vxe-column>
</vxe-table>
通过插槽来渲染复用性太差,再来看下 渲染器 + jsx 来抽象可复用的筛选渲染;
// 创建一个简单输入框渲染器
VXETable.renderer.add('MyInput', {
// 可编辑激活模板
renderEdit (h, editRender, { row, column }) {
return [
<input class="my-cell" text="text" v-modal={ row[column.property] }/>
]
},
// 可编辑显示模板
renderCell (h, editRender, { row, column }) {
return [
<span>{ row[column.property] }</span>
]
}
})
<vxe-table
border
:data="tableData">
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="name" title="Name" :edit-render="{name: 'MyInput'}"></vxe-column>
<vxe-column field="sex" title="Sex" :edit-render="{name: 'MyInput'}"></vxe-column>
<vxe-column field="time" title="Time" :edit-render="{name: 'MyInput'}"></vxe-column>
</vxe-table>
到此结束,由于渲染器的参数及高级用法就比较复杂了,这里仅仅只是介绍了简单的用法,更多进阶用于可以看官方文档哈!