浏览代码

xxxx:
1. 基础布局组件,侧边栏动态样式制作

kindring 2 年之前
父节点
当前提交
d1078dca21
共有 5 个文件被更改,包括 244 次插入41 次删除
  1. 1 0
      assets/icons/svg/arrow-down.svg
  2. 1 0
      assets/icons/svg/arrow-up.svg
  3. 234 37
      components/layout/adminLayout.vue
  4. 5 3
      map/adminSideBar.js
  5. 3 1
      pages/manger/index.vue

+ 1 - 0
assets/icons/svg/arrow-down.svg

@@ -0,0 +1 @@
+<svg t="1688635660812" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5400" width="200" height="200"><path d="M888.2 286.1L512 662.3 135.8 286.1c-16.4-16.4-43.1-16.4-59.5 0s-16.4 43.1 0 59.5l382.6 382.6c14.2 14.2 33 22 53.1 22s38.9-7.8 53.1-22l382.6-382.6c16.4-16.4 16.4-43.1 0-59.5-16.5-16.4-43.1-16.4-59.5 0z" fill="#272636" p-id="5401"></path></svg>

+ 1 - 0
assets/icons/svg/arrow-up.svg

@@ -0,0 +1 @@
+<svg t="1688635748482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6494" width="200" height="200"><path d="M904.533333 674.133333l-362.666666-362.666666c-17.066667-17.066667-42.666667-17.066667-59.733334 0l-362.666666 362.666666c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733333 0L512 401.066667l332.8 332.8c8.533333 8.533333 19.2 12.8 29.866667 12.8s21.333333-4.266667 29.866666-12.8c17.066667-17.066667 17.066667-42.666667 0-59.733334z" p-id="6495"></path></svg>

+ 234 - 37
components/layout/adminLayout.vue

@@ -4,14 +4,28 @@ export default {
   name: "adminLayout",
   props: {
     headerHeight: {
-      default: 35
+      default: '35px'
     },
     sideBarWidth: {
-      default: 270
+      default: '270px'
     },
     sideBarHeight: {
-      default: 35
+      default: '35px'
     },
+    bgColor: {default: '#fff'},
+    sideBarColor: {default: '#bebebe'},
+    headerBgColor: {default: '#086fb6'},
+    // 文本颜色, 主要文本颜色 次要文本颜色
+    textColor: {default: '#333'},
+    mainTextColor: {default: '#333'},
+    textColorHover: {default: '#fff'},
+    mainTextColorHover: {default: '#fff'},
+
+    btnColor: {default: '#086fb6'},
+    btnColorHover: {default: '#086fb6'},
+    btnTextColor: {default: '#fff'},
+    btnTextColorHover: {default: '#fff'},
+
     sidebarMenus: {
       default(){
         return []
@@ -33,44 +47,75 @@ export default {
     },
     userName: {
       default: ''
-    }
+    },
+    btnLink: {
+      type: Boolean,
+      default: false
+    },
+    activeKey: {
+      default: ''
+    },
   },
   data(){
     return {
       isShowSideBar: true,
-      headerStyle: '',
-      boxStyle: '',
-      sideBarStyle: '',
-      conStyle: '',
+      cssText: '',
+      sideMenus: [],
     }
   },
   beforeMount() {
     this.init_computedStyle();
   },
+  watch:{
+    sidebarMenus(){
+      this.init_comSideBar();
+    },
+  },
+  mounted() {
+    this.init_comSideBar();
+  },
   methods:{
-    /**
-     * 计算dom元素样式
-     */
-    init_computedStyle(){
-      let headerStyle= ``,
-          boxStyle = ``,
-          sideBarStyle = ``,
-          conStyle = ``;
-      let nextSideBarWidth = this.isShowSideBar?this.sideBarWidth:this.sideBarHeight;
-      headerStyle+=`height:${this.headerHeight}px`;
-      boxStyle += `height:calc(100% - ${this.headerHeight}px);` ;
-      sideBarStyle += `width:${nextSideBarWidth}px;`;
-      conStyle += `width:calc(100% - ${nextSideBarWidth}px);` ;
-      this.headerHeight = headerStyle;
-      this.boxStyle = boxStyle;
-      this.sideBarStyle = sideBarStyle;
-      this.conStyle = conStyle;
+    init_comSideBar(){
+      // 循环遍历菜单
+      this.sideMenus = this.sidebarMenus.map((item)=>{
+        let newItem = {...item};
+        newItem.isShow = false;
+        return newItem;
+      });
     },
     switchHandle(){
       if(!this.interactSideBar){return console.log('不允许交互sidebar');}
       this.isShowSideBar = !this.isShowSideBar;
       this.init_computedStyle();
-    }
+    },
+
+    switchSideBarMenuHandle(item){
+      item.isShow = !item.isShow;
+    },
+
+    /**
+     * 计算dom元素样式
+     */
+    init_computedStyle(){
+      let cssText = `
+      --headerHeight: ${this.headerHeight};
+      --sideBarWidth: ${this.isShowSideBar?this.sideBarWidth:this.sideBarHeight};
+      --baseSideBarWidth: ${this.sideBarWidth};
+      --sideBarHeight: ${this.sideBarHeight};
+      --bg-color: ${this.bgColor};
+      --sideBarBgColor: ${this.sideBarColor};
+      --header-color: ${this.headerBgColor};
+      --text-color: ${this.textColor};
+      --main-text-color: ${this.mainTextColor};
+      --text-color-hover: ${this.textColorHover};
+      --main-text-color-hover: ${this.mainTextColorHover};
+      --btn-color: ${this.btnColor};
+      --btn-color-hover: ${this.btnColorHover};
+      --btn-text-color: ${this.btnTextColor};
+      --btn-text-color-hover: ${this.btnTextColorHover};
+      `;
+      this.cssText = cssText;
+    },
   }
 }
 </script>
@@ -78,9 +123,9 @@ export default {
 <template>
 <!-- 管理员控制台布局 永久性头部,可伸缩侧边栏-->
 
-<div class="lay-con">
+<div class="lay-con" :style="cssText">
 <!--  头部横条 -->
-  <div class="lay-header" :style="headerHeight" >
+  <div class="lay-header"  >
     <div class="lay-logo">
       <slot name="logo">
         <h1>{{logoTitle}}</h1>
@@ -108,13 +153,36 @@ export default {
     </div>
   </div>
 <!--  内容部分-->
-  <div class="lay-box" :style="boxStyle">
-    <div class="lay-sideBar" :style="sideBarStyle">
+  <div class="lay-box" >
+    <div :class="`lay-sideBar ${!isShowSideBar?'lay-sideBar-hide':''}`" >
+<!--      侧边按钮 -->
       <div class="lay-sideBar-control" @click="switchHandle">
-        {{isShowSideBar?'&Colone;':'&ngt;'}}
+        <svg-icon :icon-class="isShowSideBar?'prev':'next'"/>
+      </div>
+<!--          侧边栏,带标题,icon,下拉菜单-->
+      <div v-for="(item,i) in sideMenus"
+           :key="'sideBar-'+i"
+           :class="`bar-menu-item ${item.isShow?'bar-menu-item-show':''}`"
+      >
+        <div class="menu-title">
+          <span class="icon"> <svg-icon :icon-class="item.icon"/> </span>
+          <span class="text">{{ item.title }}</span>
+          <span class="icon option" @click="switchSideBarMenuHandle(item)">
+            <svg-icon :icon-class="item.isShow?'arrow-up':'arrow-down'"/>
+          </span>
+        </div>
+        <div class="sub-menu-box">
+          <div v-for="sub in item.child"
+               :key="sub.key"
+               :class="`menu-item ${activeKey===sub.key?'menu-items-show':''}`"
+          >
+            <span>{{sub.title}}</span>
+          </div>
+        </div>
+
       </div>
     </div>
-    <div class="lay-content" :style="conStyle">
+    <div class="lay-content" >
       <slot></slot>
     </div>
   </div>
@@ -122,17 +190,37 @@ export default {
 </template>
 
 <style scoped>
+
 .lay-con {
+  --headerHeight: v-bind(headerHeight);
+  --sideBarWidth: v-bind(sideBarWidth);
+  --sideBarHeight: v-bind(sideBarHeight);
+  --baseSideBarWidth: v-bind(sideBarWidth);
+  --bg-color: v-bind(bgColor);
+  --sideBarBgColor: v-bind(sideBarColor);
+  --header-color: v-bind(headerBgColor);
+  --text-color: v-bind(textColor);
+  --main-text-color: v-bind(mainTextColor);
+  --text-color-hover: v-bind(textColorHover);
+  --main-text-color-hover: v-bind(mainTextColorHover);
+
+  --btn-color: v-bind(btnColor);
+  --btn-color-hover: v-bind(btnColorHover);
+  --btn-text-color: v-bind(btnTextColor);
+  --btn-text-color-hover: v-bind(btnTextColorHover);
+
   width: 100vw;
   height: 100vh;
   overflow: hidden;
-  background-color: #fff;
+  background-color: var(--sideBarBgColor);
   position: relative;
+
 }
 .lay-header{
-  background-color: #59aee3;
+  background-color: var(--header-color);
   display: flex;
   width: 100%;
+  height: var(--headerHeight);
   flex-direction: row;
 }
 .lay-header > *{
@@ -157,10 +245,12 @@ export default {
   padding: 5px 15px;
 }
 .lay-menus .menus .menu:hover{
-  color: #086fb6;
+  color: var(--text-color-hover);
 }
+
 .lay-box {
   width: 100%;
+  height:calc(100% - var(--headerHeight));
   display: flex;
 }
 .lay-box > *{
@@ -169,9 +259,10 @@ export default {
   position: relative;
 }
 .lay-sideBar{
-
+  width: var(--sideBarWidth);
 }
 .lay-content{
+  width: calc(100% - var(--sideBarWidth));
   overflow: hidden;
   background-color: #d5d5d5;
 }
@@ -188,11 +279,117 @@ export default {
   display: flex;
   justify-content: center;
   align-items: center;
-  background-color: #fff;
+  background-color: var(--sideBarBgColor);
 }
 .lay-sideBar-control:hover{
   border-color: #f0ad4e;
   background-color: #f0ad4e;
   color: #fff;
 }
+
+.bar-menu-item{
+  width: 100%;
+  height: auto;
+  position: relative;
+  margin-top: 5px;
+}
+
+.bar-menu-item .menu-title{
+  display: flex;
+  width: 100%;
+  height: var(--sideBarHeight);
+  align-items: center;
+  box-sizing: border-box;
+  padding-left: 5px;
+  padding-right: 5px;
+  cursor: default;
+  overflow: hidden;
+}
+.bar-menu-item .menu-title:hover{
+  color: var(--btn-text-color-hover);
+}
+.bar-menu-item .menu-title .icon{
+  width: var(--sideBarHeight);
+  height: var(--sideBarHeight);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: var(--text-color);
+  flex-shrink: 0;
+}
+.bar-menu-item .menu-title .icon *{
+  color: inherit;
+}
+.bar-menu-item .menu-title .option{
+  cursor: pointer;
+  color: var(--text-color);
+}
+.bar-menu-item .menu-title .option:hover{
+  color: var(--btn-text-color-hover);
+}
+.bar-menu-item .menu-title .text{
+  width: calc(100% - var(--sideBarHeight) - var(--sideBarHeight));
+  display: flex;
+  align-items: center;
+}
+.bar-menu-item .sub-menu-box{
+  width: 100%;
+  height: 0;
+  overflow: hidden;
+  transition: height .7s;
+}
+.bar-menu-item .sub-menu-box .menu-item{
+  width: 100%;
+  height: calc(var(--sideBarHeight) - 5px);
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+  padding-left: calc(var(--sideBarHeight) + 5px);
+  cursor: pointer;
+}
+.bar-menu-item .sub-menu-box .menu-item:hover{
+  color: var(--btn-text-color-hover);
+  background-color: var(--btn-color-hover);
+}
+.bar-menu-item-show{
+  height: auto;
+}
+
+.bar-menu-item-show .sub-menu-box{
+  height: auto;
+}
+
+
+.lay-sideBar-hide .lay-sideBar{
+  padding-top: 50px;
+}
+.lay-sideBar-hide .bar-menu-item{
+  box-sizing: border-box;
+  margin: 10px 0;
+  border-top: 1px solid var(--sideBarBgColor);
+}
+.lay-sideBar-hide .bar-menu-item .menu-title {
+  padding-left: 0;
+  padding-right: 0;
+}
+
+.lay-sideBar-hide .bar-menu-item .sub-menu-box{
+  position: absolute;
+  display: none;
+  top: 0;
+  left: 100%;
+  height: auto;
+  width: calc(var(--baseSideBarWidth) - var(--sideBarWidth));
+  padding: 10px 0;
+  box-shadow: 1px 1px 3px darkgray;
+  z-index: 9999;
+  background-color: var(--sideBarBgColor);
+}
+.lay-sideBar-hide .bar-menu-item:hover{
+  border-top: 1px solid var(--bg-color);
+}
+.lay-sideBar-hide .bar-menu-item:hover .sub-menu-box{
+  display: block;
+}
+
 </style>

+ 5 - 3
map/adminSideBar.js

@@ -1,7 +1,7 @@
-const adminMenus = [
+export const adminMenus = [
   {
     title: '首页展示管理',
-    icon: 'index',
+    icon: 'index-setting',
     child: [
       {
         key: 'carousel',
@@ -23,7 +23,9 @@ const adminMenus = [
         title: '新闻中心管理',
         path: '/manger/index/news'
       },
-    ],
+    ]
+  },
+  {
     title: '产品管理',
     icon: 'product',
     child: [

+ 3 - 1
pages/manger/index.vue

@@ -2,6 +2,7 @@
 
 
 import AdminLayout from "~/components/layout/adminLayout.vue";
+import {adminMenus} from "~/map/adminSideBar";
 
 export default {
   name: "mangerIndex",
@@ -15,7 +16,7 @@ export default {
           key: 'toIndex'
         }
       ],
-
+      sidebarMenus: adminMenus
 
     }
   }
@@ -27,6 +28,7 @@ export default {
 <admin-layout
   :logoTitle="'深圳合方圆站点管理'"
   :header-menus="headerMenus"
+  :sidebar-menus="sidebarMenus"
 >
   test
   <div class="abc">