表格:结合其他组件自定义列的显示内容

183 阅读1分钟

1、需求分析

项目开发中,我们常常需要自定义列的显示内容,而不仅仅是单纯的渲染。比如:表格内容可编辑、可排序、可插入输入框、可以点击等等。请看如下表格。

image.png

2、数据准备

准备表头以及表格相关特性的数据(这里用 Element)

  1. prop: 对应列内容的字段名
  2. label:显示的标题
  3. sortable:对应列是否可以排序
  4. showOverflowTooltip:当内容过长被隐藏时显示 tooltip
  5. width:对应列的宽度

columnData.json

{
    "tableColumns": [
        {
            "prop": "uesrname",
            "label": "姓名",
            "sortable": true,
            "showOverflowTooltip": false,
            "width": "100"
        },
        {
            "prop": "age",
            "label": "年龄",
            "sortable": true,
            "showOverflowTooltip": false,
            "width": "100"
        },
        {
            "prop": "phone",
            "label": "电话号码",
            "sortable": false,
            "showOverflowTooltip": false,
            "width": "200"
        },
        {
            "prop": "character",
            "label": "性格",
            "sortable": false,
            "showOverflowTooltip": false,
            "width": "180"
        },
        {
            "prop": "score",
            "label": "成绩",
            "sortable": false,
            "showOverflowTooltip": false,
            "width": "80"
        },
        {
            "prop": "action",
            "label": "操作",
            "sortable": false,
            "showOverflowTooltip": false,
            "width": "140"
        }
    ]
}

3、基本雏形

  1. 引入 columnData.json 中的 tableColumns,循环生成列。

  2. 表格 data 插入 tableData 数据,生成表格内容。

App.vue

  <template>
  <el-table :data="tableData" style="width: 801px" header-align="center" border>
    <el-table-column
      v-for="(item, index) in tableColumns"
      :key="index"
      :prop="item.prop"
      :label="item.label"
      :width="item.width"
      :sortable="item.sortable"
      :show-overflow-tooltip="item.showOverflowTooltip"
      align="center"
    >
    </el-table-column>
  </el-table>
</template>
<script>
import { tableColumns } from "../src/assets/columnData.json";
export default {
  components: {
    MyTab,
  },
  data() {
    return {
      tableColumns,
      tableData: [
        {
          uesrname: "林小饼",
          age: 17,
          phone: 15212345678,
          character: "安静",
          score: "90",
        },
        {
          uesrname: "林二饼",
          age: 18,
          phone: 15287654321,
          character: "沉稳",
          score: "100",
        },
        {
          uesrname: "林大饼",
          age: 19,
          phone: 15266668888,
          character: "活泼",
          score: "95",
        },
      ],
    };
  },
};
</script>

image.png

4、封装组件

还差一个组件,我们需要封装一下。

image.png

MyTab.vue

<template>
  <div class="my_tab">
    <div
      class="tab_item"
      :class="item.value === currValue ? 'current' : ''"
      v-for="(item, index) in tabList"
      :key="index"
      @click="changeTab(item)"
    >
      {{ item.value }}
    </div>
  </div>
</template>
<script>
export default {
  props: {
    tabList: {
      type: Array,
      default: () => [],
    },
    currValue: {
      type: String,
      default: "",
    },
  },
  methods: {
    changeTab({ value }) {
      this.$emit("update:currValue", value);
    },
  },
};
</script>
<style scoped>
.my_tab {
  display: flex;
  justify-content: center;
  align-items: center;
}
.my_tab .tab_item {
    cursor: pointer;
    background-color: #ccc;
    border-radius: 5px;
    color: #fff;
    padding: 2px 8px;
}
.my_tab .tab_item.current {
   color: red;
   background-color: yellow;
}
</style>

5、自定义列的显示内容

一切准备就绪,开始自定义列的显示内容啦!这里我们用 template ,使用 v-slot="{ row }",通过 row 来获取该列数据。

App.vue

  <template>
  <el-table :data="tableData" style="width: 801px" header-align="center" border>
    <el-table-column
      v-for="(item, index) in tableColumns"
      :key="index"
      :prop="item.prop"
      :label="item.label"
      :width="item.width"
      :sortable="item.sortable"
      :show-overflow-tooltip="item.showOverflowTooltip"
      align="center"
    >
      <template v-slot="{ row }">
        <span v-if="item.prop === 'uesrname' || item.prop === 'score'">{{ row[item.prop] }}</span>
        <span v-if="item.prop === 'age'">
          <el-input v-model="row.age" type="Number"></el-input>
        </span>
        <span v-if="item.prop === 'phone'">
          <el-input v-model="row.phone" show-password></el-input>
        </span>
        <span v-if="item.prop === 'character'">
          <MyTab :currValue.sync="row.character" :tabList="tabList"></MyTab>
        </span>
        <span v-if="item.prop === 'action'">
          <span>上移</span><span>下移</span><span>删除</span>
        </span>
      </template>
    </el-table-column>
  </el-table>
</template>
<script>
import { tableColumns } from "../src/assets/columnData.json";
import MyTab from "../src/components/MyTab.vue";
export default {
  components: {
    MyTab,
  },
  data() {
    return {
      tableColumns,
      tableData: [
        {
          uesrname: "林小饼",
          age: 17,
          phone: 15212345678,
          character: "安静",
          score: "90",
        },
        {
          uesrname: "林二饼",
          age: 18,
          phone: 15287654321,
          character: "沉稳",
          score: "100",
        },
        {
          uesrname: "林大饼",
          age: 19,
          phone: 15266668888,
          character: "活泼",
          score: "95",
        },
      ],
      tabList: [
        {
          label: "安静",
          value: "安静",
        },
        {
          label: "沉稳",
          value: "沉稳",
        },
        {
          label: "活泼",
          value: "活泼",
        },
      ],
    };
  },
};
</script>

大功告成!由于篇幅太长啦,上移下移删除就不做啦,以后有机会再出一个专题。

image.png