简体   繁体   English

有关Vue.js 2中的阵列反应性的查询

[英]Inquiry regarding array reactivity in Vue.js 2

I have written a grid component that supports child rows, ie a togglable row with a cell that spans the entire width of the table, under each normal row. 我编写了一个网格组件 ,该组件支持子行,即在每个正常行下具有可跨越表格整个宽度的单元格的可翻转行。 In order to keep track of the child rows state I am using a data property called openChildRows which defaults to an empty array. 为了跟踪子行的状态,我使用了一个名为openChildRows的数据属性,该属性默认为空数组。 When the user clicks on the toggle icon which is present on the first column of each row, the child row of that row opens. 当用户单击每行第一列上的切换图标时,该行的子行将打开。 An additional click closes it. 再次单击将其关闭。 The openChildRows array contains the ids of the open rows. openChildRows数组包含打开的行的ID。

The issue I am having is that when I use a component for the child row, all open rows that come after the one toggled will be remounted. 我遇到的问题是,当我在子行中使用组件时,切换的所有打开的行都将被重新安装。 This is clearly inefficient, especially if the child row component sends an ajax request when mounted. 这显然是低效的,尤其是如果子行组件在安装时发送ajax请求。 Ideally, what I would want is that only the new child row will be mounted. 理想情况下,我想要的是仅安装新的子行。

I have written the grid using JSX for templates. 我已经使用JSX作为模板编写了网格。 Below is the relevant code: 下面是相关代码:

Rows template: 行模板:

module.exports = function(h, that) {
    var rows = [];
    var columns;
    var rowKey = that.opts.uniqueKey;

    var rowClass;
    var data = that.source=='client'?that.filteredData:that.tableData;
    var recordCount = (that.Page-1) * that.limit;

    data.map(function(row, index) {

      index = recordCount + index + 1;

      columns = [];

      if (that.hasChildRow) {
        var childRowToggler = <td><span on-click={that.toggleChildRow.bind(that,row[rowKey])} class={`VueTables__child-row-toggler ` + that.childRowTogglerClass(row[rowKey])}></span></td>;
        if (that.opts.childRowTogglerFirst) columns.push(childRowToggler);
      }


      that.allColumns.map(function(column) {
          let rowTemplate = that.$scopedSlots && that.$scopedSlots[column];

          columns.push(<td class={that.columnClass(column)}>
            {rowTemplate ? rowTemplate({ row, column, index }) : that.render(row, column, index, h)}
        </td>)
      }.bind(that));

      if (that.hasChildRow && !that.opts.childRowTogglerFirst) columns.push(childRowToggler);

      rowClass = that.opts.rowClassCallback?that.opts.rowClassCallback(row):'';

      rows.push(<tr class={rowClass} on-click={that.rowWasClicked.bind(that, row)} on-dblclick={that.rowWasClicked.bind(that, row)}>{columns} </tr>);

    // Below is the code that renders open child rows
      if (that.hasChildRow && this.openChildRows.includes(row[rowKey])) {

        let template = this._getChildRowTemplate(h, row);

        rows.push(<tr class='VueTables__child-row'><td colspan={that.allColumns.length+1}>{template}</td></tr>);
      }

    }.bind(that))

    return rows;

}

Toggle method code: 切换方法代码:

  module.exports = function (rowId, e) {

  if (e) e.stopPropagation();

  if (this.openChildRows.includes(rowId)) {
    var index = this.openChildRows.indexOf(rowId);
    this.openChildRows.splice(index,1);
  } else {
    this.openChildRows.push(rowId);
  }
};

The _getChildRowTemplate method: _getChildRowTemplate方法:

module.exports = function (h, row) {
  // scoped slot
  if (this.$scopedSlots.child_row) return this.$scopedSlots.child_row({ row: row });

  var childRow = this.opts.childRow;

  // render function
  if (typeof childRow === 'function') return childRow.apply(this, [h, row]);

  // component
  return h(childRow, {
    attrs: {
      data: row
    }
  });
};

I changed: 我变了:

if (that.hasChildRow && this.openChildRows.includes(row[rowKey])) {

        let template = this._getChildRowTemplate(h, row);

        rows.push(<tr class='VueTables__child-row'><td colspan={that.allColumns.length+1}>{template}</td></tr>);
}

to: 至:

  rows.push(that.hasChildRow && this.openChildRows.includes(row[rowKey])?
    <tr class='VueTables__child-row'><td colspan={that.allColumns.length+1}>{this._getChildRowTemplate(h, row)}</td></tr>:h());

And voila! 瞧!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM