二次封装ElementUI table组件,支持渲染自定义列模板

921 阅读1分钟

在配置项中使用 JSX 语法,灵活传入要渲染的元素

<!-- baseTable.vue -->
<template>
  <div class="base-table">
    <el-table v-bind="$attrs" v-on="$listeners" :data="tableData">
      <!-- 实现多选 -->
      <el-table-column v-if="selection" type="selection" />
      <template v-for="item in columns">
        <!-- 渲染自定义列模板 -->
        <el-table-column v-if="item.render" :key="item.prop" v-bind="item">
          <template slot-scope="scope" v-if="item.render">
            <Render :scope="scope" :render="item.render" />
          </template>
        </el-table-column>
        <!-- 渲染常规列 -->
        <el-table-column v-else v-bind="item" :key="item.prop" />
      </template>
    </el-table>
  </div>
</template>

<script>
import Render from "./render";
export default {
  name: "BaseTable",
  components: {
    Render
  },
  props: {
    columns: {
      type: Array
    },
    tableData: {
      type: Array
    },
    selection: {
      type: Boolean,
      default: false
    }
  }
};
</script>

render.vue

<script>
// 函数式组件
export default {
  name: "Render",
  functional: true,
  props: {
    scope: Object,
    render: Function
  },
  render: (h, ctx) => {
    return ctx.props.render ? ctx.props.render(h, ctx.props.scope) : null;
  }
};
</script>

使用

<template>
  <div>
    <base-table
      border
      stripe
      selection
      @selection-change="handleSelectionChange"
      :columns="columns"
      :tableData="tableData"
    />
  </div>
</template>

<script>
import BaseTable from "../../components/BaseTable/index";
export default {
  name: "",
  components: {
    BaseTable
  },
  data() {
    return {
      tableData: [
        {
          name: "张三",
          state: 1,
          time: "2020-11-02 12:00:00",
          file: 0,
          id: 1
        },
        {
          name: "李四",
          state: 0,
          time: "2020-11-01 12:00:00",
          file: 1,
          id: 2
        }
      ]
    };
  },
  created() {
    this.columns = [
      {
        label: "序号",
        prop: "id",
        width: "50"
      },
      {
        label: "名称",
        prop: "name",
        render: (h, scope) => {
          return (
            <div class="cell-cont">
              {scope.row.file === 1 ? (
                <img
                  style="width: 13px;float: left;margin: 0 5px 0 0;"
                  src={require("@/assets/img/icon_FJ.png")}
                />
              ) : null}
              <el-tooltip effect="dark" placement="top-start">
                <div slot="content" style="max-width: 200px;">
                  {scope.row.name}
                </div>
                <span
                  class="change-name"
                  onClick={() => this.toDetail(scope.row)}
                >
                  {scope.row.name}
                </span>
              </el-tooltip>
            </div>
          );
        }
      },
      {
        label: "计划实施日期",
        prop: "time"
      },
      {
        label: "状态",
        prop: "state",
        formatter: (row, column, cellValue) => {
          return cellValue ? "完成" : "未完成";
        }
      },
      {
        label: "操作",
        prop: "action",
        render: (h, scope) => {
          return (
            <div>
              <el-button
                size="mini"
                onClick={() => {
                  this.handleEdit(scope.$index, scope.row);
                }}
              >
                编辑
              </el-button>
              <el-button
                size="mini"
                type="danger"
                onClick={() => {
                  this.handleDelete(scope.$index, scope.row);
                }}
              >
                删除
              </el-button>
            </div>
          );
        }
      }
    ];
  },
  mounted() {},
  methods: {
    // 选中行
    handleSelectionChange(val) {
      console.log(val);
    },
    // 跳转详情
    toDetail(row) {
      console.log(row);
    },
    // 编辑
    handleEdit(index, row) {
      console.log(index, row);
    },
    // 删除
    handleDelete(index, row) {
      console.log(index, row);
    }
  }
};
</script>

UI

WechatIMG938.png