我是使用VueJS和组件的新手,并且正在为不限级别的项目构建嵌套清单。
嵌套列表将可折叠,因此我想在每个列表的父级上显示状态。如果所有孩子(和儿童孩子等)都选中,则为绿色;如果仅选中其中一些,则为黄色。
我很难弄清楚如何在Vue中检查此内容,而没有每次循环遍历每个项目的常规javascript解决方案。我觉得必须有一个更清洁,更省力的解决方案。
在下面的代码片段中,您可以看到我在组件上使用的是“ childstatus”方法,以检查第一组子级上的状态,但这并没有完全消失。在示例中,您将看到Subitem 1-3-1被选中,Subitem 1-3为黄色,我也希望Item 1也为黄色。列表中的项目可以移动,也可以添加新项目,因此,我希望此操作尽可能自动进行,而不必每次都遍历所有项目,因为这些列表可能会变得很长很深。
Vue.component('checkin-list', {
template: `
<draggable :element="'ul'" class="checkin__list" :list="checklist" :options="{group:{ name: 'dragger' }}">
<li v-for="(item,index) in checklist" :key="item.id">
<div class="checkin__item" :status="childstatus(item)">
<input type="checkbox" v-model="item.check">
{{ item.naam }}
</div>
<checkin-list :checklist="item.checklist" :mode="mode" :type="type"></checkin-list>
</li>
</draggable>
`,
props: {
checklist: Array
},
methods: {
childstatus: (item) => {
let info = {
children: false,
checked: false,
children_all_checked: false,
children_some_checked: false
};
if (item.check) {
info.checked = true;
}
if (item.checklist.length) {
info.children = true;
if (item.checklist.some(x => x.check)) {
info.children_some_checked = true;
if (item.checklist.every(x => x.check)) {
info.children_all_checked = true;
}
}
}
if (!info.children) {
if (!info.checked) {
return 0;
} else {
return 1;
}
} else {
if (info.children_all_checked) {
if (info.checked) {
return 5;
} else {
return 4;
}
} else if (info.children_some_checked || info.checked) {
return 3;
} else {
return 2;
}
}
}
}
});
var items = {
"results": [{
"id": 1,
"naam": "Item 1",
"check": 0,
"checklist": [{
"id": 2,
"naam": "Subitem 1 - 1",
"check": 0,
"checklist": []
}, {
"id": 3,
"naam": "Subitem 1 - 2",
"check": 0,
"checklist": []
}, {
"id": 4,
"naam": "Subitem 1 - 3",
"check": 0,
"checklist": [{
"id": 5,
"naam": "Subitem 1 - 3 - 1",
"check": 1,
"checklist": []
}]
}, {
"id": 6,
"naam": "Subitem 1 - 4",
"check": 0,
"checklist": []
}]
}, {
"id": 7,
"naam": "Item 2",
"check": 0,
"checklist": []
}]
}
new Vue({
el: "#app",
data: {
checklist: items.results
}
})
body {
background: #fff;
font-family: Helvetica;
}
#app {
padding: 10px;
transition: all 0.2s;
}
ul { list-style: none; }
li {
margin: 8px 0;
}
.checkin__list {
padding-left: 20px;
padding-bottom: 10px;
}
.checkin__item[status="1"],
.checkin__item[status="5"] {
background-color: #abeab4;
}
/* green */
.checkin__item[status="3"],
.checkin__item[status="4"] {
background-color: #f6f5a7;
}
/* yellow */
<div id="app">
<checkin-list :checklist="checklist"></checkin-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.min.js"></script>
<script src="https://cdn.rawgit.com/David-Desmaisons/Vue.Draggable/master/dist/vuedraggable.js"></script>
或检查JSFiddle:https://jsfiddle.net/8b1yfj0x/16/
答案 0 :(得分:0)
虽然我没有按照最初的想法解决问题,但确实创建了解决方案。
我重写了该函数,以便在(嵌套的)子级中始终可以使用1级父级的id。当孩子更新时,它会在提及该ID时发出事件。然后,在主要元素上,Vue方法从该id开始,并沿其所有子级向下确定状态。当任何变化时,我只是再次发出该变化。