Skip to content

Commit 12ad747

Browse files
committed
树形菜单
1 parent 563ab01 commit 12ad747

File tree

12 files changed

+319
-0
lines changed

12 files changed

+319
-0
lines changed

tree-menu/.babelrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"presets": [
3+
["es2015", { "modules": false }]
4+
]
5+
}

tree-menu/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
node_modules/
3+
dist/
4+
npm-debug.log
5+
.idea

tree-menu/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Vue.js 递归组件实现树形菜单</title>
6+
</head>
7+
<body>
8+
<div id="app"></div>
9+
<script src="/dist/build.js"></script>
10+
</body>
11+
</html>

tree-menu/package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "tree-menu",
3+
"description": "树形菜单",
4+
"version": "0.0.1",
5+
"author": "caihg",
6+
"private": false,
7+
"scripts": {
8+
"dev": "cross-env NODE_ENV=development webpack-dev-server --inline --hot --open",
9+
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
10+
},
11+
"dependencies": {
12+
"vue": "^2.5.16"
13+
},
14+
"devDependencies": {
15+
"babel-core": "^6.26.0",
16+
"babel-loader": "^7.1.4",
17+
"babel-preset-es2015": "^6.24.1",
18+
"cross-env": "^5.1.4",
19+
"css-loader": "^0.28.11",
20+
"file-loader": "^1.1.11",
21+
"style-loader": "^0.20.3",
22+
"vue-loader": "^14.2.2",
23+
"vue-template-compiler": "^2.5.16",
24+
"webpack": "^3.11.0",
25+
"webpack-dev-middleware": "^3.1.2",
26+
"webpack-dev-server": "^2.11.2"
27+
}
28+
}

tree-menu/src/assets/file-text.png

1.38 KB
Loading

tree-menu/src/assets/file.png

1.16 KB
Loading

tree-menu/src/assets/folder-open.png

1.29 KB
Loading

tree-menu/src/assets/folder.png

1.13 KB
Loading
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<template>
2+
<ul>
3+
<li v-for="(item, index) in data">
4+
<span @click="toggle(item, index)">
5+
<i :class="['icon', item.children && item.children.length ? folderIconList[index] : 'file-text']"></i>
6+
{{ item.menuName }}
7+
</span>
8+
<tree-menu v-if="scope[index]" :data="item.children"></tree-menu>
9+
</li>
10+
</ul>
11+
</template>
12+
13+
<script>
14+
export default {
15+
name: 'treeMenu',
16+
props: {
17+
data: Array
18+
},
19+
data () {
20+
return {
21+
folderIconList: [],
22+
scope: {}
23+
}
24+
},
25+
created () {
26+
this.data.forEach((item, index) => {
27+
if (item.children && item.children.length) {
28+
this.folderIconList[index] = 'folder';
29+
}
30+
});
31+
},
32+
methods: {
33+
toggle (item, index) {
34+
this.$emit('getSubMenu', item);
35+
36+
if (item.children && item.children.length) {
37+
this.$set(this.scope, index, !this.scope[index]);
38+
this.folderIconList[index] = this.scope[index] ? 'folder-open' : 'folder';
39+
}
40+
}
41+
}
42+
}
43+
</script>
44+
45+
<style>
46+
ul {
47+
list-style: none;
48+
}
49+
i.icon {
50+
display: inline-block;
51+
width: 15px;
52+
height: 15px;
53+
background-repeat: no-repeat;
54+
vertical-align: middle;
55+
}
56+
.icon.folder {
57+
background-image: url(/src/assets/folder.png);
58+
}
59+
.icon.folder-open {
60+
background-image: url(/src/assets/folder-open.png);
61+
}
62+
.icon.file-text {
63+
background-image: url(/src/assets/file-text.png);
64+
}
65+
.tree-menu li {
66+
line-height: 1.5;
67+
}
68+
</style>

tree-menu/src/components/main.vue

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<template>
2+
<div>
3+
<my-tree :data="theData" @getSubMenu="getSubMenu"></my-tree>
4+
</div>
5+
</template>
6+
7+
<script>
8+
const myData = [
9+
{
10+
'id': '1',
11+
'menuName': '基础管理',
12+
'menuCode': '10'
13+
},
14+
{
15+
'id': '2',
16+
'menuName': '商品管理',
17+
'menuCode': ''
18+
},
19+
{
20+
'id': '3',
21+
'menuName': '订单管理',
22+
'menuCode': '30',
23+
'children': [
24+
{
25+
'menuName': '订单列表',
26+
'menuCode': '31'
27+
},
28+
{
29+
'menuName': '退货列表',
30+
'menuCode': '32',
31+
'children': []
32+
}
33+
]
34+
},
35+
{
36+
'id': '4',
37+
'menuName': '商家管理',
38+
'menuCode': '',
39+
'children': []
40+
}
41+
];
42+
43+
const subMenuData = {
44+
parentId: '1',
45+
children: [
46+
{
47+
'menuName': '用户管理',
48+
'menuCode': '11'
49+
},
50+
{
51+
'menuName': '角色管理',
52+
'menuCode': '12',
53+
'children': [
54+
{
55+
'menuName': '管理员',
56+
'menuCode': '121'
57+
},
58+
{
59+
'menuName': 'CEO',
60+
'menuCode': '122'
61+
},
62+
{
63+
'menuName': 'CFO',
64+
'menuCode': '123'
65+
},
66+
{
67+
'menuName': 'COO',
68+
'menuCode': '124'
69+
},
70+
{
71+
'menuName': '普通人',
72+
'menuCode': '124'
73+
}
74+
]
75+
},
76+
{
77+
'menuName': '权限管理',
78+
'menuCode': '13'
79+
}
80+
]
81+
};
82+
83+
const subMenuData2 = {
84+
parentId: '2',
85+
children: [
86+
{
87+
'menuName': '商品一',
88+
'menuCode': '21'
89+
},
90+
{
91+
'menuName': '商品二',
92+
'menuCode': '22',
93+
'children': [
94+
{
95+
'menuName': '子类商品1',
96+
'menuCode': '221'
97+
},
98+
{
99+
'menuName': '子类商品2',
100+
'menuCode': '222'
101+
}
102+
]
103+
}
104+
]
105+
};
106+
107+
import myTree from './common/treeMenu.vue'
108+
export default {
109+
components: {
110+
myTree
111+
},
112+
data () {
113+
return {
114+
theData: myData
115+
}
116+
},
117+
methods: {
118+
getSubMenu (menuItem) {
119+
if (menuItem.id === subMenuData.parentId) {
120+
menuItem.children = subMenuData.children;
121+
}
122+
123+
if (menuItem.id === subMenuData2.parentId) {
124+
menuItem.children = subMenuData2.children;
125+
}
126+
}
127+
}
128+
}
129+
</script>

0 commit comments

Comments
 (0)