我有一个 Vue 3.0 应用。在这个应用程序中,我有以下内容:
export default {
data() {
return {
selected: null,
departments: [
{
name: 'Sports',
items: [
{ id:'1', label: 'Football', value:'football' },
{ id:'2', label: 'Basketball', value:'basketball' },
]
},
{
name: 'Automotive',
versions: [
{ id:'3', label: 'Oil', value:'oil' },
{ id:'4', label: 'Mud Flaps', value:'mud-flaps' },
]
}
]
};
}
};
我需要在下拉列表中呈现这些项目。值得注意的是,项目需要按部分呈现。为了做到这一点,我使用了 Bootstrap's dropdown headers。我的挑战是,HTML 需要以一种我无法使用 Vue 的方式呈现。我需要像这样呈现我的 HTML:
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<li><h6 class="dropdown-header">Sports</h6></li>
<li><a class="dropdown-item" href="#">Football</a></li>
<li><a class="dropdown-item" href="#">Basketball</a></li>
<li><h6 class="dropdown-header">Automotive</h6></li>
<li><a class="dropdown-item" href="#">Oil</a></li>
<li><a class="dropdown-item" href="#">Mud Flaps</a></li>
</ul>
基于这种需要,我必须有一个嵌套的 for 循环。在伪代码中,它会是这样的:
foreach department in departments
<li><h6 class="dropdown-header">{{ department.name }}</h6></li>
foreach item in department.items
<li><a class="dropdown-item" href="#">{{ item.label }} </a></li>
end foreach
end foreach
我知道我可以用雷蛇之类的东西来做到这一点。但是,我无论如何都看不到在 Vue 中这样做。然而,我不得不相信我忽略了一些东西,因为呈现层次结构是一种常见的需求。如何在不改变数据结构的情况下在 Vue 中渲染层次结构?
谢谢。
答案 0 :(得分:2)
像这样使用嵌套的 v-for:
<template v-for="(department , i) in departments">
<li><h6 class="dropdown-header" :key="`head-${i}`">{{ department.name }}</h6></li>
<template v-for="(item , j) in department.items">
<li><a class="dropdown-item" href="#" :key="`sub-${i}${j}`">{{ item.label }} </a></li>
</template>
</template>
答案 1 :(得分:1)
您可以在 v-for
的帮助下嵌套 template
,并确保 key
与元素的绑定是唯一的(这必须是唯一的,这样您就不会从 vue 中获得奇怪的行为)。
运行下面的代码并检查结果(点击全屏查看呈现的完整列表):
// you can ignore this line
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
departments: [{
name: 'Sports',
items: [{
id: '1',
label: 'Football',
value: 'football'
},
{
id: '2',
label: 'Basketball',
value: 'basketball'
},
]
},
{
name: 'Automotive',
items: [{
id: '3',
label: 'Oil',
value: 'oil'
},
{
id: '4',
label: 'Mud Flaps',
value: 'mud-flaps'
},
]
}
],
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<template v-for="({name, items}, i) in departments">
<li :key="`header-${i}`">
<h6 class="dropdown-header">{{ name }}</h6>
</li>
<li v-for="{label, id} in items" :key="`link-${id}`">
<a class="dropdown-item" href="#">{{ label }}</a>
</li>
</template>
</ul>
</div>
答案 2 :(得分:0)
一种方法是使用计算方法。我创建了一个 jsfiddle here。
computed: {
departmentItems() {
const items = [];
this.departments.forEach(department => {
items.push({
label: department.name,
class: 'dropdown-header',
});
department.items.forEach(item => {
items.push({
label: item.label,
class: 'dropdown-item'
})
})
})
return items;
}
}
这里的重要部分是,我们有一个用于下拉标题和下拉项目的通用模型。
答案 3 :(得分:0)
您在 computed
属性中构建数据,然后使用 v-for
遍历列表。下面是一个例子:
new Vue({
el: "#app",
data() {
return {
selected: null,
departments: [
{
name: 'Sports',
items: [
{ id:'1', label: 'Football', value:'football' },
{ id:'2', label: 'Basketball', value:'basketball' },
]
},
{
name: 'Automotive',
items: [
{ id:'3', label: 'Oil', value:'oil' },
{ id:'4', label: 'Mud Flaps', value:'mud-flaps' },
]
}
]
}
},
computed: {
departmentsItem: function() {
return this.departments.reduce((acc,department) =>
[
...acc,
{ type: "department", name: department.name },
...department.items.map(item => ({ type: "item", name: item.label }))
]
, []);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<li v-for="(departmentItem,i) in departmentsItem" :key="i">
<h6
v-if="departmentItem.type==='department'" class="dropdown-header"
>{{departmentItem.name}}</h6>
<a
v-else-if="departmentItem.type==='item'" class="dropdown-item" href="#"
>{{departmentItem.name}}</a>
</li>
</ul>
</div>