Runtime environment

Iview version: 3.5.0-RC. 1 VUE version: 2.6.10

The problem



height



height:100%



But most of the time we need the table to fill the parent container, we need the table header and footer to be fixed, and only the middle part of the data to scroll.

If you open Elements in Chrome, you can see that iView uses the Object tag. In HTML, you can only listen for window resize events. You can’t directly listen for div size changes, but sometimes you can insert an object tag to listen for div size changes indirectly. Does it use object here to listen for size changes?



The source code of the iview
width
height
height:100%

The solution

The iView uses the Element-resize-Detector library to listen for changes to the outer divs and set this library to the component’s global variables. So we can also use this global variable to listen for the outer div size and dynamically set height.

Create a FillTable component, used to wrap Table, filltable.js source code is as follows:

FillTable

import { Table } from 'iview';
export default {
  name: 'fill-table',
  render(h) {
    /** pass prop */
    const tableProps = {};
    for (let prop in Table.props) {
      tableProps[prop] = this[prop];
    }
    tableProps.height = this.tableHeight;

    return h(Table, {
      props: tableProps,
      ref: 'table'./** Pass events */
      on: this.$listeners,
      /** pass scope slot */
      scopedSlots: this.$scopedSlots,
      /** pass slot */
      slot: this.$slot
    });
  },
  props: (() = > {
    var props = {};
    Object.assign(props, Table.props, {
      height: {
        type: Number
      },
      /** fills the parent container */ by default
      fill: {
        type: Boolean.default: true}});returnprops; }) (),watch: {
    height: {
      handler() {
        this.tableHeight = this.height; }},immediate: true
  },
  data() {
    // Built-in attribute values
    return {
      tableHeight: 0
    };
  },
  methods: {
    handleIViewTableResize(el) {
      this.tableHeight = el.offsetHeight;
    },
    getTableRef() {
      return this.$refs.table;
    }
  },
  mounted() {
    if (this.fill) {
      // this.$nextTick(() => {
        this.getTableRef().observer.listenTo(this.$el, this.handleIViewTableResize);
      // });
    }
    /** pass method */
    for (let method in Table.methods) {
      this[method] = (. args) = > Table.methods[method].apply(this.getTableRef(), args);
    }
  },

  beforeDestroy() {
    if (this.fill) {
      this.getTableRef().observer.removeListener(this.$el, this.handleIViewTableResize); }}};Copy the code

use

When used, the attributes and methods of the table in iView are basically the same, except the following:

  • Add v-bind:fill. The default value is true. Do not set v-bind:height to true. If set to true, the table style is supportedheight:100%Style.
  • If needV - bind: height = a fixed value, you need tov-bind:fill="false"
  • If you need to find a table component instance, usegetTableRefMethods, such asthis.refs.table.getTableRef() 。
      <FillTable
        ref="table"
        style="width:100%; height:100%"
        :columns="columns1"
        :data="data1"
        :fill="true"
      >
        <template #name="{ row }">
          <strong>{{ row.name }}--ddd</strong>
        </template>
      </FillTable>
Copy the code

Matters needing attention

Since this is an intrusive change, if iView changes the source code, such as removing the global field from the Observer, this will cause an error. In this case, you can directly reference the element-resize detector to listen for Table size changes.

demo



Meteor199. Making. IO/my – demo/vue…



Github.com/meteor199/m…