首先制定表格API。表格分为表头thead和数据tbody,所以props也定义为两部分:

  • columns: 列配置Array,每一列均为Object:
    - title: 列文字
    - key: 对应列内容字段名称
    - render: 渲染函数
    - slot:插槽名称
  • data: 数据内容Array
    在components目录中新建table目录,创建table.vue文件:
// components/table
<template>
    <table>
        <thead>
                <th v-for="(col, index) in columns" :key="index">
                    {{ col.title }}
        </thead>
        <tbody>
            <tr v-for="(row, index) in data" :key="index">
                <td v-for="(col, idx) in columns" :key="idx">
                    {{ row[col.key] }}
        </tbody>
    </table>
</template>
<script>
export default {
    props: {
        columns: {
            type: Array,
            default: () => []
        data: {
            type: Array,
            default: () => []
</script>
<style>
table {
    width: 100%;
    border-collapse: collapse;
    border-spacing: 0;
    empty-cells: show;
    border: 1px solid #e9e9e9;
table th {
    background: #f7f7f7;
    color: #5c6b77;
    font-weight: 600;
    white-space: nowrap;
table td,
table th {
    padding: 8px 16px;
    border: 1px solid #e9e9e9;
    text-align: left;
</style>

在page目录下新建table.vue页面

// page/table
<template>
        <table-render :columns="columns" :data="data"></table-render>
    </div>
</template>
<script>
import TableRender from "../components/table/table.vue";
export default {
    components: { TableRender },
    data() {
        return {
            columns: [
                    title: "姓名",
                    key: "name",
                    title: "年龄",
                    key: "age",
                    title: "出⽣⽇期",
                    key: "birthday",
            data: [
                    name: "张三",
                    age: 18,
                    birthday: "782870400000",
                    name: "李四",
                    age: 19,
                    birthday: "894988800000",
                    name: "王五",
                    age: 20,
                    birthday: "1205164800000",
</script>

效果如下:
在这里插入图片描述

使用render函数渲染

这里日期这一栏显示时间戳,计划在columns中如下使用render

title: "出⽣⽇期", key: "birthday", render: (h, { row,index, column }) => { // h 传进来的createElement // row, index, column分别是列表的当前行数据,当前索引,当前列数据 const date = new Date(parseInt(row.birthday)); const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); const birthday = `${year}-${month}- ${day}`; return h("span", birthday);

组件中table修改如下: 其中Render组件就是打算用render函数渲染的部分,它把当前所属列的数据全部通过props传了进去。

// component/table部分代码省略
<tbody>
    <tr v-for="(row, index) in data" :key="index">
        <td v-for="(col, idx) in columns" :key="idx">
            <template v-if="col.render">
                <Render
                    :row="row"
                    :column="col"
                    :index="index"
                    :render="col.render"
                ></Render>
            </template>
            <template v-else>{{ row[col.key] }} </template>
</tbody>
import Render from "./render.js";
export default {
    components: { Render }

render.js中代码如下:这里用props接受了外面传进来的参数,render函数真正渲染了页面
注意:从始至终只有render.js中的render函数是vue中真正渲染页面的render函数,columns中只是碰巧定义了render字段,它只是一个普通函数。

export default {
  functional: true,
  porps: {
    row: Object,
    column: Object,
    index: Number,
    render: Function
  render: (h, ctx) => {
    const params = {
      row: ctx.props.row,
      column: ctx.props.column,
      index: ctx.props.index
    return ctx.props.render(h, params);

使用slot-scope自定义

slot-scope就是写slot时往父级传递参数,在写table组件时添加一列slot标签,同时加上row,column,index属性,把当前列信息传递出去,在外面使用的时候就能拿到该列信息对应渲染自己想要显示的数据
组件代码如下:

//cmoponents/table 部分代码省略
    <template v-if="'col.render">
        <Render
            :row="row"
            :column="col"
            :index="index"
            :render="col.render"
        ></Render>
    </template>
    <template v-else-if="col.slot">
            :row="row"
            :column="col"
            :index="index"
            :name="col.slot"
        ></slot>
    </template>
    <template v-else>{{ row[col.key] }} </template>

page使用代码如下:这里可以拿到当前列所有信息,可以任意处理

// page/table 部分代码省略
    <table-render :columns="columns" :data="data">
        <template slot-scope="{ row, index, column }" slot="name">
            {{ row.name }}
        </template>
    </table-render>

同时使用render和slot-scope自定义

待续。。。

一.slot 插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示、以及怎样显示由父组件来决定。值得注意的是:内容要写在父组件中,然后分给需要的子组件,当slot多个时,可以通过name来加以区分,这就是所谓的具名插槽。 这是父组件 实践slot 实践具名slot 这是子组件 二.slot-scope slot-scope就是作用域插槽。官方叫它作用域插槽,实际上,对比具名插槽,我们可以叫它带数据的插槽。具名插槽在组件的templat vue中的插槽有三种:单个插槽、具名插槽、作用域插槽,这个在官网上能看到 (https://cn.vuejs.org/v2/guide/components.html#单个插槽) 作用域插槽简单来说就是父组件只管显示样式,数据由子组件来提供。比如上面的代码,el-table-column内的template是传递给其内部solt的显示内容,但是scope的值是由el-table-column内部solt绑定的数据返回的。这个数据具体是什么由el-table-column中指定,类似: export default { 渲染函数基础节点、树以及虚拟DOM虚拟DOMcreateElement参数深入数据对象完整示例约束   Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你确实需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。   让我们深入一个简单的例子,这个例子里 render 函数很实用。假设我们要生成一些带锚点的标题: <h1&... 开发中总是会遇到各种UI设计的图表,最近也一直“沉浸”在负责的两个专门做数据可视化的项目中,其中有个表格很好玩,效果如下图:(也不知道会不会压缩) 本项目主要使用VUE、Echarts、Element UI,来吧,直接开始了。 第一步:咱们需要重新封装table组件。 <el-table :data="tableData"> <el-table-column v-for="(item, index) of tableColumns" :key="index" 在这个示例代码中,我们在表头中定义了两列:姓名和操作。对于“操作”列,我们使用了 scopedSlots 来定义一个名为 operation 的插槽,用于自定义该列的内容。在插槽中,我们根据当前行的展开状态来显示不同的按钮。如果当前行已展开,则显示“Close”按钮。在 Ant Design Vue 中,可以使用 a-table 组件来创建表格,并且可以使用 expand-row 属性来自定义展开/折叠行。为了在表头中添加一个自定义的“+”按钮,可以在表头中使用 slot 插槽来自定义表头的列。 form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成器。并且支持生成任何 Vue 组件。结合内置17种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。 文档 | github 自定义组件 可生成任何Vue组件 自带数据验...