在vue.js中动态添加元素

时间:2016-11-15 22:28:23

标签: javascript vue.js vuejs2

tl; dr :我正在生成一个包含可编辑单元格的表格,类似于下图所示。我有它所以单元格是可编辑的和总更新,但我正在努力弄清楚我需要遵循实际添加新行和列的过程。

enter image description here

最终用户可以编辑除总计之外的所有单元格,例如单元格[ex1] [item1]可以从100更改为150,然后会导致一个事件,该更新将从该行更新该行的总数320至370。

最初我在HTML文件中定义主模板...

<div class="container" id="app">

    <script type="text/x-template" id="datagrid-template">
        <table class="table-striped">
            <thead>
                <headerrow v-bind:columns="columns"></headerrow>
            </thead>

            <tbody>
            <datarow v-for="row in rows" v-bind:columns="columns" v-bind:data="row"></datarow>
            </tbody>
        </table>
    </script>

    <div class="row">
        <div class="col-sm-10">
            <datagrid v-bind:columns="columns" v-bind:data="rows"></datagrid>
        </div>
        <div class="col-sm-2">
            <div class="row">
                <button type="button" v-on:click="addColumn()">Add Column</button>
            </div>
            <div class="row">
                <button type="button" v-on:click="addRow()">Add Row</button>
            </div>
        </div>
    </div>
</div>

在JS文件中,我初始化主要的Vue元素......

var app = new Vue({
  el: "#app",
  data: {
    categories: [...],
    companies: [...]
  },
  methods: {
    addRow: function() {
      console.log(this.$children[0]);
    },
    addColumn: function() {
      this.$children[0].columns.push({value: 'test'});
    }
  }
});

然后我有6种主要的不同组件类型:

  • datainput(通用输入单元格)
  • dataheader(扩展datainput)
  • datacell(扩展数据输出)
  • baserow(表中的行)
  • headerrow(扩展baserow,由数据头组成)
  • datarow(扩展baserow,由数据中心组成)

我添加了一行,细胞就这样

baserow

var baseRow = {
  render: function(createElement) {
    return createElement('tr', {}, this.getProps(createElement));
  },
  props: {...}
  }
};

headerrow

Vue.component('headerrow', {
  mixins: [baseRow],
  methods: {
    getProps: function(createElement) {
      var comps = [];
      this.$options.propsData.columns.forEach(function(el) {
        comps.push(createElement('dataheader', {
          props: {...}
        }));
      });
      return comps;
    }
  }
});

当我点击添加列时,我可以看到&#39;测试&#39;使用chrome扩展程序查看<datagrid>时,会添加到列prop中。另外,我看到了&#39;测试&#39;添加到<headerrow>列prop,但实际上并未生成UI中的任何内容。我假设这是我最初渲染行和列的结果,而且我只是有一些基本的误解......任何人都可以提供一些方向,就我出错的地方和地点而言?

enter image description here

2 个答案:

答案 0 :(得分:1)

所以这是一个根本的误解。为此,数据必须与道具一起使用。最初,必须将这些值作为支柱附加,然后将支柱分配给数据值。以下示例突出显示了我要做的事情。

var baseRow = {
  render: function(createElement) {
    return createElement('tr', this.createCells(createElement));
  },
  props: {
    initColumns: {
      type: Array,
      default: []
    },
    initData: {
      type: Object,
      default: null
    }
  },
  data: function() {
    return {
      columns: this.initColumns,
      data: this.initData
    }
  }
};

然后,要从主Vue对象(包含行组件)添加元素,您可以调用与this.columns.push({value: 'test'});类似的内容。这将更新列数据属性,并且还将更新UI。

根据我的理解,这是道具有one-way data flow的结果,而数据属性是被动的,这在this section of the docs中被否定了。

答案 1 :(得分:-1)

您不能在<tr>内使用<tbody>以外的任何内容。您可以使用Vue指令is在其中添加其他组件:

<tbody>
    <tr is="datarow" v-for="row in rows" v-bind:columns="columns" v-bind:data="row"></tr>
</tbody>