vue.js - Vuejs, Dynamic b-table with editable fields and two-way databinding
问题描述
I'm trying to generate a dynamic b-table with editable fields and with two-way databinding.
I would like to not have any hardcoded values. Now, I have:
<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>
Where:
filtered = [ { "issueDescription": "this is a description", "endTime": "2020-02-11T14:00:00.000Z",
"startTime": "2020-02-11T01:24:00.000Z" }]
If I generate template with a v-for, then I got editable fields in every column, but no binding at each field.
<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>
How do I bind to the specific row,col??
I've made a fiddle: https://jsfiddle.net/gfhu1owt/
解决方案
If you want to have ALL fields editable, you can use this syntax.
<template v-slot:cell()="{ item, field: { key } }">
<b-form-input v-model="item[key]" />
</template>
It's pretty similar to what you had. You just needed to use the key
from the slot context object. (I've shorthanded it a bit, but it's the same as going row.field.key
).
Also note that i don't use a v-for
in the template, this is because v-slot:cell()
is a fallback slot which is valid for all slots unless a specific one is defined. For example v-slot:cell(issueDescription)
would overwrite v-slot:cell()
for the issueDescription
field.
While the above works, the problem might come one day when you have a field you DONT want to be editable, like maybe an id
field in your object.
To solve this issue, I've defined my fields and passed them to the table. I've also added a editable
property to the fields i want to be editable. (note this is not a standard thing in the field object, but something specific for you use-case).
I then created a computed property editableFields
which returns all fields that have editable: true
, and then use editableFields
in my v-for
inside b-table
.
This way you can pick and choose which properties you want to be editable in your objects.
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>
推荐阅读
- python - jq + 更新json文件并根据ID号追加名称
- github - 如何在 GitHub Actions 工作流程中获取拉取请求编号
- json - 在颤动中多次将 json 数据添加到共享首选项
- vim - 复制字典以在 Vim 中注册
- python - 当多个输入可以为空时,在 Django 中使用 Q 进行过滤
- python - 在 Tensorflow-2 中训练 cifar10 数据的问题
- java - 使用 Spring 和 Thymeleaf 进行编辑
- scala - 递归列出文件并按扩展名过滤
- html - 表格单元格宽度不适用于一个单元格!我该如何解决?
- java - Java 和 MapStruct