2

背景

由于表格数据比较同构,有时候列配置是动态的,此时希望使用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>的效果,需要借助于vuerender函数与jsx模板

jsx引入方法详见渲染函数 & JSX

实现功能的babel plugintransform-vue-jsx

此时所有想创建vnode的时候都可以借助jsx来实现,jsx编译需要一个$createElement方法,所有vue实例都有这个方法

// h就是createElement
function render(h) {
  var a = 'test'
  return (
    <el-tooltip class="item" effect="dark">
      {a}
    </el-tooltip>
  )
}

table的formatter方法也支持返回vnode渲染,因此我们可以使用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>
export default {
  data () {
    return {
      columns: [
        { 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 (
              <div>
                <div domPropsInnerHTML={cell}></div>
                <span class="num-down">{row.c_t}</span>
              </div> 
            );
          }
        },
      ],
      tableData: [],
      tableTotal: 0,
    }
  }
}
</script>

说明

  • 为了使用jsx模板,这里没有声明$createElement是因为
Starting with version 3.4.0 we automatically inject const h = this.$createElement in any method and getter (not functions or arrow functions) declared in ES2015 syntax that has JSX so you can drop the (h) parameter. 详细
  • 我们这里的例子返回的是带html特殊符号的字符串,需要使用innerHTML才能正确渲染,这里react的dangerouslySetInnerHTML无效,需要使用babel-plugin-transform-vue-jsx的属性domPropsInnerHTML

以上。


defghy
170 声望8 粉丝