乐趣区

使用jsx配置elementui的table

背景

由于表格数据比较同构,有时候列配置是动态的,此时希望使用 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

此时所有想创建 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

以上。

退出移动版