# 三.数据输出(表格)

前言 --> 表格组件特点

  • 下拉菜单组件应该由两部分组成:
    • 表头
    • 数据展示部分
  • 它的主要功能包括:
    • 数据展示部分也可以嵌入基本组件,也可以使用自定义组件
    • <table><thead><tbody><tr>thtd这些标签组成,一般分为表头columns和数据data.

# 1.目录结构

├── table
│   ├── src
│   │    ├── render.js
│   │    ├── slot.js
│   │    └── table.vue
│   └── index.js
1
2
3
4
5
6

# 2.组件封装

# 2.1 table.vue

<template>
  <table>
    <thead>
      <tr>
        <th v-for="(col, i) in columns" :key="i">{{ col.title }}</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, rowIndex) in data" :key="rowIndex">
        <td v-for="(col, j) in columns" :key="j">
          <template v-if="'render' in col">
            <Render
              :row="row"
              :column="col"
              :index="rowIndex"
              :render="col.render"
            ></Render>
          </template>
          <template v-else-if="'slot' in col">
            <slot :row="row" :column="col" :index="rowIndex" :name="col.slot" />
          </template>
          <template v-else-if="'slot2' in col">
            <slot-scope :row="row" :column="col" :index="rowIndex" />
          </template>
          <template v-else> {{ row[col.key] }}</template>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
import Render from "./render.js";
import SlotScope from "./slot.js";

export default {
  name: "VueTable",
  components: { Render, SlotScope },
  provide() {
    return {
      tableRoot: this,
    }
  },
  props: {
    columns: {
      type: Array,
      default() {
        return [];
      },
    },
    data: {
      type: Array,
      default() {
        return [];
      },
    },
  },
};
</script>

<style lang="scss" scoped>
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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

组件的封装-->使用

  • 可以看到一个纯文本显示的表格组件已经封装好了

  • 现在有些地方需要用一些额外的逻辑(如生日)修改显示的效果,这里可以使用 render 函数来实现

# 2.2 render.js

export default {
    functional: true,
    props: {
        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)
    },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

render.js 定义了 4 个 props:

  • row:当前的数据
  • column:当前列的数据
  • index:当前是第几行
  • render:具体的 render 函数内容 这里的render选项并没有渲染任何节点,而是直接返回 props 中定义的 render,并将 h 和当前的行、列、序号作为参数传递出去。然后在 table.vue 里就可以使用 render.js 组件:

# 2.3 slot.js

export default {
    functional: true,
    inject: ["tableRoot"],
    props: {
        row: Object,
        column: Object,
        index: Number,
    },
    render: (h, ctx) => {
        return h(
            "div",
            ctx.injections.tableRoot.$scopedSlots[ctx.props.column.slot2]({
                row: ctx.props.row,
                column: ctx.props.column,
                index: ctx.props.index,
            })
        )
    },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 3.使用案例

# 3.1 数据展示

刷新
全屏/自适应

# 3.2 render 编辑

刷新
全屏/自适应

# 3.3 slot 编辑

刷新
全屏/自适应

# 3.4 render + slot 编辑

刷新
全屏/自适应

# 3.5 functional + slot 编辑

刷新
全屏/自适应

总结

通过对 table 组件的源码与案例分析可以得到几种表格开发方式,灵活运用在项目中可以使工作更高效