带有Vuetify数据表的动态可编辑列
我正在尝试制作一个VUE数据表组件,我想制作它,以便如果您传递了一系列列名,这些列中的值将像此示例。我目前正在尝试循环循环到将组件传递给组件的阵列prop ...
<template
v-for="(column, index) in editableColumns"
v-slot:[getEditableColumn(column)]="props"
>
<v-edit-dialog
:return-value.sync="props.item.desk"
@save="save"
@cancel="cancel"
@open="open"
@close="close"
:key="index"
>
{{ props.item.desk }}
<template v-slot:input>
<v-text-field
v-model="props.item.desk"
label="Edit"
single-line
counter
></v-text-field>
</template>
</v-edit-dialog>
</template>
getable列的运行方式:
getEditableColumn(column) {
console.log(column);
return `item.${column}`;
},
它基本上返回了我想编辑的列的值。 /code>但该功能永远不会运行,我确实必须提到,如果我直接通过这样的名称而无需循环,但是我希望它能动态起作用,因为我将在具有不同列名称的多个位置使用该表,我不想让它们所有列可编辑。
下面我附上了组件的完整代码。
<template>
<v-card>
<v-card-title>
{{ title || "" }}
<v-col>
<v-btn icon color="black" v-if="refresh">
<v-icon>mdi-refresh</v-icon>
</v-btn>
<v-btn icon color="black" v-if="exportExcel" @click="exportToXlsx">
<v-icon>mdi-microsoft-excel</v-icon>
</v-btn>
<v-btn icon color="black" v-if="exportPdf">
<v-icon>mdi-file-pdf-box</v-icon>
</v-btn>
<v-btn icon color="black" v-if="fontSizeControlls">
<v-icon>mdi-format-font-size-decrease</v-icon>
</v-btn>
<v-btn icon color="black" v-if="fontSizeControlls" @click="logSelected">
<v-icon>mdi-format-font-size-increase</v-icon>
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col v-if="searchBar">
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
outlined
dense
></v-text-field>
</v-col>
</v-card-title>
<v-data-table
@input="(selected) => $emit('selected', selected)"
@click:row="rowClickFunction"
v-model="selected"
:headers="headers"
:items="data"
:search="search"
:show-select="showSelect"
:single-select="singleSelect"
:height="height"
:items-per-page="itemsPerPage"
:item-key="itemKey"
dense
>
<!-- Pass template elements inside the component call to render custom components inside the table -->
<template
v-for="slot in Object.keys($scopedSlots)"
:slot="slot"
slot-scope="scope"
>
<slot :name="slot" v-bind="scope" />
</template>
<template
v-for="(column, index) in editableColumns"
v-slot:[getEditableColumn(column)]="props"
>
<v-edit-dialog
:return-value.sync="props.item.desk"
@save="save"
@cancel="cancel"
@open="open"
@close="close"
:key="index"
>
{{ props.item.desk }}
<template v-slot:input>
<v-text-field
v-model="props.item.desk"
label="Edit"
single-line
counter
></v-text-field>
</template>
</v-edit-dialog>
</template>
</v-data-table>
</v-card>
</template>
<script>
import { utils, writeFile } from "xlsx";
export default {
props: {
headers: Array,
data: Array,
title: String,
height: String,
itemsPerPage: Number,
itemKey: String,
searchBar: { tpye: Boolean, default: false },
rowClickFunction: {
type: Function,
default: () => {},
},
editableColumns: {
type: Array,
},
refresh: {
type: Boolean,
default: false,
},
exportExcel: {
type: Boolean,
default: false,
},
exportPdf: {
type: Boolean,
default: false,
},
fontSizeControlls: {
type: Boolean,
default: false,
},
singleSelect: {
type: Boolean,
default: false,
},
showSelect: {
type: Boolean,
default: false,
},
xlsxName: {
type: String,
default: "Sheet.xlsx",
},
},
data() {
return {
search: "",
selected: [],
dialog: false,
};
},
methods: {
exportToXlsx() {
const worksheet = utils.json_to_sheet(this.data);
const workbook = utils.book_new();
utils.book_append_sheet(workbook, worksheet, "Data");
writeFile(workbook, this.xlsxName);
},
getEditableColumn(column) {
console.log(column);
return `item.${column}`;
},
logSelected() {
console.log(this.selected);
},
logRow(row) {
console.log(row);
console.log(this.selected);
},
getSlotName(slot) {
return `${slot}.slotName`;
},
save() {
this.snack = true;
this.snackColor = "success";
this.snackText = "Data saved";
},
cancel() {
this.snack = true;
this.snackColor = "error";
this.snackText = "Canceled";
},
open() {
this.snack = true;
this.snackColor = "info";
this.snackText = "Dialog opened";
},
close() {
console.log("Dialog closed");
},
},
};
</script>
I am trying to make a vue data table component, I want to make it so that if you pass an array of column names, the values in those columns will be editable like in this example. I am currently trying to loop through the array prop passed to the component like as so...
<template
v-for="(column, index) in editableColumns"
v-slot:[getEditableColumn(column)]="props"
>
<v-edit-dialog
:return-value.sync="props.item.desk"
@save="save"
@cancel="cancel"
@open="open"
@close="close"
:key="index"
>
{{ props.item.desk }}
<template v-slot:input>
<v-text-field
v-model="props.item.desk"
label="Edit"
single-line
counter
></v-text-field>
</template>
</v-edit-dialog>
</template>
the get editable columns operates as such:
getEditableColumn(column) {
console.log(column);
return `item.${column}`;
},
it basically returns the value of the column I want to be editable as such item.columnName
but the function never runs, I do have to mention that if I pass directly the name like this without a for loop it works, but I want this to work dynamically as I will use the table in multiple places with different column names, and I don't want to make them all columns editable editable.
Below I have attached the full code of the component.
<template>
<v-card>
<v-card-title>
{{ title || "" }}
<v-col>
<v-btn icon color="black" v-if="refresh">
<v-icon>mdi-refresh</v-icon>
</v-btn>
<v-btn icon color="black" v-if="exportExcel" @click="exportToXlsx">
<v-icon>mdi-microsoft-excel</v-icon>
</v-btn>
<v-btn icon color="black" v-if="exportPdf">
<v-icon>mdi-file-pdf-box</v-icon>
</v-btn>
<v-btn icon color="black" v-if="fontSizeControlls">
<v-icon>mdi-format-font-size-decrease</v-icon>
</v-btn>
<v-btn icon color="black" v-if="fontSizeControlls" @click="logSelected">
<v-icon>mdi-format-font-size-increase</v-icon>
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col v-if="searchBar">
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
outlined
dense
></v-text-field>
</v-col>
</v-card-title>
<v-data-table
@input="(selected) => $emit('selected', selected)"
@click:row="rowClickFunction"
v-model="selected"
:headers="headers"
:items="data"
:search="search"
:show-select="showSelect"
:single-select="singleSelect"
:height="height"
:items-per-page="itemsPerPage"
:item-key="itemKey"
dense
>
<!-- Pass template elements inside the component call to render custom components inside the table -->
<template
v-for="slot in Object.keys($scopedSlots)"
:slot="slot"
slot-scope="scope"
>
<slot :name="slot" v-bind="scope" />
</template>
<template
v-for="(column, index) in editableColumns"
v-slot:[getEditableColumn(column)]="props"
>
<v-edit-dialog
:return-value.sync="props.item.desk"
@save="save"
@cancel="cancel"
@open="open"
@close="close"
:key="index"
>
{{ props.item.desk }}
<template v-slot:input>
<v-text-field
v-model="props.item.desk"
label="Edit"
single-line
counter
></v-text-field>
</template>
</v-edit-dialog>
</template>
</v-data-table>
</v-card>
</template>
<script>
import { utils, writeFile } from "xlsx";
export default {
props: {
headers: Array,
data: Array,
title: String,
height: String,
itemsPerPage: Number,
itemKey: String,
searchBar: { tpye: Boolean, default: false },
rowClickFunction: {
type: Function,
default: () => {},
},
editableColumns: {
type: Array,
},
refresh: {
type: Boolean,
default: false,
},
exportExcel: {
type: Boolean,
default: false,
},
exportPdf: {
type: Boolean,
default: false,
},
fontSizeControlls: {
type: Boolean,
default: false,
},
singleSelect: {
type: Boolean,
default: false,
},
showSelect: {
type: Boolean,
default: false,
},
xlsxName: {
type: String,
default: "Sheet.xlsx",
},
},
data() {
return {
search: "",
selected: [],
dialog: false,
};
},
methods: {
exportToXlsx() {
const worksheet = utils.json_to_sheet(this.data);
const workbook = utils.book_new();
utils.book_append_sheet(workbook, worksheet, "Data");
writeFile(workbook, this.xlsxName);
},
getEditableColumn(column) {
console.log(column);
return `item.${column}`;
},
logSelected() {
console.log(this.selected);
},
logRow(row) {
console.log(row);
console.log(this.selected);
},
getSlotName(slot) {
return `${slot}.slotName`;
},
save() {
this.snack = true;
this.snackColor = "success";
this.snackText = "Data saved";
},
cancel() {
this.snack = true;
this.snackColor = "error";
this.snackText = "Canceled";
},
open() {
this.snack = true;
this.snackColor = "info";
this.snackText = "Dialog opened";
},
close() {
console.log("Dialog closed");
},
},
};
</script>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
插槽名称必须是标题元素的值之一
The slot name must be one of the headers element's value