zoukankan      html  css  js  c++  java
  • 超级表格组件之render抽象

    参考——element el-table表格的vue组件二次封装(附表格高度自适应) - 掘金 (juejin.cn)

    JSX——Vue JSX、自定义 v-model - 你的美好,我都记得 (ainyi.com)

    0.问题

    抽象一个复杂表格组件

    1.解决方法

    借助element自己的renderHeader与上面的大佬写的render函数,可以抽象出来这样一个组件

    // tableCom.vue

    <template>
      <div>
        <el-table
          empty-text="暂无数据"
          ref="table"
          :data="tableList"
          border
          stripe
          fit
          highlight-current-row
          :height="inTableHeight"
          @selection-change="selectionChange"
          @row-click="rowClick"
          :header-cell-style="{ background: 'rgb(1, 97, 90)', color: 'white' }"
        >
          <!-- 选择框 -->
          <el-table-column
            v-if="select"
            type="selection"
            fixed="left"
            width="55"
            align="center"
          />
          <template v-for="(itm, idx) in header">
            <!-- 特殊处理列 -->
            <el-table-column
              v-if="itm.render && !itm.children"
              :key="idx"
              :renderHeader="itm.renderHeader ? itm.renderHeader : null"
              :prop="itm.prop ? itm.prop : null"
              :label="itm.label ? itm.label : null"
              :width="itm.width ? itm.width : null"
              :sortable="itm.sortable ? itm.sortable : false"
              :align="itm.align ? itm.align : 'center'"
              :fixed="itm.fixed ? itm.fixed : null"
              :show-overflow-tooltip="itm.tooltip"
              min-width="50"
            >
              <template slot-scope="scope">
                <ex-slot
                  :render="itm.render"
                  :row="scope.row"
                  :index="scope.$index"
                  :column="itm"
                />
              </template>
            </el-table-column>
            <!-- 二级表头 -->
            <el-table-column
              :key="idx"
              v-if="itm.children"
              :label="itm.label ? itm.label : null"
              header-align="center"
              :renderHeader="itm.renderHeader ? itm.renderHeader : null"
            >
              <el-table-column
                v-for="(child, indexNum) in itm.children"
                :key="indexNum"
                :renderHeader="child.renderHeader ? child.renderHeader : null"
                :prop="child.prop ? child.prop : null"
                :label="child.label ? child.label : null"
                :width="child.width ? child.width : null"
                :sortable="child.sortable ? child.sortable : false"
                :align="child.align ? child.align : 'center'"
                :fixed="child.fixed ? child.fixed : null"
                :show-overflow-tooltip="child.tooltip"
                min-width="50"
              >
                <template slot-scope="scope">
                  <ex-slot
                    :render="child.render"
                    :row="scope.row"
                    :index="scope.$index"
                    :column="child"
                  />
                </template>
              </el-table-column>
            </el-table-column>
            <!-- 正常列 -->
            <el-table-column
              v-if="!itm.render && !itm.children"
              :key="idx"
              :renderHeader="itm.renderHeader ? itm.renderHeader : null"
              :prop="itm.prop ? itm.prop : null"
              :label="itm.label ? itm.label : null"
              :width="itm.width ? itm.width : null"
              :sortable="itm.sortable ? itm.sortable : false"
              :align="itm.align ? itm.align : 'center'"
              :fixed="itm.fixed ? itm.fixed : null"
              :formatter="itm.formatter"
              :show-overflow-tooltip="itm.tooltip"
              min-width="50"
            />
          </template>
        </el-table>
      </div>
    </template>
    
    <script>
    // 自定义内容的组件
    var exSlot = {
      functional: true,
      props: {
        row: Object,
        render: Function,
        index: Number,
        column: {
          type: Object,
          default: null,
        },
      },
      render: (h, context) => {
        const params = {
          row: context.props.row,
          index: context.props.index,
        };
        if (context.props.column) params.column = context.props.column;
        return context.props.render(h, params);
      },
    };
    
    export default {
      components: { exSlot },
      props: {
        tableList: {
          type: Array,
          default: () => [],
        },
        header: {
          type: Array,
          default: () => [],
        },
        select: {
          type: Boolean,
          default: () => false,
        },
        height: {
          type: [Number, String, Function],
          default: () => null,
        },
      },
      data() {
        return {
          inTableHeight: null,
        };
      },
      created() {
        //该阶段可以接收父组件的传递参数
        this.inTableHeight = this.height;
        console.log("slot see", this.$slots); // 看看里面有啥
      },
      mounted() {
        this.$nextTick(() => {
          //表格高度自适应浏览器大小
          this.changeTableHight();
          if (!this.height) {
            window.onresize = () => {
              this.changeTableHight();
            };
          }
        });
      },
      destroyed() {
        //高度自适应事件注销
        window.onresize = null;
      },
      watch: {
        /**
         * 数据变化后 高度自适应
         */
        tableList() {
          this.$nextTick(() => {
            this.changeTableHight();
          });
        },
      },
      methods: {
        /**
         * 选择框选择后更改,事件分发
         */
        selectionChange(selection) {
          this.$emit("selection-change", selection);
        },
        /**
         * 点击事件
         */
        rowClick(row, column, event) {
          this.$emit("row-click", row, column, event);
        },
        /**
         * 高度自适应
         * 当表格展示空间小于460按460px展示,大于的时候高度填充
         */
        changeTableHight() {
          if (this.height) {
            //如果有传进来高度就取消自适应
            this.inTableHeight = this.height;
            this.$refs.table.doLayout();
            return;
          }
          let tableHeight = window.innerHeight || document.body.clientHeight;
          //高度设置
          let disTop = this.$refs.table.$el;
          //如果表格上方有元素则减去这些高度适应窗口,66是底下留白部分
          tableHeight -= disTop.offsetTop + 26;
          if (disTop.offsetParent) tableHeight -= disTop.offsetParent.offsetTop;
          this.inTableHeight = tableHeight < 460 ? 460 : tableHeight;
          //重绘表格
          this.$refs.table.doLayout();
        },
      },
    };
    </script>
    <style>
    .changeColorYellow {
      color: rgb(206, 206, 169);
    }
    </style>
    View Code

    2.使用

    // testPage.vue

    普通表格内容的使用

    二级表头使用

     3.补充——其他版本的render抽象

    上代码

    // lineCom.vue

    <template>
      <div class="lineCom">
        <template v-for="(itm, idx) in header">
          <div v-if="itm.render" :key="idx">
              <ex-slot
                :render="itm.render"
                :column="itm"
              />
          </div>
        </template>
      </div>
    </template>
    
    <script>
    // 自定义内容的组件
    var exSlot = {
      functional: true,
      props: {
        row: Object,
        render: Function,
        index: Number,
        column: {
          type: Object,
          default: null,
        },
      },
      render: (h, context) => {
        // const params = {
        //   row: context.props.row,
        //   index: context.props.index,
        // };
        // if (context.props.column) params.column = context.props.column;
        return context.props.render(h, context.props.column);
      },
    };
    
    export default {
      components: { exSlot },
      props: {
        header: {
          type: Array,
          default: () => [],
        },
      },
    };
    </script>
    View Code

    // lineComTable.js

    // 使用

    人生到处知何似,应似飞鸿踏雪泥。
  • 相关阅读:
    去深圳办理港澳通行证签注延期
    預約申領往來港澳通行證及簽注x
    表格选中效果展示
    Purchase购物车实例分析
    IOS开发基础知识--碎片17
    IOS开发基础知识--碎片16
    IOS开发基础知识--碎片15
    IOS开发基础知识--碎片14
    IOS关于LKDBHelper实体对象映射插件运用
    IOS开发基础知识--碎片13
  • 原文地址:https://www.cnblogs.com/lepanyou/p/15384942.html
Copyright © 2011-2022 走看看