VUE中递归算法实现树形菜单的写法:
<template>
<div>
<!-- 父组件将数据传入子组件 -->
<tree :msg=‘msg‘ />
</div>
</template>
<script>
export default {
data (){ //模拟数据
return{
n:0,
msg: [{name:‘北京‘,
sub:[{name:‘东城区‘,
sub:[
{name:‘朝阳区‘}
]
},{name:‘西城区‘,
sub:[
{name:‘关虎屯‘}
]
},{name:‘南城区‘},{name:‘北城区‘}]
}
,{
name:‘广东‘,
sub:[{name:‘广州‘,
sub:[{name:‘越秀区‘},{name:‘白云区‘},{name:‘海珠区‘}]
},
{name:‘深圳‘,
sub:[{name:‘蛇口区‘},{name:‘保安区‘},{name:‘盐田区‘}]
},
]
},{
name:‘湖北‘,
sub:[{name:‘武汉‘,
sub:[{name:‘江夏区‘},{name:"洪山区"},{name:‘江汉区‘}]
},
{name:‘天门市‘,
sub:[{name:‘精灵‘},{name:"小班"},{name:‘打扮‘}]
}]
}],
}
},
// 注册父组件
components: {
tree:{
name:‘gs‘,//递归的构造函数名
//父组件模板,相当于构造函数return的值
template:`
<ul>
<li v-for="(v,i) in msg" :key=i @click.stop.self=‘n=i‘> //第一层的数据,点击之后,子集菜单会展开,其他子集菜单会关闭
{{v.name}}
<gs :msg=v.sub v-if="i==n"/>//将下一层数据传入构造函数,进行调用,形成递归,相当于自己调用自己,这一步是最关键的一步,
</li>
</ul>
`,
props: [‘msg‘],//接受父组件传的值
data(){
return{
n:0 //默认展开的菜单下标
}
}
},
}
}
</script>
JS递归方法实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button onclick="fun()">递归测试</button>
<div id="div">
</div>
<script>
//模拟数据
var data = [{
name: 1,
sub: [{
name: ‘1-1‘,
sub: []
}]
}, {
name: 2,
sub: [{
name: "2-1",
sub: [{
name: ‘2-1-1‘,
sub: []
}, {
name: ‘2-1-2‘,
sub: []
}
]
}, {
name: "2-2",
sub: [{
name: ‘2-2-1‘,
sub: []
}, {
name: ‘2-2-2‘,
sub: [{
name: ‘2-2-2-1‘,
sub: []
}]
}]
}
]
}, {
name: 3,
sub: []
}]
var div = document.getElementById(‘div‘)
var str = ‘‘;
//递归函数function list(data) {
if (data) {
if (data.length > 0) {
str += "<ul>";
for (let v = 0; v < data.length; v++) {
const item = data[v];
str += ‘<li>‘ + item.name;
list(item.sub)
str += ‘</li>‘;
}
str += "</ul>";
}
}
}
list(data)
console.log(str)
div.innerHTML = str;
//以下是递归测试函数,与树形菜单无关
var arr = [];
function fun() {
var num = parseFloat(prompt("输入数字:"));
if (typeof(num) == ‘number‘) {
while (num > 0) {
arr.push(num)
num--;
}
//console.log(arr)
}
}
var arrlist = [];
// var data=[1,[2,3],[4,[5,6,[8]]],9,[10]];
var fun3 = arr => [...arr].map((item) => Array.isArray(item) ? fun3(item) : arrlist.push(item));
fun3(data)
// console.log( fun3(data))
</script>
</body>
</html>
使用VUE + element-ui 实现树形菜单:
<template>
<div class="custom-tree-container">
<div class="block">
<p>使用 render-content</p>
<el-tree
:data="data"
show-checkbox
node-key="id"
default-expand-all
:expand-on-click-node="false"
:render-content="renderContent"
></el-tree>
</div>
<div class="block">
<p>使用 scoped slot</p>
<el-tree
:data="data"
show-checkbox
node-key="id"
default-expand-all
:expand-on-click-node="false"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button type="text" size="mini" @click="() => append(data)">Append</el-button>
<el-button type="text" size="mini" @click="() => remove(node, data)">Delete</el-button>
</span>
</span>
</el-tree>
</div>
<button @click="getAdd">+</button>
<button @click="getjian">-</button>
</div>
</template>
<script>
let id = 1000;
export default {
data() {
const data = [
{
name: "北京",
sub: [
{
name: "北京",
sub: [
{ name: "东城区" },
{ name: "西城区" },
{ name: "南城区" },
{ name: "北城区" }
]
}
]
},
{
name: "广东",
sub: [
{
name: "广州",
sub: [{ name: "越秀区" }, { name: "白云区" }, { name: "海珠区" }]
},
{
name: "深圳",
sub: [{ name: "蛇口区" }, { name: "保安区" }, { name: "盐田区" }]
}
]
},
{
name: "湖北",
sub: [
{
name: "武汉",
sub: [{ name: "江夏区" }, { name: "洪山区" }, { name: "江汉区" }]
},
{
name: "天门市",
sub: [{ name: "精灵" }, { name: "小班" }, { name: "打扮" }]
}
]
}
];
//关键部分
let _data = function(data) {
return data.map(v => {
if (v.sub) { // 遍历数据,将菜单数据赋值给 ui框架指定属性名
v.label = v.name;
v.children = v.sub;
return _data(v.sub);
}
if (v.name && !v.sub) {
v.label = v.name;
return 123;
}
});
};
_data(data);
return {
data: JSON.parse(JSON.stringify(data)), //将处理过的数据进行深刻隆
data: JSON.parse(JSON.stringify(data))
};
},
methods: {
append(data) {
const newChild = { id: id++, label: "testtest", children: [] };
if (!data.children) {
this.$set(data, "children", []);
}
data.children.push(newChild);
},
remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
},
renderContent(h, { node, data, store }) {
return (
<span class="custom-tree-node">
<span>{node.label}</span>
<span>
<el-button
size="mini"
type="text"
on-click={() => this.append(data)}
>
Append
</el-button>
<el-button
size="mini"
type="text"
on-click={() => this.remove(node, data)}
>
Delete
</el-button>
</span>
</span>
);
},
getAdd() {
this.$store.commit("increment");
console.log("我是加法" + this.$store.state.count);
},
getjian() {
this.$store.commit("jian", 2);
console.log("我是加Z法" + this.$store.state.count);
}
},
mounted() {
console.log(this.$store.state.count);
}
};
</script>
<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>
原文:https://www.cnblogs.com/wxyblog/p/11618686.html