英文:
Vue - pass down slots to child components
问题
我想从Vuetify创建一个可重用的数据表格组件。某些列可能包含v-slot
以修改该列内的数据。例如:我将用户角色存储为整数,并希望它们在表格中显示为用户
或管理员
。目前,我是通过以下v-slot
来实现的:
<template v-slot:item.role="{ item }">
{{ (item.role === 1) ? 'Administrator' : 'User' }}
</template>
因为这不是每个数据表格的使用情况,我想从使用数据表格的父组件中传递这些v-slot
。我的数据表格组件目前如下所示:
<template>
<v-data-table :headers="headers" :items="items">
<template v-slot:item.role="{ item }">
{{ (item.role === 1) ? 'Administrator' : 'User' }}
</template>
<template v-slot:item.action="{ item }">
<v-icon @click="deleteItem(item)" small>fas fa-trash</v-icon>
</template>
</v-data-table>
</template>
<script>
export default {
name: "DataTable",
props: {
title: String,
headers: Array,
items: Array
},
methods: {
deleteItem(item) {
this.$emit("clicked", item);
}
}
};
</script>
这是我使用DataTable的组件(UserTable.vue):
<template>
<DataTable :title="title" :headers="headers" :items="items" @clicked="onDelete" />
</template>
<script>
import DataTable from "../../../components/DataTable";
import axios from "axios";
export default {
name: "UserTable",
components: {
DataTable
},
props: {
items: Array
},
data: () => ({
title: "Users",
headers: [
{
text: "Name",
value: "name"
},
{
text: "Email",
value: "email"
},
{
text: "Role",
value: "role"
},
{ text: "Actions", value: "action", sortable: false }
]
}),
methods: {
onDelete(item) {
this.$emit("clicked", item);
}
}
};
</script>
在理想情况下,我希望在UserTable组件中像这样使用它:
<template>
<DataTable :title="title" :headers="headers" :items="items" @clicked="onDelete">
<template v-slot:item.role="{ item }">
{{ (item.role === 1) ? 'Administrator' : 'User' }}
</template>
<template v-slot:item.action="{ item }">
<v-icon @click="deleteItem(item)" small>fas fa-trash</v-icon>
</template>
</DataTable>
</template>
然后,将DataTable保持简洁和简单,像这样:
<template>
<v-data-table :headers="headers" :items="items">
<slot></slot>
</v-data-table>
</template>
但显然这不像我预期的那样工作,因为现在它不会显示所需列中的任何内容。我创建了一个CodeSandbox,让您看看我现在的情况:
有人可以告诉我为什么我的方法不起作用,或者我如何修复这个问题吗?
英文:
I want to make a reusable Data Table component from Vuetify. Some columns could contain v-slot
to modify the data inside that column. For example: I store the user roles as integers and want them displayed as user
or adminin the table. Currently I do this with this
v-slot`:
<template v-slot:item.role="{item} ">
{{ (item.role === 1) ? 'Administrator' : 'User' }}
</template>
Because this will not be the use-case for every Data Table I want to pass these v-slot
from a parent component which uses the Data Table. My Data Table component currently looks like this:
<template>
<v-data-table :headers="headers" :items="items">
<template v-slot:item.role="{item} ">
{{ (item.role === 1) ? 'Administrator' : 'User' }}
</template>
<template v-slot:item.action="{ item }">
<v-icon @click="deleteItem(item)" small>fas fa-trash</v-icon>
</template>
</v-data-table>
</template>
<script>
export default {
name: "DataTable",
props: {
title: String,
headers: Array,
items: Array
},
methods: {
deleteItem(item) {
this.$emit("clicked", item);
}
}
};
</script>
And this is the component (UserTable.vue) where I use the DataTable:
<template>
<DataTable :title="title" :headers="headers" :items="items" @clicked="onDelete" />
</template>
<script>
import DataTable from "../../../components/DataTable";
import axios from "axios";
export default {
name: "UserTable",
components: {
DataTable
},
props: {
items: Array
},
data: () => ({
title: "Users",
headers: [
{
text: "Name",
value: "name"
},
{
text: "Email",
value: "email"
},
{
text: "Role",
value: "role"
},
{ text: "Actions", value: "action", sortable: false }
],
}),
methods: {
onDelete(item) {
this.$emit("clicked", item);
}
}
};
</script>
In an ideal situation I would like to have it something like this in the UserTable component:
<template>
<DataTable :title="title" :headers="headers" :items="items" @clicked="onDelete">
<template v-slot:item.role="{item} ">
{{ (item.role === 1) ? 'Administrator' : 'User' }}
</template>
<template v-slot:item.action="{ item }">
<v-icon @click="deleteItem(item)" small>fas fa-trash</v-icon>
</template>
</DataTable>
</template>
And then keep the DataTable clean and simple like this:
<template>
<v-data-table :headers="headers" :items="items">
<slot></slot>
</v-data-table>
</template>
But that obviously doesn't seem to work as I expected because it doesn't show anything in the desired columns now. I created a CodeSandBox to let you see how I have it now:
https://codesandbox.io/s/priceless-bohr-oxu18?fontsize=14&hidenavigation=1&theme=dark
Can someone tell me why my approach doesn't work or how I might fix this?
答案1
得分: 4
我通过查看这个答案成功修复了这个问题:
https://stackoverflow.com/a/52823029/7603806
我在我的DataTable
组件中添加了上面的代码,并现在从使用DataTable
的UserTable
组件中传递插槽。
英文:
I managed to fix this by looking at this answer:
https://stackoverflow.com/a/52823029/7603806
<template v-for="slot in Object.keys($scopedSlots)" :slot="slot" slot-scope="scope"><slot :name="slot" v-bind="scope"/></template>
I added the code above in my DataTable
component and pass the slots now from the UserTable
component which uses the DataTable
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论