vue封装el-table实现高度配置化

1、封装 Table.vue:

<template>
  <div id="ETable">
    <el-table
      ref="Table"
      :data="data"
      v-bind="$attrs"
      v-on="$listeners"
    >
      <el-table-column
        v-if="selectable"
        type="selection"
        v-bind="getSelectionBind()"
      >
      </el-table-column>

      <el-table-column
        v-if="!noIndex"
        type="index"
        v-bind="getIndexBind()"
      ></el-table-column>

      <el-table-column
        v-for="(item,index) in items"
        :key="index"
        v-bind="getBind(item)"
      >

        <template
          v-if="$scopedSlots[item.prop]"
          #default="scope"
        >
          <slot
            :name='item.prop'
            :item='item'
            v-bind="scope"
          />
        </template>

        <template
          v-else-if="item.type"
          #default="{row}"
        >

          <component :is="item.type" v-bind="item.bind(row[item.prop])"/> 
          
        </template>


      </el-table-column>

      <el-table-column
        v-if="$scopedSlots.default"
        v-bind="getOperaBind()"
        #default="scope"
      >

        <slot v-bind="scope" />

      </el-table-column>

      <el-empty
        v-if="!disEmpty"
        slot="empty"
        description="暂无数据"
      ></el-empty>

    </el-table>

    <el-pagination
      v-if="page"
      v-bind="page"
      @size-change="_c_size_change"
      @current-change="_c_page_change"
    />

  </div>

</template>
<script>
import * as _ from "lodash";


let config = {
  defIndexBind: { label: "序号", width: "80px", align: "center" },
  defOperaBind: { label: "操作", width: "200px", align: "center" },
  selectionBind: { width: "50px" },
  defBind: { align: "center", } 
}
export default {
  config,

  props: {
    data: Array,
    items: Array,
    page: Object,

    noIndex: Boolean,
    selectable: Boolean,

    operaBind: Object,
    indexBind: Object,

    selectionBind: Object,
    disEmpty: Boolean
  },
  mounted() {
    this.$nextTick(function () {
      this.setColSpan();
    });
  },
  methods: {
    // 暂时只支持单层的表头合并,多层的后面再说
    setColSpan() {
      let cells = this.$el.getElementsByClassName("el-table__header")[0].rows[0].cells;

      if (!cells) return;

      this.items?.forEach((item, index) => {
        let i = this.noIndex ? index : index + 1;

        if (item.colSpan === 0) {
          cells[i].style.display = "none";
        } else {
          cells[i].colSpan = item.colSpan || 1;
        }
      });
    },
    //----------普通方法-----------
    clearSelection() {
      this.$refs.Table.clearSelection();
    },
    toggleRowSelection() {
      this.$refs.Table.toggleRowSelection.apply(this, [...arguments]);
    },
    toggleRowsSelection(rows, flag) {
      this.$refs.Table.clearSelection();
      rows?.forEach((row) => {
        this.$refs.Table.toggleRowSelection(row, flag);
      });
      
    },
    getOperaBind() {
      let bind = this.operaBind || {};
      let def = _.cloneDeep(config.defOperaBind)

      return _.merge(def, bind);
    },
    getIndexBind() {
      let bind = this.indexBind || {};
      let def = _.cloneDeep(config.defIndexBind)

      return _.merge(def, bind);
    },
    getSelectionBind() {
      let bind = this.selectionBind || {};
      let def = _.cloneDeep(config.selectionBind)

      return _.merge(def, bind);
    },
    getBind(item) {
      let def = _.cloneDeep(config.defBind)

      return _.merge(def, item);
    },

    //----------点击事件-----------
    _c_size_change(val) {
      this.page.pageSize = val;
      this.$emit("page-change", this.page.pageNo);
    },
    _c_page_change(val) {
      this.$emit("page-change", val);
    },

    //----------接口方法-----------
  },
};
</script>
<style lang="scss">
.mycell, .mycell .cell{
  padding: 0!important
}
</style>

2、用法:

<template>
  <div>

    <ETable 
      :data="tableData" 
      :items="items"
      height="70vh"
      border
      :page.sync="page"
      @page-change="_c_page_change">

      <template #name="{row, item}">
        自定义:<el-tag>{{row[item.prop]}}</el-tag>
      </template>

      <template #default="{row, item}">
        <EBtn mode="detail" @click="_c_add"/>
        <EBtn mode="update" @click="_c_update(row)"/>
        <EBtn mode="delete" @click="_c_delete"/>
      </template>
    </ETable>
  </div>
</template>

<script>
import crud_mixin from '@/mixins/crud_mixin.js'
export default {
  mixins: [crud_mixin],
  data() {
    let _this = this
    return {
      tableData: [
        {
          id: 10201,
          created_at: "2022-05-23T09:52:44.655+08:00",
          updated_at: "2022-05-23T10:01:25.571+08:00",
          is_deleted: 0,
          name: "张三",
          age: 21,
          sex: 1,
          org_id: 57,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "111",
          manager_name: "王sir",
          manager_id: 25,
          tel: "13451820534",
        },
        {
          id: 10177,
          created_at: "2022-04-06T11:21:10.794+08:00",
          updated_at: "2022-04-06T11:30:50.51+08:00",
          is_deleted: 0,
          name: "姓名",
          age: 21,
          sex: 0,
          org_id: 52,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "22",
          manager_name: "小委",
          manager_id: 30,
          tel: "13451820538",
        },
        {
          id: 10175,
          created_at: "2022-04-01T16:04:42.217+08:00",
          updated_at: "2022-04-01T16:07:49.398+08:00",
          is_deleted: 0,
          name: "奥特曼11",
          age: 9991,
          sex: 1,
          org_id: 2,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "M781",
          manager_name: "哥斯拉1",
          manager_id: 200,
          tel: "1234561",
        },
        {
          id: 10171,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "姚春华",
          age: 1981,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "沙家圩村星月花园49-1506",
          tel: "18862953186",
        },
        {
          id: 10170,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "顾金水",
          age: 1969,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "源兴社区居委会源兴花苑8-103",
          tel: "18862931462",
        },
        {
          id: 10169,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "姜美香",
          age: 1967,
          sex: 0,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "源兴社区居委会源兴花苑9-204",
          tel: "18862931462",
        },
        {
          id: 10168,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "施兴华",
          age: 1958,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "源兴社区居委会源兴花苑41-402",
          tel: "18862931462",
        },
        {
          id: 10167,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "黄聪明",
          age: 1957,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "朝阳社区四圩桥村8组",
          tel: "15996582978",
        },
        {
          id: 10166,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "胡顺英",
          age: 1965,
          sex: 0,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "朝阳社区四圩桥村一组",
          tel: "15996582978",
        },
        {
          id: 10165,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "陈圣珍",
          age: 1943,
          sex: 0,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "朝阳社区朝阳花苑21-302",
          tel: "15996582978",
        },
      ],
      items: [
        { prop: "name", label: "弱势群体人员姓名", colSpan: 0 },
        { 
          prop: "age", 
          label: "出生年份",
          type: 'ETag',    // 这是自己封装的组件名称
          bind:val => ({
            text: val+'',
            effect: 'plain',
          }) 
        },
        {
          prop: "sex",
          label: "性别",
          type: 'el-image',
          bind:value => {
            let src = {
              1: require(`@/assets/images/boy.png`),
              0: require(`@/assets/images/girl.png`),
            }[value] || require(`@/assets/images/unknown.png`)
            return {
              src,
              'preview-src-list': [src],
              style:{
                width: '40px',
              }
            }
          }
        },
        { 
          prop: "address", 
          label: "住址",
          formatter(row, col, value){
            return value + '111'
          } 
        },
        { 
          prop: "detail", 
          label: "具体情况",
          'class-name': 'mycell',
          type: 'ECellList',    // 这是自己封装的组件名称
          bind: value => ({
            data: value,
            getItemText: (item, index) => (index+1) +'、'+ item.name
          })
        },
        { prop: "manager_name", label: "帮扶责任人" },
        { prop: "tel", label: "帮扶责任人联系电话" },
      ],
    };
  },
  mounted() {},
  methods: {
  },
};
</script>

<style></style>

3、效果:

4、一般表格会用到crud_mixin.js:

import * as _ from 'lodash'
export default {
  data() {
    return {
      page: {
        pageNo: 1,
        pageSize: 10,
        total: 0,
        pageSizes: [10, 20, 30, 40],
        layout: "total, sizes, prev, pager, next, jumper",
        pagerCount: 5,
        background: true,
      },
      isEditDialogVisible: false,
      isAdd: true,
      loading:false,
      curRow: null,
    }
  },
  watch:{
    'page.pageNo'(n, o){
      this.page['current-page'] = n
    }
  },
  created(){
  },
  mounted(){

  },
  methods: {
    _m_tip(msg){
      this.$message.success(msg);
      this.isEditDialogVisible = false;
      this._c_query();
    },
    _c_query() {
      this.$set(this.page, 'pageNo', 1)
      this._i_query();
    },
    _c_add(row){
      this.$set(this, 'editForm', this.$options.data().editForm)
      this.isAdd=true;
      this.isEditDialogVisible=true
      
      this.curRow = row
    },
    _c_update(row) {
      this.editForm = _.cloneDeep(row);
      this.isAdd = false;
      this.isEditDialogVisible = true;
      
      this.curRow = row
    },
    _c_delete(row, $index) {
      this.curRow = row
      this.$confirm('确认删除吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(res => {
          this._i_delete(row, $index);
        },res => {}
      );
    },
    _c_confirm(isAdd){
      isAdd? this._i_add():this._i_update()
    },
    _c_page_change(val) {
      this.page.pageNo = val;
      this._i_query();
    },
  }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue3中封装el-table可以通过以下步骤进行: 1. 首先,我们需要创建一个自定义组件,可以命名为MyTable。 2. 在MyTable组件中,我们需要导入el-tableel-table-column组件,可以使用import语句进行导入。 3. 在template标签中,我们可以使用el-table来渲染表格。可以设置属性如:data、border、stripe等。 4. 在el-table标签内部,我们可以使用el-table-column来定义表格的列。可以设置属性如:prop(对应数据源)、label(列名)、width(列宽)等。 5. 在script标签中,我们需要定义MyTable组件的props,用于接收父组件传递的数据。 6. 在script标签中,我们可以定义一些方法或者计算属性,用于处理表格的点击事件、排序、筛选等。 7. 最后,我们需要在父组件中使用MyTable组件,并传递数据和配置选项给MyTable组件的props,来渲染自定义的表格。 总结一下,Vue3中封装el-table的关键步骤包括创建自定义组件、导入el-tableel-table-column组件、在MyTable组件中使用el-tableel-table-column来渲染表格、定义props、定义方法和计算属性以及在父组件中使用MyTable组件。通过封装el-table,我们可以更好地复用和管理表格组件,并实现更灵活的表格功能。 ### 回答2: Vue3是一个用于构建用户界面的渐进式JavaScript框架。它具有轻量级、高效、易用的特点,并且在Vue3中可以灵活地封装el-table。 首先,为了封装el-table,我们可以创建一个自定义组件,命名为TableWrapper。在TableWrapper组件的模板中使用el-table,并将el-table的相关属性、事件和插槽通过props进行传递和接收。 在TableWrapper组件的props中,我们可以定义例如data、columns、pagination等与el-table相关的属性。这样,我们就可以通过在使用TableWrapper组件时传递这些属性来配置el-table的行为。 另外,我们还可以在TableWrapper组件中定义一些需要自定义的功能,例如表格的样式、表头的固定、排序功能等。这些功能可以通过在TableWrapper组件中添加相关的方法和事件来实现。 除了属性和方法外,我们还可以使用插槽在TableWrapper组件中自定义表格的各个部分,例如表头、表尾、表格内容等。通过在TableWrapper组件的模板中使用<slot>元素,并在使用TableWrapper组件时传递相应的内容,可以方便地自定义el-table的外观和布局。 总之,通过将el-table封装到自定义组件TableWrapper中,我们可以更好地控制和定制el-table的行为和外观。这样,我们就能够根据实际需要快速构建出符合需求的数据表格。 ### 回答3: Vue3中封装el-table的步骤如下: 1. 首先,创建一个名为el-table-wrapper的组件,该组件用于封装el-table。 2. 在el-table-wrapper组件中,引入el-table组件,并在模板中使用el-table进行数据展示。 3. 在el-table-wrapper组件中,接收名为data的props属性,用于传递表格数据。 4. 在el-table-wrapper组件中,通过v-for指令遍历data数据,并使用el-table-column组件进行表格列的定义。 5. 在el-table-wrapper组件中,使用slot插槽来支持自定义表格内容,例如添加操作按钮等。 6. 在el-table-wrapper组件中,可以设置一些其他属性,如border、stripe等,以适应不同的需求。 7. 在el-table-wrapper组件中,可以使用事件监听器来捕获el-table的一些事件,例如选择行、排序等。 8. 在el-table-wrapper组件中,通过emit方法触发自定义事件,以便在父组件中处理表格的交互逻辑。 总结:在Vue3中封装el-table,需要通过创建一个包装组件,在其中引入el-table组件并定义相应的列和属性,同时支持自定义内容和事件。这样可以提高代码的复用性和可维护性,方便在不同的项目中使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值