Commit b858224eb6e45b32e8cdc01feda2cd7a8164f1b8

Authored by BigBoss
1 parent 8a0e4eede0
Exists in master

layout修改

src/layout/components/Sidebar/index.vue
1 <template> 1 <template>
2 <div :class="{'has-logo':showLogo}"> 2 <div :class="{'has-logo':showLogo}">
3 <logo v-if="showLogo" :collapse="isCollapse" /> 3 <logo v-if="showLogo" class="logo" :collapse="isCollapse" />
4 <el-scrollbar wrap-class="scrollbar-wrapper"> 4 <!-- <el-scrollbar wrap-class="scrollbar-wrapper"> -->
5 <el-menu 5 <el-menu
6 :default-active="activeMenu" 6 :default-active="activeMenu"
7 :collapse="isCollapse" 7 :background-color="variables.menuBg"
8 :background-color="variables.menuBg" 8 :text-color="variables.menuText"
9 :text-color="variables.menuText" 9 :unique-opened="false"
10 :unique-opened="false" 10 :active-text-color="variables.menuActiveText"
11 :active-text-color="variables.menuActiveText" 11 :collapse-transition="false"
12 :collapse-transition="false" 12 mode="horizontal"
13 mode="vertical" 13 >
14 > 14 <el-menu-item v-for="route in permission_routes" :key="route.path">
15 <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" /> 15 <sidebar-item :key="route.path" :item="route" :base-path="route.path" />
16 </el-menu> 16 </el-menu-item>
17 </el-scrollbar> 17
18 </el-menu>
19 <!-- </el-scrollbar> -->
18 </div> 20 </div>
19 </template> 21 </template>
20 22
21 <script> 23 <script>
22 import { mapGetters } from 'vuex' 24 import { mapGetters } from 'vuex'
23 import Logo from './Logo' 25 import Logo from './Logo'
24 import SidebarItem from './SidebarItem' 26 import SidebarItem from './SidebarItem'
25 import variables from '@/styles/variables.scss' 27 import variables from '@/styles/variables.scss'
26 28
27 export default { 29 export default {
28 components: { SidebarItem, Logo }, 30 components: { SidebarItem, Logo },
29 computed: { 31 computed: {
30 ...mapGetters([ 32 ...mapGetters([
31 'permission_routes', 33 'permission_routes',
32 'sidebar' 34 'sidebar'
33 ]), 35 ]),
34 activeMenu() { 36 activeMenu() {
35 const route = this.$route 37 const route = this.$route
36 const { meta, path } = route 38 const { meta, path } = route
37 // if set path, the sidebar will highlight the path you set 39 // if set path, the sidebar will highlight the path you set
38 if (meta.activeMenu) { 40 if (meta.activeMenu) {
39 return meta.activeMenu 41 return meta.activeMenu
40 } 42 }
41 return path 43 return path
42 }, 44 },
43 showLogo() { 45 showLogo() {
44 return this.$store.state.settings.sidebarLogo 46 return this.$store.state.settings.sidebarLogo
45 }, 47 },
46 variables() { 48 variables() {
47 return variables 49 return variables
48 }, 50 },
49 isCollapse() { 51 isCollapse() {
50 return !this.sidebar.opened 52 return !this.sidebar.opened
51 } 53 }
52 } 54 }
53 } 55 }
54 </script> 56 </script>
57 <style>
58 .logo{
59 width:115px;
60 }
61 </style>
55 62
src/layout/index.vue
1 <template> 1 <template>
2 <div :class="classObj" class="app-wrapper"> 2 <div :class="classObj" class="app-wrapper">
3 <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> 3 <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
4 <sidebar class="sidebar-container" /> 4 <sidebar class="sidebar-container" />
5 <div :class="{hasTagsView:needTagsView}" class="main-container"> 5 <div :class="{hasTagsView:needTagsView}" class="main-container">
6 <div :class="{'fixed-header':fixedHeader}"> 6 <div :class="{'fixed-header':fixedHeader}">
7 <navbar /> 7 <navbar />
8 <tags-view v-if="needTagsView" /> 8 <tags-view v-if="needTagsView" />
9 </div> 9 </div>
10 <app-main /> 10 <app-main />
11 <right-panel v-if="showSettings"> 11 <right-panel v-if="showSettings">
12 <settings /> 12 <settings />
13 </right-panel> 13 </right-panel>
14 </div> 14 </div>
15 </div> 15 </div>
16 </template> 16 </template>
17 17
18 <script> 18 <script>
19 import RightPanel from '@/components/RightPanel' 19 import RightPanel from '@/components/RightPanel'
20 import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components' 20 import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
21 import ResizeMixin from './mixin/ResizeHandler' 21 import ResizeMixin from './mixin/ResizeHandler'
22 import { mapState } from 'vuex' 22 import { mapState } from 'vuex'
23 23
24 export default { 24 export default {
25 name: 'Layout', 25 name: 'Layout',
26 components: { 26 components: {
27 AppMain, 27 AppMain,
28 Navbar, 28 Navbar,
29 RightPanel, 29 RightPanel,
30 Settings, 30 Settings,
31 Sidebar, 31 Sidebar,
32 TagsView 32 TagsView
33 }, 33 },
34 mixins: [ResizeMixin], 34 mixins: [ResizeMixin],
35 computed: { 35 computed: {
36 ...mapState({ 36 ...mapState({
37 sidebar: state => state.app.sidebar, 37 sidebar: state => state.app.sidebar,
38 device: state => state.app.device, 38 device: state => state.app.device,
39 showSettings: state => state.settings.showSettings, 39 showSettings: state => state.settings.showSettings,
40 needTagsView: state => state.settings.tagsView, 40 needTagsView: state => state.settings.tagsView,
41 fixedHeader: state => state.settings.fixedHeader 41 fixedHeader: state => state.settings.fixedHeader
42 }), 42 }),
43 classObj() { 43 classObj() {
44 return { 44 return {
45 hideSidebar: !this.sidebar.opened, 45 hideSidebar: !this.sidebar.opened,
46 openSidebar: this.sidebar.opened, 46 openSidebar: this.sidebar.opened,
47 withoutAnimation: this.sidebar.withoutAnimation, 47 withoutAnimation: this.sidebar.withoutAnimation,
48 mobile: this.device === 'mobile' 48 mobile: this.device === 'mobile'
49 } 49 }
50 } 50 }
51 }, 51 },
52 methods: { 52 methods: {
53 handleClickOutside() { 53 handleClickOutside() {
54 this.$store.dispatch('app/closeSideBar', { withoutAnimation: false }) 54 this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
55 } 55 }
56 } 56 }
57 } 57 }
58 </script> 58 </script>
59 59
60 <style lang="scss" scoped> 60 <style lang="scss" scoped>
61 @import "~@/styles/mixin.scss"; 61 @import "~@/styles/mixin.scss";
62 @import "~@/styles/variables.scss"; 62 @import "~@/styles/variables.scss";
63 63
64 .app-wrapper { 64 .app-wrapper {
65 @include clearfix; 65 @include clearfix;
66 position: relative; 66 position: relative;
67 height: 100%; 67 height: 100%;
68 width: 100%; 68 width: 100%;
69 69
70 &.mobile.openSidebar { 70 &.mobile.openSidebar {
71 position: fixed; 71 position: fixed;
72 top: 0; 72 top: 0;
73 } 73 }
74 } 74 }
75 75
76 .drawer-bg { 76 .drawer-bg {
77 background: #000; 77 background: #000;
78 opacity: 0.3; 78 opacity: 0.3;
79 width: 100%; 79 width: 100%;
80 top: 0; 80 top: 0;
81 height: 100%; 81 height: 100%;
82 position: absolute; 82 position: absolute;
83 z-index: 999; 83 z-index: 999;
84 } 84 }
85 85
86 .fixed-header { 86 .fixed-header {
87 position: fixed; 87 position: fixed;
88 top: 0; 88 top: 0;
89 right: 0; 89 right: 0;
90 z-index: 9; 90 z-index: 9;
91 width: calc(100% - #{$sideBarWidth}); 91 // width: calc(100% - #{$sideBarWidth});
92 width: 100%;
93 margin-top: 54px;
92 transition: width 0.28s; 94 transition: width 0.28s;
93 } 95 }
94 96
95 .hideSidebar .fixed-header { 97 .hideSidebar .fixed-header {
96 width: calc(100% - 54px) 98 // width: calc(100% - 54px)
99 width:100%;
97 } 100 }
98 101
99 .mobile .fixed-header { 102 .mobile .fixed-header {
100 width: 100%; 103 width: 100%;
101 } 104 }
102 </style> 105 </style>
103 106
src/router/index.js
1 import Vue from 'vue' 1 import Vue from 'vue'
2 import Router from 'vue-router' 2 import Router from 'vue-router'
3 3
4 Vue.use(Router) 4 Vue.use(Router)
5 5
6 /* Layout */ 6 /* Layout */
7 import Layout from '@/layout' 7 import Layout from '@/layout'
8 8
9 /* Router Modules */ 9 /* Router Modules */
10 // import componentsRouter from './modules/components' 10 // import componentsRouter from './modules/components'
11 // import chartsRouter from './modules/charts' 11 // import chartsRouter from './modules/charts'
12 // import tableRouter from './modules/table' 12 // import tableRouter from './modules/table'
13 // import nestedRouter from './modules/nested' 13 // import nestedRouter from './modules/nested'
14 import userRouter from './modules/user'// 用户 14 import userRouter from './modules/user'// 用户
15 import systemRouter from './modules/system'// 系统设置 15 import systemRouter from './modules/system'// 系统设置
16 import prodRouter from './modules/prod'// 产品 16 import prodRouter from './modules/prod'// 产品
17 import orderRouter from './modules/order'// 订单 17 import orderRouter from './modules/order'// 订单
18 import metaRouter from './modules/meta'// 元定义 18 import metaRouter from './modules/meta'// 元定义
19 // import sitesRouter from './modules/sites' 19 // import sitesRouter from './modules/sites'
20 import applicationRouter from './modules/application'// 应用 20 import applicationRouter from './modules/application'// 应用
21 import operationsRouter from './modules/operations'// 运营官 21 import operationsRouter from './modules/operations'// 运营官
22 import logisticsRouter from './modules/logistics'// 物流路由 22 import logisticsRouter from './modules/logistics'// 物流路由
23 import staffRouter from './modules/staff'// 员工 23 import staffRouter from './modules/staff'// 员工
24 import recommendRouter from './modules/recommend'// 推荐 24 import recommendRouter from './modules/recommend'// 推荐
25 // import manufacturerRouter from './modules/manufacturer' 25 // import manufacturerRouter from './modules/manufacturer'
26 26
27 /** 27 /**
28 * Note: sub-menu only appear when route children.length >= 1 28 * Note: sub-menu only appear when route children.length >= 1
29 * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html 29 * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
30 * 30 *
31 * hidden: true if set true, item will not show in the sidebar(default is false) 31 * hidden: true if set true, item will not show in the sidebar(default is false)
32 * alwaysShow: true if set true, will always show the root menu 32 * alwaysShow: true if set true, will always show the root menu
33 * if not set alwaysShow, when item has more than one children route, 33 * if not set alwaysShow, when item has more than one children route,
34 * it will becomes nested mode, otherwise not show the root menu 34 * it will becomes nested mode, otherwise not show the root menu
35 * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb 35 * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
36 * name:'router-name' the name is used by <keep-alive> (must set!!!) 36 * name:'router-name' the name is used by <keep-alive> (must set!!!)
37 * meta : { 37 * meta : {
38 roles: ['admin','assistant','runner', 'shoper'] control the page roles (you can set multiple roles) 38 roles: ['admin','assistant','runner', 'shoper'] control the page roles (you can set multiple roles)
39 title: 'title' the name show in sidebar and breadcrumb (recommend set) 39 title: 'title' the name show in sidebar and breadcrumb (recommend set)
40 icon: 'svg-name' the icon show in the sidebar 40 icon: 'svg-name' the icon show in the sidebar
41 noCache: true if set true, the page will no be cached(default is false) 41 noCache: true if set true, the page will no be cached(default is false)
42 affix: true if set true, the tag will affix in the tags-view 42 affix: true if set true, the tag will affix in the tags-view
43 breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) 43 breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
44 activeMenu: '/example/list' if set path, the sidebar will highlight the path you set 44 activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
45 } 45 }
46 */ 46 */
47 47
48 /** 48 /**
49 * constantRoutes 49 * constantRoutes
50 * a base page that does not have permission requirements 50 * a base page that does not have permission requirements
51 * all roles can be accessed 51 * all roles can be accessed
52 */ 52 */
53 export const constantRoutes = [{ 53 export const constantRoutes = [{
54 path: '/redirect', 54 path: '/redirect',
55 component: Layout, 55 component: Layout,
56 hidden: true, 56 hidden: true,
57 children: [{ 57 children: [{
58 path: '/redirect/:path*', 58 path: '/redirect/:path*',
59 component: () => import('@/views/redirect/index') 59 component: () => import('@/views/redirect/index')
60 }] 60 }]
61 }, 61 },
62 { 62 {
63 path: '/login', 63 path: '/login',
64 component: () => import('@/views/login/index'), 64 component: () => import('@/views/login/index'),
65 hidden: true 65 hidden: true
66 }, 66 },
67 { 67 {
68 path: '/auth-redirect', 68 path: '/auth-redirect',
69 component: () => import('@/views/login/auth-redirect'), 69 component: () => import('@/views/login/auth-redirect'),
70 hidden: true 70 hidden: true
71 }, 71 },
72 { 72 {
73 path: '/404', 73 path: '/404',
74 component: () => import('@/views/error-page/404'), 74 component: () => import('@/views/error-page/404'),
75 hidden: true 75 hidden: true
76 }, 76 },
77 { 77 {
78 path: '/500', 78 path: '/500',
79 component: () => import('@/views/error-page/500'), 79 component: () => import('@/views/error-page/500'),
80 hidden: true 80 hidden: true
81 }, 81 },
82 { 82 {
83 path: '/401', 83 path: '/401',
84 component: () => import('@/views/error-page/401'), 84 component: () => import('@/views/error-page/401'),
85 hidden: true 85 hidden: true
86 }, 86 },
87 { 87 {
88 path: '/', 88 path: '/',
89 component: Layout, 89 component: Layout,
90 redirect: '/dashboard', 90 redirect: '/dashboard',
91 children: [{ 91 children: [{
92 path: 'dashboard', 92 path: 'dashboard',
93 component: () => import('@/views/dashboard/index'), 93 component: () => import('@/views/dashboard/index'),
94 name: 'Dashboard', 94 name: 'Dashboard',
95 meta: { 95 meta: {
96 title: 'dashboard', 96 title: 'dashboard',
97 icon: 'dashboard', 97 icon: 'dashboard',
98 affix: true 98 affix: true
99 } 99 }
100 }] 100 }]
101 } 101 }
102 // { 102 // {
103 // path: '/documentation', 103 // path: '/documentation',
104 // component: Layout, 104 // component: Layout,
105 // children: [ 105 // children: [
106 // { 106 // {
107 // path: 'index', 107 // path: 'index',
108 // component: () => import('@/views/documentation/index'), 108 // component: () => import('@/views/documentation/index'),
109 // name: 'Documentation', 109 // name: 'Documentation',
110 // meta: { title: 'documentation', icon: 'documentation', affix: true } 110 // meta: { title: 'documentation', icon: 'documentation', affix: true }
111 // } 111 // }
112 // ] 112 // ]
113 // }, 113 // },
114 // { 114 // {
115 // path: '/guide', 115 // path: '/guide',
116 // component: Layout, 116 // component: Layout,
117 // redirect: '/guide/index', 117 // redirect: '/guide/index',
118 // children: [{ 118 // children: [{
119 // path: 'index', 119 // path: 'index',
120 // component: () => import('@/views/guide/index'), 120 // component: () => import('@/views/guide/index'),
121 // name: 'Guide', 121 // name: 'Guide',
122 // meta: { 122 // meta: {
123 // title: 'guide', 123 // title: 'guide',
124 // icon: 'guide', 124 // icon: 'guide',
125 // noCache: true 125 // noCache: true
126 // } 126 // }
127 // }] 127 // }]
128 // } 128 // }
129 // { 129 // {
130 // path: '/profile', 130 // path: '/profile',
131 // component: Layout, 131 // component: Layout,
132 // redirect: '/profile/index', 132 // redirect: '/profile/index',
133 // hidden: true, 133 // hidden: true,
134 // children: [ 134 // children: [
135 // { 135 // {
136 // path: 'index', 136 // path: 'index',
137 // component: () => import('@/views/profile/index'), 137 // component: () => import('@/views/profile/index'),
138 // name: 'Profile', 138 // name: 'Profile',
139 // meta: { title: 'profile', icon: 'user', noCache: true } 139 // meta: { title: 'profile', icon: 'user', noCache: true }
140 // } 140 // }
141 // ] 141 // ]
142 // } 142 // }
143 ] 143 ]
144 144
145 /** 145 /**
146 * asyncRoutes 146 * asyncRoutes
147 * the routes that need to be dynamically loaded based on user roles 147 * the routes that need to be dynamically loaded based on user roles
148 */ 148 */
149 export const asyncRoutes = [ 149 export const asyncRoutes = [
150 // { 150 // {
151 // path: '/permission', 151 // path: '/permission',
152 // component: Layout, 152 // component: Layout,
153 // redirect: '/permission/page', 153 // redirect: '/permission/page',
154 // alwaysShow: true, // will always show the root menu 154 // alwaysShow: true, // will always show the root menu
155 // name: 'Permission', 155 // name: 'Permission',
156 // meta: { 156 // meta: {
157 // title: 'permission', 157 // title: 'permission',
158 // icon: 'lock', 158 // icon: 'lock',
159 // roles: ['admin', 'assistant'] // you can set roles in root nav 159 // roles: ['admin', 'assistant'] // you can set roles in root nav
160 // }, 160 // },
161 // children: [ 161 // children: [
162 // { 162 // {
163 // path: 'page', 163 // path: 'page',
164 // component: () => import('@/views/permission/page'), 164 // component: () => import('@/views/permission/page'),
165 // name: 'PagePermission', 165 // name: 'PagePermission',
166 // meta: { 166 // meta: {
167 // title: 'pagePermission', 167 // title: 'pagePermission',
168 // roles: ['admin','assistant'] // or you can only set roles in sub nav 168 // roles: ['admin','assistant'] // or you can only set roles in sub nav
169 // } 169 // }
170 // }, 170 // },
171 // { 171 // {
172 // path: 'directive', 172 // path: 'directive',
173 // component: () => import('@/views/permission/directive'), 173 // component: () => import('@/views/permission/directive'),
174 // name: 'DirectivePermission', 174 // name: 'DirectivePermission',
175 // meta: { 175 // meta: {
176 // title: 'directivePermission', 176 // title: 'directivePermission',
177 // roles: ['admin', 'shoper'] 177 // roles: ['admin', 'shoper']
178 // // if do not set roles, means: this page does not require permission 178 // // if do not set roles, means: this page does not require permission
179 // } 179 // }
180 // }, 180 // },
181 // { 181 // {
182 // path: 'role', 182 // path: 'role',
183 // component: () => import('@/views/permission/role'), 183 // component: () => import('@/views/permission/role'),
184 // name: 'RolePermission', 184 // name: 'RolePermission',
185 // meta: { 185 // meta: {
186 // title: 'rolePermission', 186 // title: 'rolePermission',
187 // roles: ['admin', 'runner'] 187 // roles: ['admin', 'runner']
188 // } 188 // }
189 // } 189 // }
190 // ] 190 // ]
191 // }, 191 // },
192 // tableRouter, 192 // tableRouter,
193 applicationRouter, // 应用 193 applicationRouter, // 应用
194 operationsRouter, // 运营官 194 operationsRouter, // 运营官
195 // manufacturerRouter, 195 // manufacturerRouter,
196 userRouter, // 用户 196 userRouter, // 用户
197 orderRouter, // 订单 197 orderRouter, // 订单
198 prodRouter, // 产品 198 prodRouter, // 产品
199 logisticsRouter, // 物流 199 logisticsRouter, // 物流
200 staffRouter, // 员工 200 staffRouter, // 员工
201 recommendRouter, // 推荐 201 recommendRouter, // 推荐
202 metaRouter, // 元定义 202 metaRouter, // 元定义
203 // sitesRouter, 203 // sitesRouter,
204 systemRouter, // 系统设置 204 systemRouter, // 系统设置
205 // componentsRouter, 205 // componentsRouter,
206 // chartsRouter, 206 // chartsRouter,
207 // nestedRouter, 207 // nestedRouter,
208 // tableRouter, 208 // tableRouter,
209 { 209 // {
210 path: '/icon', 210 // path: '/icon',
211 component: Layout, 211 // component: Layout,
212 children: [{ 212 // children: [{
213 path: 'index', 213 // path: 'index',
214 component: () => import('@/views/icons/index'), 214 // component: () => import('@/views/icons/index'),
215 name: 'Icons', 215 // name: 'Icons',
216 meta: { 216 // meta: {
217 title: 'icons', 217 // title: 'icons',
218 icon: 'icon', 218 // icon: 'icon',
219 noCache: true 219 // noCache: true
220 } 220 // }
221 }] 221 // }]
222 }, 222 // },
223 /** when your routing map is too long, you can split it into small modules **/ 223 /** when your routing map is too long, you can split it into small modules **/
224 224
225 // { 225 // {
226 // path: '/example', 226 // path: '/example',
227 // component: Layout, 227 // component: Layout,
228 // redirect: '/example/list', 228 // redirect: '/example/list',
229 // name: 'Example', 229 // name: 'Example',
230 // meta: { 230 // meta: {
231 // title: 'example', 231 // title: 'example',
232 // icon: 'example' 232 // icon: 'example'
233 // }, 233 // },
234 // children: [{ 234 // children: [{
235 // path: 'create', 235 // path: 'create',
236 // component: () => import('@/views/example/create'), 236 // component: () => import('@/views/example/create'),
237 // name: 'CreateArticle', 237 // name: 'CreateArticle',
238 // meta: { 238 // meta: {
239 // title: 'createArticle', 239 // title: 'createArticle',
240 // icon: 'edit' 240 // icon: 'edit'
241 // } 241 // }
242 // }, 242 // },
243 // { 243 // {
244 // path: 'edit/:id(\\d+)', 244 // path: 'edit/:id(\\d+)',
245 // component: () => import('@/views/example/edit'), 245 // component: () => import('@/views/example/edit'),
246 // name: 'EditArticle', 246 // name: 'EditArticle',
247 // meta: { 247 // meta: {
248 // title: 'editArticle', 248 // title: 'editArticle',
249 // noCache: true, 249 // noCache: true,
250 // activeMenu: '/example/list' 250 // activeMenu: '/example/list'
251 // }, 251 // },
252 // hidden: true 252 // hidden: true
253 // }, 253 // },
254 // { 254 // {
255 // path: 'list', 255 // path: 'list',
256 // component: () => import('@/views/example/list'), 256 // component: () => import('@/views/example/list'),
257 // name: 'ArticleList', 257 // name: 'ArticleList',
258 // meta: { 258 // meta: {
259 // title: 'articleList', 259 // title: 'articleList',
260 // icon: 'list' 260 // icon: 'list'
261 // } 261 // }
262 // } 262 // }
263 // ] 263 // ]
264 // }, 264 // },
265 265
266 // { 266 // {
267 // path: '/tab', 267 // path: '/tab',
268 // component: Layout, 268 // component: Layout,
269 // children: [ 269 // children: [
270 // { 270 // {
271 // path: 'index', 271 // path: 'index',
272 // component: () => import('@/views/tab/index'), 272 // component: () => import('@/views/tab/index'),
273 // name: 'Tab', 273 // name: 'Tab',
274 // meta: { title: 'tab', icon: 'tab' } 274 // meta: { title: 'tab', icon: 'tab' }
275 // } 275 // }
276 // ] 276 // ]
277 // }, 277 // },
278 278
279 // { 279 // {
280 // path: '/error', 280 // path: '/error',
281 // component: Layout, 281 // component: Layout,
282 // redirect: 'noRedirect', 282 // redirect: 'noRedirect',
283 // name: 'ErrorPages', 283 // name: 'ErrorPages',
284 // meta: { 284 // meta: {
285 // title: 'errorPages', 285 // title: 'errorPages',
286 // icon: '404' 286 // icon: '404'
287 // }, 287 // },
288 // children: [ 288 // children: [
289 // { 289 // {
290 // path: '401', 290 // path: '401',
291 // component: () => import('@/views/error-page/401'), 291 // component: () => import('@/views/error-page/401'),
292 // name: 'Page401', 292 // name: 'Page401',
293 // meta: { title: 'page401', noCache: true } 293 // meta: { title: 'page401', noCache: true }
294 // }, 294 // },
295 // { 295 // {
296 // path: '404', 296 // path: '404',
297 // component: () => import('@/views/error-page/404'), 297 // component: () => import('@/views/error-page/404'),
298 // name: 'Page404', 298 // name: 'Page404',
299 // meta: { title: 'page404', noCache: true } 299 // meta: { title: 'page404', noCache: true }
300 // } 300 // }
301 // ] 301 // ]
302 // }, 302 // },
303 303
304 // { 304 // {
305 // path: '/error-log', 305 // path: '/error-log',
306 // component: Layout, 306 // component: Layout,
307 // children: [ 307 // children: [
308 // { 308 // {
309 // path: 'log', 309 // path: 'log',
310 // component: () => import('@/views/error-log/index'), 310 // component: () => import('@/views/error-log/index'),
311 // name: 'ErrorLog', 311 // name: 'ErrorLog',
312 // meta: { title: 'errorLog', icon: 'bug' } 312 // meta: { title: 'errorLog', icon: 'bug' }
313 // } 313 // }
314 // ] 314 // ]
315 // }, 315 // },
316 316
317 // { 317 // {
318 // path: '/excel', 318 // path: '/excel',
319 // component: Layout, 319 // component: Layout,
320 // redirect: '/excel/export-excel', 320 // redirect: '/excel/export-excel',
321 // name: 'Excel', 321 // name: 'Excel',
322 // meta: { 322 // meta: {
323 // title: 'excel', 323 // title: 'excel',
324 // icon: 'excel' 324 // icon: 'excel'
325 // }, 325 // },
326 // children: [ 326 // children: [
327 // { 327 // {
328 // path: 'export-excel', 328 // path: 'export-excel',
329 // component: () => import('@/views/excel/export-excel'), 329 // component: () => import('@/views/excel/export-excel'),
330 // name: 'ExportExcel', 330 // name: 'ExportExcel',
331 // meta: { title: 'exportExcel' } 331 // meta: { title: 'exportExcel' }
332 // }, 332 // },
333 // { 333 // {
334 // path: 'export-selected-excel', 334 // path: 'export-selected-excel',
335 // component: () => import('@/views/excel/select-excel'), 335 // component: () => import('@/views/excel/select-excel'),
336 // name: 'SelectExcel', 336 // name: 'SelectExcel',
337 // meta: { title: 'selectExcel' } 337 // meta: { title: 'selectExcel' }
338 // }, 338 // },
339 // { 339 // {
340 // path: 'export-merge-header', 340 // path: 'export-merge-header',
341 // component: () => import('@/views/excel/merge-header'), 341 // component: () => import('@/views/excel/merge-header'),
342 // name: 'MergeHeader', 342 // name: 'MergeHeader',
343 // meta: { title: 'mergeHeader' } 343 // meta: { title: 'mergeHeader' }
344 // }, 344 // },
345 // { 345 // {
346 // path: 'upload-excel', 346 // path: 'upload-excel',
347 // component: () => import('@/views/excel/upload-excel'), 347 // component: () => import('@/views/excel/upload-excel'),
348 // name: 'UploadExcel', 348 // name: 'UploadExcel',
349 // meta: { title: 'uploadExcel' } 349 // meta: { title: 'uploadExcel' }
350 // } 350 // }
351 // ] 351 // ]
352 // }, 352 // },
353 353
354 // { 354 // {
355 // path: '/zip', 355 // path: '/zip',
356 // component: Layout, 356 // component: Layout,
357 // redirect: '/zip/download', 357 // redirect: '/zip/download',
358 // alwaysShow: true, 358 // alwaysShow: true,
359 // name: 'Zip', 359 // name: 'Zip',
360 // meta: { title: 'zip', icon: 'zip' }, 360 // meta: { title: 'zip', icon: 'zip' },
361 // children: [ 361 // children: [
362 // { 362 // {
363 // path: 'download', 363 // path: 'download',
364 // component: () => import('@/views/zip/index'), 364 // component: () => import('@/views/zip/index'),
365 // name: 'ExportZip', 365 // name: 'ExportZip',
366 // meta: { title: 'exportZip' } 366 // meta: { title: 'exportZip' }
367 // } 367 // }
368 // ] 368 // ]
369 // }, 369 // },
370 370
371 // { 371 // {
372 // path: '/pdf', 372 // path: '/pdf',
373 // component: Layout, 373 // component: Layout,
374 // redirect: '/pdf/index', 374 // redirect: '/pdf/index',
375 // children: [ 375 // children: [
376 // { 376 // {
377 // path: 'index', 377 // path: 'index',
378 // component: () => import('@/views/pdf/index'), 378 // component: () => import('@/views/pdf/index'),
379 // name: 'PDF', 379 // name: 'PDF',
380 // meta: { title: 'pdf', icon: 'pdf' } 380 // meta: { title: 'pdf', icon: 'pdf' }
381 // } 381 // }
382 // ] 382 // ]
383 // }, 383 // },
384 // { 384 // {
385 // path: '/pdf/download', 385 // path: '/pdf/download',
386 // component: () => import('@/views/pdf/download'), 386 // component: () => import('@/views/pdf/download'),
387 // hidden: true 387 // hidden: true
388 // }, 388 // },
389 389
390 // { 390 // {
391 // path: '/theme', 391 // path: '/theme',
392 // component: Layout, 392 // component: Layout,
393 // children: [ 393 // children: [
394 // { 394 // {
395 // path: 'index', 395 // path: 'index',
396 // component: () => import('@/views/theme/index'), 396 // component: () => import('@/views/theme/index'),
397 // name: 'Theme', 397 // name: 'Theme',
398 // meta: { title: 'theme', icon: 'theme' } 398 // meta: { title: 'theme', icon: 'theme' }
399 // } 399 // }
400 // ] 400 // ]
401 // }, 401 // },
402 402
403 // { 403 // {
404 // path: '/clipboard', 404 // path: '/clipboard',
405 // component: Layout, 405 // component: Layout,
406 // children: [ 406 // children: [
407 // { 407 // {
408 // path: 'index', 408 // path: 'index',
409 // component: () => import('@/views/clipboard/index'), 409 // component: () => import('@/views/clipboard/index'),
410 // name: 'ClipboardDemo', 410 // name: 'ClipboardDemo',
411 // meta: { title: 'clipboardDemo', icon: 'clipboard' } 411 // meta: { title: 'clipboardDemo', icon: 'clipboard' }
412 // } 412 // }
413 // ] 413 // ]
414 // }, 414 // },
415 415
416 // { 416 // {
417 // path: '/i18n', 417 // path: '/i18n',
418 // component: Layout, 418 // component: Layout,
419 // children: [ 419 // children: [
420 // { 420 // {
421 // path: 'index', 421 // path: 'index',
422 // component: () => import('@/views/i18n-demo/index'), 422 // component: () => import('@/views/i18n-demo/index'),
423 // name: 'I18n', 423 // name: 'I18n',
424 // meta: { title: 'i18n', icon: 'international' } 424 // meta: { title: 'i18n', icon: 'international' }
425 // } 425 // }
426 // ] 426 // ]
427 // }, 427 // },
428 428
429 // { 429 // {
430 // path: 'external-link', 430 // path: 'external-link',
431 // component: Layout, 431 // component: Layout,
432 // children: [ 432 // children: [
433 // { 433 // {
434 // path: 'https://github.com/PanJiaChen/vue-element-admin', 434 // path: 'https://github.com/PanJiaChen/vue-element-admin',
435 // meta: { title: 'externalLink', icon: 'link' } 435 // meta: { title: 'externalLink', icon: 'link' }
436 // } 436 // }
437 // ] 437 // ]
438 // }, 438 // },
439 439
440 // 404 page must be placed at the end !!! 440 // 404 page must be placed at the end !!!
441 { 441 {
442 path: '*', 442 path: '*',
443 redirect: '/404', 443 redirect: '/404',
444 hidden: true 444 hidden: true
445 } 445 }
446 ] 446 ]
447 447
448 const createRouter = () => new Router({ 448 const createRouter = () => new Router({
449 // mode: 'history', // require service support 449 // mode: 'history', // require service support
450 scrollBehavior: () => ({ 450 scrollBehavior: () => ({
451 y: 0 451 y: 0
452 }), 452 }),
453 routes: constantRoutes 453 routes: constantRoutes
454 }) 454 })
455 455
456 const router = createRouter() 456 const router = createRouter()
457 457
458 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465 458 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
459 export function resetRouter() { 459 export function resetRouter() {
460 const newRouter = createRouter() 460 const newRouter = createRouter()
461 router.matcher = newRouter.matcher // reset router 461 router.matcher = newRouter.matcher // reset router
462 } 462 }
463 463
464 export default router 464 export default router
465 465
src/router/modules/user.js
1 /** When your routing table is too long, you can split it into small modules**/ 1 /** When your routing table is too long, you can split it into small modules**/
2 2
3 import Layout from '@/layout' 3 import Layout from '@/layout'
4 4
5 const chartsRouter = { 5 const chartsRouter = {
6 path: '/users', 6 path: '/users',
7 component: Layout, 7 component: Layout,
8 redirect: '/users/page', 8 redirect: '/users/page',
9 alwaysShow: true, // will always show the root menu 9 alwaysShow: true, // will always show the root menu
10 name: 'Users', 10 name: 'Users',
11 meta: { 11 meta: {
12 title: 'users.people', 12 title: 'users.people',
13 icon: 'peoples', 13 icon: 'peoples',
14 roles: ['admin', 'assistant'] // you can set roles in root nav 14 roles: ['admin', 'assistant'] // you can set roles in root nav
15 }, 15 },
16 children: [{ 16 children: [{
17 path: 'assistant', 17 path: '用户管理',
18 component: () => import('@/views/users/list'), 18 component: () => import('@/views/users/list'),
19 name: 'assistant', 19 name: '用户管理',
20 query: { 20 query: {
21 test: 'ssssss' 21 test: 'ssssss'
22 }, 22 },
23 meta: { 23 meta: {
24 title: 'users.assistant', 24 title: '用户管理',
25 roles: ['admin'] // or you can only set roles in sub nav 25 roles: ['admin'] // or you can only set roles in sub nav
26 } 26 }
27 },
28 {
29 path: 'runner',
30 component: () => import('@/views/users/list'),
31 name: 'runner',
32 query: {
33 test: 'ssssss'
34 },
35 meta: {
36 title: 'users.runner',
37 roles: ['admin', 'assistant'] // or you can only set roles in sub nav
38 }
39 },
40 {
41 path: 'shoper',
42 component: () => import('@/views/users/list'),
43 name: 'shoper',
44 query: {
45 test: 'ssssss'
46 },
47 meta: {
48 title: 'users.shoper',
49 roles: ['admin', 'assistant'] // or you can only set roles in sub nav
50 }
51 },
52 {
53 path: 'users',
54 component: () => import('@/views/users/list'),
55 name: 'users',
56 query: {
57 test: 'ssssss'
58 },
59 meta: {
60 title: 'users.user',
61 roles: ['admin', 'assistant'] // or you can only set roles in sub nav
62 }
63 } 27 }
64 // ,{
65 // path: '/icons',
66 // component: () => import('@/views/icons/index'),
67 // name: 'icons',
68 // meta: {
69 // title: 'icons',
70 // roles: ['admin', 'assistant', 'shoper', 'runner'] // or you can only set roles in sub nav
71 // }
72 // }
73 ] 28 ]
74 } 29 }
75 30
76 export default chartsRouter 31 export default chartsRouter
77 32
src/styles/sidebar.scss
1 #app { 1 #app {
2 2
3 .main-container { 3 .main-container {
4 min-height: 100%; 4 min-height: 100%;
5 transition: margin-left .28s; 5 transition: margin-left .28s;
6 margin-left: $sideBarWidth; 6 // margin-left: $sideBarWidth;
7 margin-top: 54px;
7 position: relative; 8 position: relative;
8 } 9 }
9 10
10 .sidebar-container { 11 .sidebar-container {
11 transition: width 0.28s; 12 transition: width 0.28s;
12 width: $sideBarWidth !important; 13 // width: $sideBarWidth !important;
14 width: 100% !important;
13 background-color: $menuBg; 15 background-color: $menuBg;
14 height: 100%; 16 // height: 100%;
17 height: 54px;
15 position: fixed; 18 position: fixed;
16 font-size: 0px; 19 font-size: 0px;
17 top: 0; 20 top: 0;
18 bottom: 0; 21 bottom: 0;
19 left: 0; 22 left: 0;
20 z-index: 1001; 23 z-index: 1001;
21 overflow: hidden; 24 overflow: hidden;
22 25
23 // reset element-ui css 26 // reset element-ui css
24 .horizontal-collapse-transition { 27 .horizontal-collapse-transition {
25 transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; 28 transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
26 } 29 }
27 30
28 .scrollbar-wrapper { 31 .scrollbar-wrapper {
29 overflow-x: hidden !important; 32 overflow-x: hidden !important;
30 } 33 }
31 34
32 .el-scrollbar__bar.is-vertical { 35 .el-scrollbar__bar.is-vertical {
33 right: 0px; 36 right: 0px;
34 } 37 }
35 38
36 .el-scrollbar { 39 .el-scrollbar {
37 height: 100%; 40 height: 100%;
38 } 41 }
39 42
40 &.has-logo { 43 &.has-logo {
41 .el-scrollbar { 44 .el-scrollbar {
42 height: calc(100% - 50px); 45 height: calc(100% - 50px);
43 } 46 }
44 } 47 }
45 48
46 .is-horizontal { 49 .is-horizontal {
47 display: none; 50 display: none;
48 } 51 }
49 52
50 a { 53 a {
51 display: inline-block; 54 display: inline-block;
52 width: 100%; 55 width: 100%;
53 overflow: hidden; 56 overflow: hidden;
54 } 57 }
55 58
56 .svg-icon { 59 .svg-icon {
57 margin-right: 16px; 60 margin-right: 16px;
58 } 61 }
59 62
60 .el-menu { 63 .el-menu {
61 border: none; 64 border: none;
62 height: 100%; 65 height: 100%;
63 width: 100% !important; 66 width: 100% !important;
64 } 67 }
65 68
66 // menu hover 69 // menu hover
67 .submenu-title-noDropdown, 70 .submenu-title-noDropdown,
68 .el-submenu__title { 71 .el-submenu__title {
69 &:hover { 72 &:hover {
70 background-color: $menuHover !important; 73 background-color: $menuHover !important;
71 } 74 }
72 } 75 }
73 76
74 .is-active>.el-submenu__title { 77 .is-active>.el-submenu__title {
75 color: $subMenuActiveText !important; 78 color: $subMenuActiveText !important;
76 } 79 }
77 80
78 & .nest-menu .el-submenu>.el-submenu__title, 81 & .nest-menu .el-submenu>.el-submenu__title,
79 & .el-submenu .el-menu-item { 82 & .el-submenu .el-menu-item {
80 min-width: $sideBarWidth !important; 83 min-width: $sideBarWidth !important;
81 background-color: $subMenuBg !important; 84 background-color: $subMenuBg !important;
82 85
83 &:hover { 86 &:hover {
84 background-color: $subMenuHover !important; 87 background-color: $subMenuHover !important;
85 } 88 }
86 } 89 }
87 } 90 }
88 91
89 .hideSidebar { 92 .hideSidebar {
90 .sidebar-container { 93 .sidebar-container {
91 width: 54px !important; 94 width: 54px !important;
92 } 95 }
93 96
94 .main-container { 97 .main-container {
95 margin-left: 54px; 98 margin-left: 54px;
96 } 99 }
97 100
98 .submenu-title-noDropdown { 101 .submenu-title-noDropdown {
99 padding: 0 !important; 102 padding: 0 !important;
100 position: relative; 103 position: relative;
101 104
102 .el-tooltip { 105 .el-tooltip {
103 padding: 0 !important; 106 padding: 0 !important;
104 107
105 .svg-icon { 108 .svg-icon {
106 margin-left: 20px; 109 margin-left: 20px;
107 } 110 }
108 } 111 }
109 } 112 }
110 113
111 .el-submenu { 114 .el-submenu {
112 overflow: hidden; 115 overflow: hidden;
113 116
114 &>.el-submenu__title { 117 &>.el-submenu__title {
115 padding: 0 !important; 118 padding: 0 !important;
116 119
117 .svg-icon { 120 .svg-icon {
118 margin-left: 20px; 121 margin-left: 20px;
119 } 122 }
120 123
121 .el-submenu__icon-arrow { 124 .el-submenu__icon-arrow {
122 display: none; 125 display: none;
123 } 126 }
124 } 127 }
125 } 128 }
126 129
127 .el-menu--collapse { 130 .el-menu--collapse {
128 .el-submenu { 131 .el-submenu {
129 &>.el-submenu__title { 132 &>.el-submenu__title {
130 &>span { 133 &>span {
131 height: 0; 134 height: 0;
132 width: 0; 135 width: 0;
133 overflow: hidden; 136 overflow: hidden;
134 visibility: hidden; 137 visibility: hidden;
135 display: inline-block; 138 display: inline-block;
136 } 139 }
137 } 140 }
138 } 141 }
139 } 142 }
140 } 143 }
141 144
142 .el-menu--collapse .el-menu .el-submenu { 145 .el-menu--collapse .el-menu .el-submenu {
143 min-width: $sideBarWidth !important; 146 min-width: $sideBarWidth !important;
144 } 147 }
145 148
146 // mobile responsive 149 // mobile responsive
147 .mobile { 150 .mobile {
148 .main-container { 151 .main-container {
149 margin-left: 0px; 152 margin-left: 0px;
150 } 153 }
151 154
152 .sidebar-container { 155 .sidebar-container {
153 transition: transform .28s; 156 transition: transform .28s;
154 width: $sideBarWidth !important; 157 width: $sideBarWidth !important;
155 } 158 }
156 159
157 &.hideSidebar { 160 &.hideSidebar {
158 .sidebar-container { 161 .sidebar-container {
159 pointer-events: none; 162 pointer-events: none;
160 transition-duration: 0.3s; 163 transition-duration: 0.3s;
161 transform: translate3d(-$sideBarWidth, 0, 0); 164 transform: translate3d(-$sideBarWidth, 0, 0);
162 } 165 }
163 } 166 }
164 } 167 }
165 168
166 .withoutAnimation { 169 .withoutAnimation {
167 170
168 .main-container, 171 .main-container,
169 .sidebar-container { 172 .sidebar-container {
170 transition: none; 173 transition: none;
171 } 174 }
172 } 175 }
173 } 176 }
174 177
175 // when menu collapsed 178 // when menu collapsed
176 .el-menu--vertical { 179 .el-menu--vertical {
177 &>.el-menu { 180 &>.el-menu {
178 .svg-icon { 181 .svg-icon {
179 margin-right: 16px; 182 margin-right: 16px;
180 } 183 }
181 } 184 }
182 185
183 .nest-menu .el-submenu>.el-submenu__title, 186 .nest-menu .el-submenu>.el-submenu__title,
184 .el-menu-item { 187 .el-menu-item {
185 &:hover { 188 &:hover {
186 // you can use $subMenuHover 189 // you can use $subMenuHover
187 background-color: $menuHover !important; 190 background-color: $menuHover !important;
188 } 191 }
189 } 192 }
190 193
191 // the scroll bar appears when the subMenu is too long 194 // the scroll bar appears when the subMenu is too long
192 >.el-menu--popup { 195 >.el-menu--popup {
193 max-height: 100vh; 196 max-height: 100vh;
194 overflow-y: auto; 197 overflow-y: auto;
195 198
196 &::-webkit-scrollbar-track-piece { 199 &::-webkit-scrollbar-track-piece {
197 background: #d3dce6; 200 background: #d3dce6;
198 } 201 }
199 202
200 &::-webkit-scrollbar { 203 &::-webkit-scrollbar {
201 width: 6px; 204 width: 6px;
202 } 205 }
203 206
204 &::-webkit-scrollbar-thumb { 207 &::-webkit-scrollbar-thumb {
205 background: #99a9bf; 208 background: #99a9bf;
206 border-radius: 20px; 209 border-radius: 20px;
207 } 210 }
208 } 211 }
209 } 212 }
210 213
src/views/operations/operations.vue
1 <template> 1 <template>
2 <div class="login-container"> 2 <el-container style=" border: 1px solid #eee">
3 <el-button 3 <el-main>
4 type="primary" 4 <el-tabs v-model="activeName" tab-position="top" @tab-click="handleClick">
5 @click="() => addNode()" 5 <el-tab-pane label="秀野堂主" name="first">
6 >{{ $t('users.add') }}</el-button> 6 <span />
7 <el-tree 7 </el-tab-pane>
8 ref="tree" 8 <el-tab-pane label="Richa" name="second" />
9 :data="data" 9 </el-tabs>
10 show-checkbox 10 </el-main>
11 node-key="id" 11 </el-container>
12 highlight-current
13 check-strictly
14 indent="40"
15 icon-class="el-icon-pc"
16 :props="defaultProps"
17 >
18 <!-- <el-tree
19 :data="data"
20 show-checkbox
21 node-key="id"
22 default-expand-all
23 highlight-current
24 isLeaf
25 @node-contextmenu="()=>rightKey(node, data)"
26 check-strictly//在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false
27 :expand-on-click-node="false"//是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。
28 :props="defaultProps"
29 > -->
30 <span
31 slot-scope="{ node, data }"
32 class="custom-tree-node"
33 >
34 <span>{{ node.label }}</span>
35 <span>
36 <el-button
37 type="primary"
38 icon="el-icon-upload"
39 size="mini"
40 @click="() => append(data)"
41 >
42 {{ $t('users.add') }}
43 </el-button>
44 <el-button
45 type="primary"
46 icon="el-icon-edit"
47 size="mini"
48 @click="() => update(node, data)"
49 >
50 {{ $t('users.update') }}
51 </el-button>
52 <el-button
53 type="primary"
54 icon="el-icon-delete"
55 size="mini"
56 class="danger"
57 @click="() => remove(node, data)"
58 >
59 {{ $t('users.del') }}
60 </el-button>
61 </span>
62 </span>
63 </el-tree>
64
65 <!-- <div class="buttons">
66 <el-button @click="getCheckedNodes">通过 node 获取</el-button>
67 <el-button @click="getCheckedKeys">通过 key 获取</el-button>
68 <el-button @click="setCheckedNodes">通过 node 设置</el-button>
69 <el-button @click="setCheckedKeys">通过 key 设置</el-button>
70 <el-button @click="resetChecked">清空</el-button>
71 </div> -->
72 </div>
73 </template> 12 </template>
74 <script> 13 <script>
75 let id = 1000
76 export default { 14 export default {
77 data() { 15 data() {
78 return { 16 return {
79 data: [ 17
80 {
81 label: '成镜',
82 id: '1',
83 children: [
84 {
85 label: '款式',
86 id: '11',
87 children: [
88 { label: '青春学子风' },
89 { label: '休闲' },
90 { label: '商务' },
91 { label: '复古' },
92 { label: '时尚' },
93 { label: '质感哥特潮' },
94 { label: '轻简北欧风' },
95 { label: '理性几何派' },
96 { label: '多元新风尚' },
97 { label: '立体巴洛克' },
98 { label: '有机未来时' },
99 { label: '无界人文系' },
100 { label: '自然舒视角' },
101 { label: '流线洛可可' },
102 { label: '奶奶风' },
103 { label: '简约-极简文艺范' },
104 { label: '运动风' },
105 { label: '行政风' },
106 { label: '折射率' }
107 ]
108 },
109 { label: '个性化服务', id: '267', children: [] },
110 {
111 label: '赠品',
112 id: '259',
113 children: [{ label: '眼镜布' }, { label: '眼镜盒' }]
114 },
115 {
116 label: '场景',
117 id: '258',
118 children: [
119 { label: '学校场景' },
120 { label: '出行交际' },
121 { label: '夜店迷人' },
122 { label: '明星同款' }
123 ]
124 },
125 {
126 label: '销售保障',
127 id: '245',
128 children: [
129 { label: '可退' },
130 { label: '可换' },
131 { label: '可修' }
132 ]
133 },
134 {
135 label: '功能',
136 id: '140',
137 children: [
138 { label: '防踩压' },
139 { label: '防扭曲' },
140 { label: '抗过敏' },
141 { label: '防腐蚀' },
142 { label: '耐磨损' },
143 { label: '抗蓝光' }
144 ]
145 },
146 {
147 label: '品牌',
148 id: '71',
149 children: [
150 { label: '购易' },
151 { label: '海俪恩' },
152 { label: '沙漠风暴' },
153 { label: '古诗' },
154 { label: '暴龙' },
155 { label: '犀牛' },
156 { label: 'Ray-Ban雷朋' },
157 { label: 'PARIM派丽蒙' },
158 { label: '石狼' },
159 { label: '木九十' }
160 ]
161 },
162 {
163 label: '边形',
164 id: '49',
165 children: [
166 { label: '半框' },
167 { label: '全框' },
168 { label: '无框' }
169 ]
170 },
171 {
172 label: '性别',
173 id: '23',
174 children: [{ label: '男性' }, { label: '女性' }]
175 },
176 {
177 label: '梁型',
178 id: '20',
179 children: [{ label: '双梁' }, { label: '单梁' }]
180 },
181 {
182 label: '重量',
183 id: '19',
184 children: [{ label: '30克以下' }, { label: '80克以上' }]
185 },
186 {
187 label: '适用脸型',
188 id: '15',
189 children: [{ label: '方' }, { label: '圆' }, { label: '瓜子' }]
190 },
191 {
192 label: '形状',
193 id: '14',
194 children: [
195 { label: '正圆形' },
196 { label: '椭圆形' },
197 { label: '方圆' },
198 { label: '方形' },
199 { label: '多边形' },
200 { label: '内三角(蛤蟆)' },
201 { label: '外三角(蝶形)' }
202 ]
203 },
204 { label: '年龄', id: '12', children: [{ label: '通用' }] },
205 {
206 label: '材质',
207 id: '10',
208 children: [
209 { label: '板材' },
210 { label: '纯钛' },
211 { label: 'TR90' },
212 { label: '木质' },
213 { label: '竹质' },
214 { label: 'β钛' },
215 { label: 'PC' },
216 { label: 'ULTEM塑钢' },
217 { label: '钨钛塑钢' },
218 { label: '镁铝合金' },
219 { label: '碳纤维' }
220 ]
221 },
222 { label: '折射率', id: '286', children: [] },
223 {
224 label: '颜色',
225 id: '13',
226 children: [
227 { label: '金色' },
228 { label: '银色' },
229 { label: '黑色' },
230 { label: '彩色' },
231 { label: '枪色' }
232 ]
233 }
234 ]
235 },
236 {
237 label: '镜片',
238 id: '2',
239 children: [
240 {
241 label: '面型',
242 id: '85',
243 children: [{ label: '球面单光' }, { label: '非球面单光' }]
244 },
245 { label: '近视度数', id: '92', children: [] },
246 { label: '散光', id: '93', children: [] },
247 {
248 label: '功能',
249 id: '95',
250 children: [
251 { label: '防起雾' },
252 { label: '防蓝光' },
253 { label: '防紫外线' },
254 { label: '偏光' },
255 { label: '染色' },
256 { label: '抗疲劳' },
257 { label: '青少年渐进' },
258 { label: '内渐进' },
259 { label: '变色' },
260 { label: '双光' },
261 { label: '耐磨损' },
262 { label: '防尘' },
263 { label: '防水' },
264 { label: '防摔' },
265 { label: '防指纹' },
266 { label: '防反光' }
267 ]
268 },
269 {
270 label: '颜色',
271 id: '100',
272 children: [
273 { label: '透明' },
274 { label: '染色' },
275 { label: '变色' },
276 { label: '单色' }
277 ]
278 },
279 {
280 label: '折射率',
281 id: '101',
282 children: [
283 { label: '1.56' },
284 { label: '1.60' },
285 { label: '1.65' },
286 { label: '1.67' },
287 { label: '1.71' },
288 { label: '1.74' }
289 ]
290 },
291 { label: '阿贝数(色散)', id: '102', children: [] },
292 { label: '重量', id: '103', children: [] },
293 {
294 label: '材质',
295 id: '104',
296 children: [
297 { label: '树脂' },
298 { label: '玻璃' },
299 { label: '宇宙PC' },
300 { label: 'PC' }
301 ]
302 },
303 {
304 label: '品牌',
305 id: '118',
306 children: [
307 { label: '好视力' },
308 { label: 'RAISE锐视' },
309 { label: '依视路' },
310 { label: '凯米' },
311 { label: '蔡司' },
312 { label: '舒曼' }
313 ]
314 },
315 {
316 label: '销售保障',
317 id: '249',
318 children: [
319 { label: '可退' },
320 { label: '可换' },
321 { label: '可修' }
322 ]
323 }
324 ]
325 },
326 {
327 label: '隐形眼镜',
328 id: '88',
329 children: [
330 {
331 label: '颜色',
332 id: '105',
333 children: [
334 { label: '绿' },
335 { label: '灰' },
336 { label: '黑' },
337 { label: '紫' },
338 { label: '蓝' },
339 { label: '棕色' },
340 { label: '紫色' }
341 ]
342 },
343 {
344 label: '颜料',
345 id: '106',
346 children: [{ label: '水性' }, { label: '油性' }]
347 },
348 { label: '度数', id: '107', children: [] },
349 {
350 label: '周期',
351 id: '108',
352 children: [
353 { label: '日抛' },
354 { label: '周抛' },
355 { label: '双周抛' },
356 { label: '月抛' },
357 { label: '季抛' },
358 { label: '半年抛' },
359 { label: '年抛' }
360 ]
361 },
362 {
363 label: '品牌',
364 id: '133',
365 children: [
366 { label: 'HolyNara' },
367 { label: '爱尔康' },
368 { label: 'MaxLook' },
369 { label: 'NEO' },
370 { label: 'GEO' },
371 { label: '实瞳' },
372 { label: '茵洛' },
373 { label: 'DAZZSHOP' },
374 { label: 'O-LENS' },
375 { label: 'envie' },
376 { label: '曼秀雷敦' },
377 { label: '妃蜜莉' },
378 { label: '海俪恩' },
379 { label: '凯达' },
380 { label: '蔡司' },
381 { label: '酷视' },
382 { label: 'LILMOON' },
383 { label: 'RICHBABY' },
384 { label: 'T-Garden' },
385 { label: 'lenstown' },
386 { label: '新加坡P2' },
387 { label: '星欧' },
388 { label: '美尼康' },
389 { label: '美汐' },
390 { label: '欧舒天' },
391 { label: '海昌' },
392 { label: '菲士康' },
393 { label: '卫康' },
394 { label: '库博' },
395 { label: '安视优' },
396 { label: '美若康' },
397 { label: '视康' },
398 { label: '澜柏' },
399 { label: '3N' },
400 { label: 'BIJOU' },
401 { label: '依视明' },
402 { label: '博士伦' },
403 { label: '瞳昕' },
404 { label: '科莱博' },
405 { label: '绮芙莉' },
406 { label: '雅培' },
407 { label: '爱能视' },
408 { label: '女神秘语' },
409 { label: '博视顿' },
410 { label: '妆美堂' },
411 { label: '人鱼姬' },
412 { label: 'EverColor' },
413 { label: 'Sincere' }
414 ]
415 },
416 {
417 label: '工艺',
418 id: '159',
419 children: [{ label: '涂层工艺' }, { label: '三层夹色工艺' }]
420 },
421 {
422 label: '材质',
423 id: '164',
424 children: [{ label: '硅水凝胶' }, { label: '水凝胶' }]
425 },
426 {
427 label: '含水量',
428 id: '174',
429 children: [
430 { label: '0-40%' },
431 { label: '40-44%' },
432 { label: '45%以上' }
433 ]
434 },
435 {
436 label: '基弧',
437 id: '178',
438 children: [{ label: '0.0-8.4' }, { label: '8.4以上' }]
439 },
440 {
441 label: '直径',
442 id: '181',
443 children: [{ label: '13.4-14' }, { label: '14以上' }]
444 },
445 {
446 label: '中心厚度',
447 id: '184',
448 children: [
449 { label: '0.0 - 0.03' },
450 { label: '0.04 - 0.09' },
451 { label: '0.1以上' }
452 ]
453 },
454 { label: '销售保障', id: '253', children: [] },
455 { label: '赠品', id: '260', children: [] }
456 ]
457 },
458 {
459 label: '特种镜',
460 id: '146',
461 children: [
462 {
463 label: '镜面颜色',
464 id: '237',
465 children: [{ label: '透明' }, { label: '亮金色' }]
466 },
467 {
468 label: '品牌',
469 id: '238',
470 children: [{ label: '宁哥牌' }, { label: '秀野牌' }]
471 },
472 {
473 label: '销售保障',
474 id: '254',
475 children: [{ label: '包退' }, { label: '包换' }]
476 },
477 {
478 label: '功能',
479 id: '268',
480 children: [
481 { label: '防风镜' },
482 { label: '防爆溅工作镜' },
483 { label: '泳镜' },
484 { label: '智能镜' }
485 ]
486 }
487 ]
488 }
489 ],
490 defaultProps: {
491 children: 'children',
492 label: 'label'
493 }
494 } 18 }
495 }, 19 },
496 methods: { 20 methods: {
497 getCheckedNodes() {
498 console.log(this.$refs.tree.getCheckedNodes())
499 },
500 getCheckedKeys() {
501 console.log(this.$refs.tree.getCheckedKeys())
502 },
503 addNode() {
504 let h
505 this.$message({
506 message: h('p', null, [
507 h('span', null, '添加一个新节点 ')
508 // h("i", { style: "color: teal" }, "VNode")
509 ])
510 })
511 },
512 append(data) {
513 const newChild = { id: id++, label: 'testtest', children: [] }
514 if (!data.children) {
515 this.$set(data, 'children', [])
516 }
517 data.children.push(newChild)
518 },
519 remove(node, data) {
520 // 删除
521 const parent = node.parent
522 const children = parent.data.children || parent.data
523 const index = children.findIndex(d => d.id === data.id)
524 children.splice(index, 1)
525 },
526 rightKey(node, data) {
527 // 右键
528 const h = this.$createElement
529 // console.log(data, this.$refs.tree);
530 this.$message({
531 message: h('p', null, [
532 h('span', null, '右键了啊! ' + node + data),
533 h('i', { style: 'color: teal' }, 'VNode')
534 ])
535 })
536 },
537 update(node, data) {
538 // 更新
539 const h = this.$createElement
540 this.$message({
541 message: h('p', null, [
542 h('span', null, '内容可以是 '),
543 h('i', { style: 'color: teal' }, 'VNode')
544 ])
545 })
546 },
547 setCheckedNodes() {
548 this.$refs.tree.setCheckedNodes([
549 {
550 id: 5,
551 label: '二级 2-1'
552 },
553 {
554 id: 9,
555 label: '三级 1-1-1'
556 }
557 ])
558 },
559 setCheckedKeys() {
560 this.$refs.tree.setCheckedKeys([3])
561 },
562 resetChecked() {
563 this.$refs.tree.setCheckedKeys([])
564 }
565 } 21 }
566 } 22 }
567 </script> 23 </script>
568 <style> 24 <style>
569 .custom-tree-node {
570 flex: 1;
571 display: flex;
572 align-items: center;
573 justify-content: space-between;
574 font-size: 14px;
575 padding-right: 8px;
576 }
577 </style> 25 </style>
578 26