Mr.*_*Web 5 javascript vue.js vuejs2
我正在尝试实现一个层次结构树,其中我有一个用户列表,并为每个用户设置了一个“高级”,因此它定义了谁是高级用户。这就是我试图解决问题的方式:
这就是我正在做的:
data(){
return{
users: [{
id: 1,
fname: 'Joe',
lname: 'Smith',
title: 'Super-Senior',
senior_id: 0,
}, {
id: 2,
fname: 'Bill',
lname: 'Simons',
title: 'Junior-1',
senior_id: 0,
}];
}
},
methods: {
juniors(senior) {
return this.users.filter((user) =>
user.senior_id == senior.id
);
}
}
Run Code Online (Sandbox Code Playgroud)
然后是组件树:
<ul>
<li v-for="chief in juniors(snr_chief)">
<div class="child mx-1">{{chief.lname}} {{chief.fname}}<br /> <small>{{chief.title}}</small>
</div>
<ul>
<li v-for="second in juniors(chief)">
<div class="child mx-1">{{second.lname}} {{second.fname}}<br /> <small>{{second.title}}</small>
</div>
<ul>
<li v-for="third in juniors(second)">
<div class="child mx-1">{{third.lname}} {{third.fname}}<br /> <small>{{third.title}}</small>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
这非常有效,但当然可以降低 3 个级别。我实际上不知道用户可能会深入多少级。
所以这个想法是有一个递归组件,但我不知道如何实现它。就像是:
<ul>
<li v-for="chief in juniors(snr_chief)">
<div class="child mx-1">{{chief.lname}} {{chief.fname}}<br /> <small>{{chief.title}}</small>
</div>
<Repeater :juniors="snr_chief" :self="chief" />
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
function listToTree(data, options) {
options = options || {};
var ID_KEY = options.idKey || 'Id';
var PARENT_KEY = options.parentKey || 'ParentId';
var CHILDREN_KEY = options.childrenKey || 'Items';
var item, id, parentId;
var map = {};
for(var i = 0; i < data.length; i++ ) { // make cache
if(data[i][ID_KEY]){
map[data[i][ID_KEY]] = data[i];
data[i][CHILDREN_KEY] = [];
}
}
for (var i = 0; i < data.length; i++) {
if(data[i][PARENT_KEY]) { // is a child
if(map[data[i][PARENT_KEY]]) // for dirty data
{
map[data[i][PARENT_KEY]][CHILDREN_KEY].push(data[i]); // add child to parent
data.splice( i, 1 ); // remove from root
i--; // iterator correction
} else {
data[i][PARENT_KEY] = 0; // clean dirty data
}
}
};
return data;
}
Vue.component('menu-tree', {
props: ['item'],
template: '<ul class="c-tree"><li>{{item.MenuName}}<menu-tree v-for="y in item.Items" v-bind:item="y"></menu-tree></li></ul>'
})
var app = new Vue({
el:"#app",
data:{
items:[{
Id: 1,
MenuName: "Menu 1",
ParentId: null
},
{
Id: 2,
MenuName: "Menu 2",
ParentId: null
},
{
Id: 3,
MenuName: "Menu 3",
ParentId: null
},
{
Id: 4,
MenuName: "Sub Menu 1 - 1",
ParentId: 1
},
{
Id: 5,
MenuName: "Sub Menu 1 - 2",
ParentId: 1
},
{
Id: 6,
MenuName: "Sub Menu 1 - 1 - 1",
ParentId: 4
},
{
Id: 7,
MenuName: "Sub Menu 1 - 1 - 1 - 1",
ParentId: 6
}],
heirarchyItems: []
},
created: function(){
this.heirarchyItems = listToTree(this.items);
}
});
Run Code Online (Sandbox Code Playgroud)
.c-tree{
list-style: none;
}
.c-tree > li {
margin-left: 20px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<menu-tree v-for="hItem in heirarchyItems" v-bind:item="hItem"></menu-tree>
</div>
Run Code Online (Sandbox Code Playgroud)