ElementUI——elementui2.0表格支持render渲染

2024-08-15 09:16:49 浏览数 (2)

前言

当前项目基于vue2.0 elementui来实现的,所以简单封装一个表格支持render函数来自定义渲染;

内容

custom-column

封装自定义列的组件

代码语言:javascript复制
var customColumn = {
  functional: true,
  render: (h, data) => {
    const params = {
      row: data.props.row,
      column: data.props.prop,
      render: data.props.render,
    };
    return params.render
      ? params.render(h, params.row)
      : h("span", params.row[params.column]);
  },
};

render

引用时的写法

代码语言:javascript复制
{
    label: "主体资质状态",
  prop: "status",
  align: "center",
  render: (h, row) => {
    return h(
      "el-tag",
      {
        props: {
          type: TIKTOK_QUA_COLOR[row.status],
        },
      },
      TIKTOK_QUA_STATUS[row.status]
    );
  },
},

ExpandTable

完整的表单组件,同理基于封装的render,这里的组件可以进一步的进行优化,比如将操作列表中的按钮,使用render来自定义;

代码语言:javascript复制
<template>
  <div class="app-container">
    <!-- 查询表单 -->
    <el-form
      :inline="true"
      :model="formData"
      ref="ruleForm"
      v-if="formItems.length"
    >
      <el-form-item
        v-for="item in formItems"
        :label="item.label"
        :key="item.name"
      >
        <component
          :is="item.type"
          :type="item.range"
          :value-format="item.valueFormat"
          :start-placeholder="item.startPlaceholder"
          :end-placeholder="item.endPlaceholder"
          v-model="formData[item.name]"
          :placeholder="item.placeholder"
          @keyup.enter.native="submitForm"
        >
          <component
            v-for="(els, i) in item.els"
            :key="i"
            :is="els.type"
            :slot="els.slot"
            v-model="formData[els.name]"
            class="input-width"
          >
            <el-option
              v-for="op in els.options"
              :key="op.value"
              :label="op.label"
              :value="op.value"
            >
            </el-option>
          </component>

          <el-option
            v-for="op in item.options"
            :key="op.value"
            :label="op.label"
            :value="op.value"
          >
          </el-option>
        </component>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm">查询</el-button>
        <el-button @click="resetForm">重置</el-button>
        <el-button v-if="tableConfig.export" @click="handleExport">
          导出
        </el-button>
        <a id="downlink" />
      </el-form-item>
    </el-form>

    <!-- 动态表格 -->
    <el-button
      v-if="tableConfig.add.status"
      type="primary"
      class="margin-b15"
      @click="handleOperateEvent(tableConfig.add.value)"
    >
      {{ tableConfig.add.label }}
    </el-button>
    <el-table
      :data="data"
      border
      fit
      highlight-current-row
      style="width: 100%"
      :max-height="tableHeight"
    >
      <el-table-column
        v-for="column in columns"
        :type="column.type"
        :key="column.prop"
        :prop="column.prop"
        :label="column.label"
        :fixed="column.fixed"
        :width="column.width"
        :align="column.align"
      >
        <template scope="scope">
          <!-- 自定义render -->
          <custom-column
            :render="column.render"
            :row="scope.row"
            :prop="column.prop"
          />
        </template>
      </el-table-column>

      <el-table-column
        v-if="tableConfig.op.status"
        label="操作"
        align="center"
        fixed="right"
      >
        <template slot-scope="scope">
          <el-link
            v-for="els in tableConfig.op.items"
            :key="els.value"
            :type="els.type"
            class="margin-r15"
            @click="handleOperateEvent(els.value, scope.row)"
          >
            {{ els.label }}
          </el-link>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <v-page
      style="margin-top: 15px"
      :page="page"
      @onChangePage="handlePageChange"
    />
  </div>
</template>
<script>
var customColumn = {
  functional: true,
  props: {
    row: Object,
    render: Function,
    prop: String,
  },
  render: (h, data) => {
    const params = {
      row: data.props.row,
      column: data.props.prop,
      render: data.props.render,
    };
    return params.render
      ? params.render(h, params.row)
      : h("span", params.row[params.column]);
  },
};

export default {
  props: {
    formItems: {
      type: Array,
      default: () => [],
    },
    data: Array,
    columns: Array,
    page: Object,
    tableConfig: Object,
  },
  components: { customColumn },
  data() {
    return {
      formData: {},
      tableHeight: 600,
    };
  },
  created() {
    if (window) {
      this.tableHeight = window.innerHeight - 320;
      if (this.tableHeight < 300) this.tableHeight = 300;
    }
  },
  methods: {
    handleExport() {
      this.$emit("export");
    },
    submitForm() {
      this.$emit("search", this.formData);
    },
    resetForm() {
      this.formData = {};
      this.$emit("search", this.formData);
    },
    handlePageChange(data) {
      this.$emit("page", data);
    },
    handleOperateEvent(type, data) {
      this.$emit("operate", type, data);
    },
  },
};
</script>

<style lang="scss" scoped>
.margin-r15 {
  margin-right: 15px;
}

.margin-b15 {
  margin-bottom: 15px;
}

.input-width {
  width: 88px !important;
}
</style>

使用

引用组件使用,因为组件直接在main.js中注册了,所以直接使用了

代码语言:javascript复制
<template>
  <div class="app-container">
    <!-- 表格 -->
    <v-ExpandTable
      :data="tableData"
      :columns="columns"
      :form-items="formItems"
      :page="page"
      :table-config="tableConfig"
      @search="handleSearch"
      @page="handlePageChange"
      @export="handleExport"
      @operate="handleOperateEvent"
    />
  </div>
</template>

<script>
import {
  TIKTOK_QUA_OPTIONS,
  TIKTOK_QUA_COLOR,
  TIKTOK_QUA_STATUS,
} from "@/utils/data";
import { getQualificationList } from "@/api/dy-compete/qualification";
export default {
  data() {
    return {
      searchForm: {},
      formItems: [
        {
          type: "el-input",
          label: "用户名称",
          name: "username",
          placeholder: "请输入用户名称",
        },
        {
          type: "el-input",
          label: "代理商名称",
          name: "agent_name",
          placeholder: "请输入代理商名称",
        },
        {
          type: "el-input",
          label: "一级代理商名称",
          name: "first_agent_name",
          placeholder: "请输入一级代理商名称",
        },
        {
          type: "el-select",
          label: "主体资质状态",
          name: "status",
          placeholder: "请选择主体资质状态",
          options: TIKTOK_QUA_OPTIONS,
        },
        {
          type: "el-select",
          label: "行业资质状态",
          name: "industry_qua_status",
          placeholder: "请选择行业资质状态",
          options: TIKTOK_QUA_OPTIONS,
        },
      ],
      tableConfig: {
        type: "subject",
        op: {
          status: true,
          items: [
            {
              label: "编辑",
              value: "edit",
              type: "primary",
            },
            {
              label: "详情",
              value: "detail",
              type: "success",
            },
          ],
        },
        add: {
          status: true,
          label: "新增主体资质",
          value: "add",
        },
        export: true,
      },
      columns: [
        {
          label: "用户名称",
          prop: "username",
          align: "center",
        },
        {
          label: "代理商",
          prop: "agent_name",
          align: "center",
        },
        {
          label: "一级代理商",
          prop: "first_agent_name",
          align: "center",
        },
        {
          label: "主体资质状态",
          prop: "status",
          align: "center",
          render: (h, row) => {
            return h(
              "el-tag",
              {
                props: {
                  type: TIKTOK_QUA_COLOR[row.status],
                },
              },
              TIKTOK_QUA_STATUS[row.status]
            );
          },
        },
        {
          label: "行业资质状态",
          prop: "industry_qua_status",
          align: "center",
          render: (h, row) => {
            return h(
              "el-tag",
              {
                props: {
                  type: TIKTOK_QUA_COLOR[row.status],
                },
              },
              TIKTOK_QUA_STATUS[row.status]
            );
          },
        },
        {
          label: "拒绝理由",
          prop: "reject_reason",
          align: "center",
        },
      ],
      tableData: [],
      page: {},
    };
  },
  created() {
    this.getQualificationListInfo();
  },
  methods: {
    handleExport() {
      const head = {
        username: "用户名",
        agent_name: "代理商名称",
        first_agent_name: "一级代理商",
        status: "主体资质状态",
        industry_qua_status: "行业资质状态",
        reject_reason: "拒绝理由",
        subject: "主体资质",
        industries: "行业资质",
      };

      this.$downloadFile(
        this.outFile,
        "抖音竞价_主体资质信息",
        head,
        "/douyin/qualification/subject",
        this.searchForm,
        {},
        "SUBJECT_QUALIFICATION"
      );
    },
    handleSearch(data) {
      this.searchForm = data;
      this.getQualificationListInfo(data);
    },
    getQualificationListInfo(params) {
      getQualificationList(params).then((r) => {
        this.tableData = r.data.items;
        this.page = r.data.page;
      });
    },
    handlePageChange(data) {
      this.getQualificationListInfo({ ...data, ...this.searchForm });
    },
    handleOperateEvent(type, data) {
      console.log(type, data);
    },
  },
};
</script>
<style lang="scss" scoped></style>

渲染效果

0 人点赞