调整界面和底座风格基本保持一致
This commit is contained in:
		
							
								
								
									
										254
									
								
								examples/components/sliderNav.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								examples/components/sliderNav.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,254 @@ | ||||
| <template> | ||||
|   <section class="sliderNav"> | ||||
|     <el-input class="searchApp" size="small" v-model="searchApp" placeholder="搜索应用" clearable | ||||
|               prefix-icon="iconfont iconSearch" @change="recordSearch"/> | ||||
|     <el-scrollbar class="ai-menu"> | ||||
|       <div v-for="(item,i) in navs" :key="i"> | ||||
|         <div class="rootMenu" :class="{isActive:menuPath.includes(item.name)}" | ||||
|              @click.stop="openKidMenu(item)"> | ||||
|           <i class="prep-icon" :class="item.style||'iconfont iconloudongmoxing'"/> | ||||
|           <span class="menuName fill" v-text="item.label"/> | ||||
|           <i v-if="item.children" class="iconfont" :class="arrowIcon(item.showChildren)"/> | ||||
|         </div> | ||||
|         <div class="kidMenu" v-if="item.showChildren" @click.stop> | ||||
|           <div class="kidPane"> | ||||
|             <div class="submenu wrap" flex v-for="menu in item.children" :key="menu.name"> | ||||
|               <b v-text="menu.label" :class="{menuBtn:menu.type==1,current:menuPath.includes(menu.name)}" | ||||
|                  @click="handleSelect(menu)"/> | ||||
|               <div class="menuBtn" v-for="kid in menu.children" :key="kid.name" v-text="kid.label" | ||||
|                    @click="handleSelect(kid)" | ||||
|                    :class="{current:menuPath.includes(kid.name)}"/> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="divider"/> | ||||
|     </el-scrollbar> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "sliderNav", | ||||
|   data() { | ||||
|     return { | ||||
|       searchApp: "", | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user', 'apps']), | ||||
|     navs() { | ||||
|       let reg = new RegExp(`.*${this.searchApp?.replace(/-/g,'')||''}.*`, 'gi') | ||||
|       return (this.apps || []).filter(e => !this.searchApp || reg?.test(e.name) || reg?.test(e.label)) | ||||
|     }, | ||||
|     isConsoleRoute() { | ||||
|       return this.$route.name == "工作台" | ||||
|     }, | ||||
|     menuPath() { | ||||
|       let paths = [], current = this.apps?.find(e => e.name == this.$route.name) | ||||
|       const findParent = name => { | ||||
|         let menu = this.apps?.find(e => e.name == name) | ||||
|         if (menu) { | ||||
|           paths.push(menu.name) | ||||
|           if (!!menu.parentId) findParent(menu.parentId) | ||||
|         } | ||||
|       } | ||||
|       if (current) { | ||||
|         findParent(current.name) | ||||
|       } | ||||
|       return paths | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     openKidMenu(parent) { | ||||
|       if (parent.children) { | ||||
|         parent.showChildren = !parent.showChildren | ||||
|       } else { | ||||
|         this.handleSelect(parent) | ||||
|       } | ||||
|     }, | ||||
|     handleSelect(item) { | ||||
|       if (!item.path) return | ||||
|       if (item.name == this.$route.name) { | ||||
|         //避免同一路由跳转的BUG vue-router官方BUG | ||||
|       } else { | ||||
|         let {name, path} = item | ||||
|         if (/\?app=/.test(path)) { | ||||
|           this.goto({name, query: {app: path.replace(/.+\?app=/, '')}}) | ||||
|         } else if (/\?moduleId=/.test(path)) { | ||||
|           this.goto({name, query: {moduleId: path.replace(/.+\?moduleId=/, '')}}) | ||||
|         } else { | ||||
|           this.goto({name}) | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     goto(item) { | ||||
|       this.$router.push(item) | ||||
|     }, | ||||
|     subMenuIcon(flag) { | ||||
|       return flag ? 'iconfont iconArrow_Down' : "iconfont iconArrow_Right" | ||||
|     }, | ||||
|     arrowIcon(v) { | ||||
|       return v ? "iconArrow_Down" : "iconArrow_Right" | ||||
|     }, | ||||
|     recordSearch() { | ||||
|       localStorage.setItem("searchApp", this.searchApp) | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.searchApp = localStorage.getItem("searchApp") || "" | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| .sliderNav { | ||||
|   width: 200px; | ||||
|   height: 100%; | ||||
|   transition: width .1s; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   flex-direction: column; | ||||
|   border-right: 1px solid #e5e5e5; | ||||
|   flex-shrink: 0; | ||||
|   box-sizing: border-box; | ||||
|   background: #EFF1F4; | ||||
|   color: #222; | ||||
|   position: relative; | ||||
|  | ||||
|   .kidMenu { | ||||
|     padding: 0 16px; | ||||
|     background: #EFF1F4; | ||||
|  | ||||
|     .rootName { | ||||
|       font-size: 20px; | ||||
|       color: #333; | ||||
|       cursor: default; | ||||
|     } | ||||
|  | ||||
|     .kidPane { | ||||
|       font-size: 13px; | ||||
|  | ||||
|       .submenu { | ||||
|         margin-top: 8px; | ||||
|         width: 100%; | ||||
|         color: #aaa; | ||||
|  | ||||
|         & > b { | ||||
|           width: 100%; | ||||
|           line-height: 28px; | ||||
|         } | ||||
|  | ||||
|         & > * { | ||||
|           cursor: default; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .menuBtn { | ||||
|         display: block; | ||||
|         width: 50%; | ||||
|         cursor: pointer; | ||||
|         line-height: 32px; | ||||
|         color: #333; | ||||
|         flex-shrink: 0; | ||||
|  | ||||
|         &:hover { | ||||
|           color: #26f; | ||||
|         } | ||||
|  | ||||
|         &.current { | ||||
|           color: #26f; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .rootMenu { | ||||
|     padding: 0 16px; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     height: 44px; | ||||
|     cursor: pointer; | ||||
|     box-shadow: 0px -1px 0px 0px #D8DCE3 inset, 0px 1px 0px 0px #FFF inset, -1px 0px 0px 0px #E5E5E5 inset; | ||||
|     gap: 8px; | ||||
|     font-size: 13px; | ||||
|  | ||||
|     .iconfont { | ||||
|       color: #89B; | ||||
|       font-size: 20px; | ||||
|     } | ||||
|  | ||||
|     &.isActive { | ||||
|       color: #26f; | ||||
|  | ||||
|       .iconfont { | ||||
|         color: #26f !important; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     &:hover { | ||||
|       color: #26f; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-menu { | ||||
|     padding-left: 0; | ||||
|     flex: 1; | ||||
|     min-height: 0; | ||||
|  | ||||
|     .el-scrollbar__wrap { | ||||
|       overflow-x: auto; | ||||
|     } | ||||
|  | ||||
|     &::-webkit-scrollbar { | ||||
|       display: none; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .searchApp { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     height: 44px; | ||||
|     padding: 0 16px; | ||||
|     box-shadow: 0px -1px 0px 0px #E5E5E5 inset; | ||||
|  | ||||
|     .el-input__inner { | ||||
|       border: none; | ||||
|       background: inherit; | ||||
|       padding: 0 28px; | ||||
|     } | ||||
|  | ||||
|     .el-input__prefix { | ||||
|       left: 16px; | ||||
|  | ||||
|       .iconSearch { | ||||
|         font-size: 20px; | ||||
|         width: fit-content; | ||||
|         color: #89B; | ||||
|         line-height: 44px; | ||||
|       } | ||||
|  | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .divider { | ||||
|     color: #aaa; | ||||
|     border-top: 1px solid #ddd; | ||||
|     position: relative; | ||||
|     font-size: 12px; | ||||
|     margin: 16px 16px 32px; | ||||
|  | ||||
|     &:before { | ||||
|       content: "到达底部"; | ||||
|       position: absolute; | ||||
|       top: 50%; | ||||
|       left: 50%; | ||||
|       transform: translate(-50%, -50%); | ||||
|       padding: 0 16px; | ||||
|       background: #EFF1F4; | ||||
|       white-space: nowrap; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user