常用table组件封装(函数组件,render函数, 动态slot)

功能:
1,key-value类型的展示(如图),自定义单元格宽度
2,value支持显示省略号,自带title, 合并格(列)
3, value单元格支持使用render,slot,html自定义功能

效果图:
在这里插入图片描述

使用示例:

egData试用主组件的示例

        <CustomerTable :tableData="egData" >
           <template slot-scope="{value}" slot="name">
             slot渲染: {{value}}
           </template>
          <template slot-scope="{value}" slot="rys">
            <el-button size="mini" type="primary"> {{value}}</el-button>
           </template>
        </CustomerTable>

源码:

1, table主组件

<!--
@authors 秋刀鱼
@version 1.0.0
props: tableData 
       type (render,slot,html, 默认为空, 直接显示value内容)
详细解释看示例data: egData
const egData = [
  [
    // 每个二级arr,是一行
    {
      key: "示例key",
      keyWidth: 120, // key 单元格宽度,表格的特性只需要在第一行数据设置width
      value: "示例value示例value示例value示例value示例value示例value示例value示例value示例value",
      valueWidth: 200, // value 单元格宽度
      showEllipsis: true // value 当显示不下时是否显示 省略号
    },
    { key: "示例key", keyWidth: 120, value: "示例value" }
  ],
  [
    {
      key: "示例key",
      value: "示例value",
      type: "render",
      render: h => {
        return h(
          "el-input",
          {
            props: {
              size: "mini",
              value: this.renderInputValue // 在data声明默认值
            },
            on: {
              // 实现双向绑定
              input: value => {
                this.renderInputValue = value;
              }
            }
          },
          ""
        );
      }
    },
    {
      key: "示例key",
      value: "示例value-render",
      type: "render",
      render: h => { // 使用render函数自定义单元格内容
        return h(
          "div",
          {
            style: { color: "red" },
            on: {
              click: () => {
                alert("自定义事件");
              }
            }
          },
          "我是vue的render函数创建的"
        );
      }
    }
  ],
  [
    { key: "示例key", value: "合并单元格", colspan: 3 } // colspan 合并单元格列
  ],
  [{ key: "示例slot", value: "张三", colspan: 3, type: "slot", slot: "name" }],// 使用作用域slot在指定单元格插入组件
  [{ key: "示例slot", value: "阿里巴巴", colspan: 3, type: "slot", slot: "rys" }],
  [{ key: "示例html", value: "<b>自定义的b标签<br/>hah</b>", colspan: 3, type: "html" }] // 直接插入html
];
-->

<template>
  <table class="c-table">
    <tr class="c-tr" v-for="(item, index) in tableData" :key="index">
      <template v-for="(item2, i) in item">
        <td class="c-td c-td-key" :width="item2.keyWidth ? item2.keyWidth : ''" :key="i">
          {{ item2.key }}
        </td>
        <td
          :class="['c-td', 'c-td-val', { ellipsis: item2.showEllipsis }]"
          :width="item2.valueWidth ? item2.valueWidth : ''"
          :colspan="item2.colspan ? item2.colspan : ''"
          :key="i"
        >
          <table-cell-render v-if="item2.type === 'render'" :value="item2.value" :render="item2.render"></table-cell-render>
          <table-cell-slot v-else-if="item2.type ==='slot'" :value="item2.value" :slot="item2.slot"></table-cell-slot>
          <div v-else-if="item2.type ==='html'" v-html="item2.value"></div>
          <span v-else :title="item2.value" >
            {{ item2.value }}
          </span>
        </td>
      </template>
    </tr>
  </table>
</template>

<script>
import TableCellRender from "./table-cell-render"
import TableCellSlot from "./table-cell-slot"
export default {
  props: {
    tableData: {
      type: Array,
      default: () => []
    }
  },
  components:{TableCellRender,TableCellSlot},
  provide () {
      return {
          tableRoot: this
      };
  }
}
</script>

<style lang="less" scoped>
.c-table {
  width: 100%;
  background: white;
  table-layout: fixed;
}
.c-table,
.c-tr,
.c-td {
  border: 1px solid #dbdbdb;
  box-sizing: border-box;
}
.c-td {
  padding: 12px 0;
  word-wrap: break-word;
  word-break: break-all;
  white-space: normal;
}
.c-td-key {
  background:  #f5f7fa;
  text-align: right;
  padding-right: 10px;
  font-size: 12px;
  color: #666666;
}
.c-td-val {
  text-align: left;
  padding-left: 10px;
  font-size: 12px;
  color: #333333;
}
.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-break: normal;
}
</style>

2,单元格render组件table-cell-render.js

export default {
  name: 'TableCellRender',
  functional: true,
  props: {
    render: Function,
    value: [Object, String, Array, Number]
  },
  render: (h, ctx) => {
    const params = {
      value: ctx.props.value
    };

    return ctx.props.render(h, params);
  }
};

3,单元格slot组件 table-cell-slot.js

export default {
    name: 'TableCellSlot',
    functional: true,
    inject: ['tableRoot'],
    props: {
        value: [Object, String, Array, Number],
        slot: String
    },
    render: (h, ctx) => {
        return h('div', ctx.injections.tableRoot.$scopedSlots[ctx.props.slot]({
            value: ctx.props.value
        })
        );
    }
};
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值