Vue2实现树形菜单(多级菜单)功能模块结构⽰意图
1. ├── index.html
2. ├── main.js
3. ├── router
4. │└── index.js # 路由配置⽂件
5. ├── components # 组件⽬录
6. │├── App.vue # 根组件
7. │├── Home.vue # ⼤的框架结构组件
8. │├── TreeView.vue
9. │├── TreeViewItem.vue
10. │└── TreeDetail.vue
11. ├── store
12. ├── index.js # 我们组装模块并导出 store 的地⽅
13. ├── modules # 模块⽬录
14. └── menusModule.js # 菜单模块
这个多级菜单实现的功能如下:
1、可展⽰多级菜单,理论上可以展⽆限级菜单
2、当前菜单⾼亮功能
3、刷新后依然会⾃动定位到上⼀次点击的菜单,即使这个是⼦菜单,并且⽗菜单会⾃动展开
4、⼦菜单的显⽰隐藏有收起、展开,同时带有淡⼊效果
这个例⼦⽤到的知识点:路由、状态管理、组件。
状态管理安装:
1. npm install --save vuex
更多关于 vuex 的介绍可以看官⽅⽂档:。
我们先来看看效果演⽰图:
程序员是⽤代码来沟通的,所以费话不多说,直接上码:
index.html
1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="utf-8">
5. <meta name="viewport" content="width=device-width,initial-scale=1.0">
6. <title>Vue 实现树形菜单(多级菜单)功能模块- 云库⽹</title>
7. </head>
8. <body>
9. <div id="app"></div>
10. </body>
11. </html>
main.js
1. import Vue from 'vue'
2. import App from './components/App'
3. import router from './router'
4. import store from './store/index'
5. fig.productionTip = false
6. /* eslint-disable no-new */
7. new Vue({
8. el: '#app',
9. router,
10. store,
11. components: {
12. App
13. },
14. template: '<App/>'
15. })
在 main.js 中引⼊路由和状态管理配置App.vue
1. <template>
2. <div id="app">
3. <Home></Home>
4. </div>
5. </template>
6. <script>
7. import Home from "./Home";
8. export default {
9. components: {
10. Home
11. },
12. name: "App"
13. };
14. </script>
15. <style>
16. * {
17. padding: 0;
18. margin: 0;
19. }
20. #app {
21. font-family: "Avenir", Helvetica, Arial, sans-serif;
22. -webkit-font-smoothing: antialiased;
23. -moz-osx-font-smoothing: grayscale;
24. color: #2c3e50;
25. }
26. html,
27. body,
28. #app,
29. .home {
30. height: 100%;
31. }
32. html,
33. body {
34. overflow: hidden;
35. }
36. </style>
Home.vue
1. <template>
2. <div class="home">
3. <div class="side-bar">
4. <Tree-view></Tree-view>
5. </div>
6. <div class="continer">
7. <router-view></router-view>
8. </div>
9. </div>
10. </template>
11. <script>
12. import TreeView from "./TreeView";
13. export default {
14. components: {
15. TreeView
16. },
17. name: "Home"
18. };
19. </script>
20. <style scoped>
21. .side-bar {
22. width: 300px;
23. height: 100%;
24. overflow-y: auto;
25. overflow-x: hidden;
26. font-size: 14px;
27. position: absolute;
28. top: 0;
29. left: 0;
30. }
31. .continer {
32. padding-left: 320px;
33. }
34. </style>
这个 Home.vue 主要是⽤来完成页⾯的⼤框架结构。
TreeView.vue
1. <template>
2. <div class="tree-view-menu">
3. <Tree-view-item :menus='menus'></Tree-view-item>
4. </div>
5. </template>
6. <script>
7. import TreeViewItem from "./TreeViewItem";
8. const menusData = [];
9. export default {
10. components: {
11. TreeViewItem
12. },
13. name: "TreeViewMenu",
14. data() {
15. return {
16. menus: this.$us
17. };
18. }
19. };
20. </script>
21. <style scoped>
22. .tree-view-menu {
23. width: 300px;
24. height: 100%;
25. overflow-y: auto;
26. overflow-x: hidden;
27. }
28. .tree-view-menu::-webkit-scrollbar {
29. height: 6px;
30. width: 6px;
31. }
32. .tree-view-menu::-webkit-scrollbar-trac {
33. -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
34. box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
35. }
36. .tree-view-menu::-webkit-scrollbar-thumb {
37. background-color: #6e6e6e;
38. outline: 1px solid #333;
39. }
40. .tree-view-menu::-webkit-scrollbar {
41. height: 4px;
42. width: 4px;
43. }
44. .tree-view-menu::-webkit-scrollbar-track {
45. -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
46. box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
47. }
48. .tree-view-menu::-webkit-scrollbar-thumb {
49. background-color: #6e6e6e;
50. outline: 1px solid #708090;
51. }
52. </style>
这个组件也⾮常地简单,拿到菜单数据,传给⼦组件,并把菜单的滚动条样式修改了下。
TreeViewItem.vue
1. <template>
2. <div class="tree-view-item">
3. <div class="level" :class="'level-'+ menu.level" v-for="menu in menus" :key="menu.id">
4. <div v-if="pe === 'link'">
5. <router-link class="link" v-bind:to="menu.url" @click.native="toggle(menu)">{{menu.name}}</router-link>
6. </div>
7. <div v-if="pe === 'button'">
8. <div class="button heading" :class="{selected: menu.isSelected,expand:menu.isExpanded}" @click="toggle(menu)">
9. {{menu.name}}
10. <div class="icon">
11. <svg xmlns="/2000/svg" focusable="false" viewBox="0 0 24 24">
12. <path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z "></path>
13. </svg>
14. </div>
15. </div>
16. <transition name="fade">
17. <div class="heading-children" v-show="menu.isExpanded" v-if="menu.subMenu">
18. <Tree-view-item :menus='menu.subMenu'></Tree-view-item>
19. </div>
20. </transition>
21. </div>
22. </div>
23. </div>
24. </template>
25. <script>
vue中reactive
26. export default {
27. name: "TreeViewItem",
28. props: ["menus"],
29. created() {
30. this.$storemit("firstInit", { url: this.$route.path });
31. },
32. methods: {
33. toggle(menu) {
34. this.$storemit("findParents", { menu });
35. }
36. }
37. };
38. </script>
39. <style scoped>
40. a {
41. text-decoration: none;
42. color: #333;
43. }
44. .link,
45. .button {
46. display: block;
47. padding: 10px 15px;
48. transition: background-color 0.2s ease-in-out 0s, color 0.3s ease-in-out 0.1s;
49. -moz-user-select: none;
50. -webkit-user-select: none;
51. -ms-user-select: none;
52. -khtml-user-select: none;
53. user-select: none;
54. }
55. .button {
56. position: relative;
57. }
58. .link:hover,
59. .button:hover {
60. color: #1976d2;
61. background-color: #eee;
62. cursor: pointer;
63. }
64. .icon {
65. position: absolute;
66. right: 0;
67. display: inline-block;
68. height: 24px;
69. width: 24px;
70. fill: currentColor;
71. transition: -webkit-transform 0.15s;
72. transition: transform 0.15s;
73. transition: transform 0.15s, -webkit-transform 0.15s;
74. transition-timing-function: ease-in-out;
75. }
76. .heading-children {
77. padding-left: 14px;
78. overflow: hidden;
79. }
80. .expand {
81. display: block;
82. }
83. .collapsed {
84. display: none;
85. }
86. .expand .icon {
87. -webkit-transform: rotate(90deg);
88. transform: rotate(90deg);
89. }
90. .selected {
91. color: #1976d2;
92. }
93. .fade-enter-active {
94. transition: all 0.5s ease 0s;
95. }
96. .fade-enter {
97. opacity: 0;
98. }
99. .fade-enter-to {
100. opacity: 1;
101. }
102. .fade-leave-to {
103. height: 0;
104. }
105. </style>
上⾯的这个组件才是这个树型结构重点代码,⽤了递归的思想来实现这个树型菜单。TreeViewDetail.vue
1. <template>
2. <h3>
3. 这⾥是{{currentRoute}}导航详情
4. </h3>
5. </template>
6. <script>
7. export default {
8. name: "TreeViewDetail",
9. data() {
10. return {
11. currentRoute: this.$route.path
12. };
13. },
14. watch: {
15. //监听路由,只要路由有变化(路径,参数等变化)都有执⾏下⾯的函数
16. $route: {
17. handler: function(val, oldVal) {
18. this.currentRoute = val.name;
19. },
20. deep: true
21. }
22. }
23. };
24. </script>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论