背景
由於表格數據比較同構,有時候列配置是動態的,此時希望使用v-for來配置column
<template>
<el-table :data="tableData">
<el-table-column v-for="col in columns"
:key="col.dataIndex"
:label="col.title"
:prop="col.dataIndex"
:formatter="col.render" />
</el-table>
</template>
<script>
const PHONE_COLS = [
{ title: '錄音id', dataIndex: 'attach_id' },
{ title: '接聽客服', dataIndex: 'handle_user_info' },
{ title: '呼叫類型', dataIndex: 'type_desc' },
{ title: '通話時長', dataIndex: 'duration' },
];
const WORK_COLS = [
{ title: '工單id', dataIndex: 'attach_id' },
{ title: '創建客服', dataIndex: 'handle_user_info' },
{ title: '創建時間', dataIndex: 'c_t' },
{ title: '工單來源', dataIndex: 'source' },
{ title: '工單分類', dataIndex: 'ws_type',
render: (row, column, cell) => (cell || []).join(',')
}
];
export default {
data () {
return {
columns: PHONE_COLS,
tableData: [],
tableTotal: 0,
}
},
}
</script>
可以看到代碼比直接使用template更加簡潔,另外也可以利用formatter
函數處理簡單的自定義字符串
問題:自定義template
的列
當我們希望使用配置的方式來達到<template v-slot>
的效果,需要藉助於vue
的render
函數與jsx
模板
jsx
引入方法詳見渲染函數 & JSX
此時所有想創建vnode的時候都可以藉助jsx
來實現,jsx
編譯需要一個createElement
方法,如下
// h就是createElement
function render(h) {
var a = 'test'
return (
<el-tooltip class="item" effect="dark">
{a}
</el-tooltip>
)
}
table的formatter
方法也支持返回vnode渲染,因此我們可以想辦法拿到createElement
後使用jsx來達到複雜列的渲染,如下
<template>
<el-table :data="tableData">
<el-table-column v-for="col in columns"
:key="col.dataIndex"
:label="col.title"
:prop="col.dataIndex"
:formatter="col.render" />
</el-table>
</template>
<script>
let createElement
const WORK_COLS = [
{ title: '工單id', dataIndex: 'attach_id' },
{ title: '創建客服', dataIndex: 'handle_user_info' },
{ title: '創建時間', dataIndex: 'c_t' },
{ title: '工單來源', dataIndex: 'source' },
{ title: '工單分類', dataIndex: 'ws_type',
render: (row, column, cell) => (cell || []).join(',')
},
{ title: '工單描述', dataIndex: 'desc',
render: (row, column, cell) => {
return (function(h) {
return (
<div domPropsInnerHTML={cell}></div>
);
})(createElement)
}
},
];
export default {
data () {
return {
columns: WORK_COLS,
tableData: [],
tableTotal: 0,
}
},
mounted() {
createElement = this.$createElement
}
}
</script>
說明
- 爲了使用
jsx
模板,我們製造了帶有h函數的匿名函數來生成vnode
Note the h function, which is a shorthand for a Vue instance's $createElement method, must be in the scope where the JSX is. 詳細
- 獲取
createElement
方法比較多,比如可以把columns
放在組件內部通過this.$createElement
,此處是1個簡單例子 - 我們這裏的例子返回的是帶html特殊符號的字符串,需要使用innerHTML才能正確渲染,這裏react的
dangerouslySetInnerHTML
無效,需要使用babel-plugin-transform-vue-jsx
的屬性domPropsInnerHTML
以上。