Vuejs,带有 editable 字段和双向数据绑定的动态 b-table

Vuejs, Dynamic b-table with editable fields and two-way databinding

我正在尝试使用 editable 字段和双向数据绑定生成动态 b-table。

我不想有任何硬编码值。现在,我有:

<b-table striped hover :items="filtered">
    <template v-slot:cell(issueDescription)="row">
      <b-form-input v-model="row.item.issueDescription" />
    </template>
    <template v-slot:cell(endTime)="row">
      <b-form-input v-model="row.item.endTime" />
    </template>
    <template v-slot:cell(startTime)="row">
      <b-form-input v-model="row.item.startTime" />
    </template>
</b-table>

其中:

filtered = [ { "issueDescription": "this is a description", "endTime": "2020-02-11T14:00:00.000Z", 
"startTime": "2020-02-11T01:24:00.000Z" }]

如果我用 v-for 生成模板,那么我在每一列中都有 editable 字段,但在每个字段上都没有绑定。

<b-table striped hover :items="filtered">
    <template v-for="x in filtered" v-slot:cell()="row">
      <b-form-input v-model="row.item.BIND_TO_SPECIFIC_TABLE_ROW_COL" />
    </template>
</b-table>

如何绑定到特定的行、列?

我做了一个fiddle:https://jsfiddle.net/gfhu1owt/

如果你想要所有字段编辑table,你可以使用这个语法。

<template v-slot:cell()="{ item, field: { key } }">
  <b-form-input v-model="item[key]" />
</template>

这与您所拥有的非常相似。您只需要使用插槽上下文对象中的 key。 (我已经简写了一点,但它与 row.field.key 相同)。 另请注意,我没有在模板中使用 v-for,这是因为 v-slot:cell() 是一个后备插槽,它对所有插槽都有效,除非定义了特定插槽。例如 v-slot:cell(issueDescription) 将覆盖 issueDescription 字段的 v-slot:cell()

虽然上述方法有效,但有一天当您有一个您不想编辑的字段时,问题可能会出现table,例如您的对象中的 id 字段。

为了解决这个问题,我定义了我的字段并将它们传递给 table。我还在我想编辑的字段中添加了 editable 属性table。 (请注意,这不是字段对象中的标准内容,而是针对您的用例的特定内容)。

然后我创建了一个计算 属性 editableFields 其中 returns 所有具有 editable: true 的字段,然后在我的 v-for 中使用 editableFields ]里面b-table.

通过这种方式,您可以选择要在对象中编辑的属性table。

new Vue({
  el: "#app",
  computed: {
    editableFields() {
      return this.fields.filter(field => field.editable)
    }
  },
  data: {
    filtered: [
      { 
        "id": "1",
        "issueDescription": "this is a description", 
        "endTime": "2020-02-11T14:00:00.000Z", 
        "startTime": "2020-02-11T01:24:00.000Z" 
      },
      { 
        "id": "2",
        "issueDescription": "this is a description", 
        "endTime": "2020-02-11T14:00:00.000Z", 
        "startTime": "2020-02-11T01:24:00.000Z" 
      }
    ],
    fields: [
      { key: 'id', label: 'ID' },
      { key: 'issueDescription', label: 'Issue Description', editable: true },
      { key: 'startTime', label: 'Start Time', editable: true },
      { key: 'endTime', label: 'End Time', editable: true }
    ]
  }
})
<link href="https://unpkg.com/bootstrap@4.4.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap-vue@2.4.1/dist/bootstrap-vue.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.4.1/dist/bootstrap-vue.min.js"></script>

<div id='app'>
  <b-table :items="filtered" :fields="fields">
    <template v-for="field in editableFields" v-slot:[`cell(${field.key})`]="{ item }">
      <b-input v-model="item[field.key]"/>
    </template>
  </b-table>
</div>