配置菜单
菜单使用element-plus(menu)因为在layout的index中定义了整体的菜单栏navbar和主内容的显示区域,这里在layout中的components下定义一个Sidebar/index组件作为侧边栏
新建Sidebar/index组件,然后再style目录下的variable.module.scss文件中定义导航页面需要的颜色:
1 2 3 4 5 6 7 8 9 10 11 12 13 //菜单导航颜色 $menutext: #bfcbd9; //导航激活颜色 $menuActiveText: #409eff; //菜单背景色 $menuBg: #304156; //vite scss 支持这种导出 :export { menuText: $menutext; menuActiveText: $menuActiveText; menuBg: $menuBg; }
3.然后再Sidebar/index.vue中导入import varabiles from “@/style/varabiles.module.scss” 如果ts显示找不到该目录就在style目录下声明一个variable.module.scss.d.ts声明这些变量给ts检查,ts会扫描这个文件内容为:
1 2 3 4 5 6 7 interface IVaraibles{ menuText:string menuActiveText:string menuBg:string } enport const variables:IVaraibles export default variables//导出该变量
然后就可以使用导入的变量里面的样式对菜单进行设置了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <template> <el-menu class="sidebar-container-menu" :default-active="defaultActive" :background-color="varabiles.menuBg" :text-color="varabiles.menuText" :active-text-color="varabiles.menuActiveText" @open="handleOpen" @close="handleClose" :collapse="false" > <el-menu-item index="/dashboard" disabled> <span>Navigator Three</span> </el-menu-item> </el-menu> </template> <script setup lang="ts"> import varabiles from "@/style/variable.module.scss" // import { useRouter } from 'vue-router' const route = useRoute() const defaultActive = computed(() => { //..... return route.path }) const handleOpen = (key: string, keyPath: string[]) => { console.log(key, keyPath) } const handleClose = (key: string, keyPath: string[]) => { console.log(key, keyPath) } </script>
但是如果我们自定义的sider显示的区域加上:collapse=”false”(收起侧边栏)这个后会导致和我们自己的设置的宽度冲突所以在父组件中对class=”sidebar-container-menu”的样式进行样式穿透操作:
1 2 3 4 5 6 7 .sider { //控制子组件的样式使用样式穿透,.el-menu--collapse为缩放的时候给<sidebar></sidebar>设置的样式会缩小宽度,只有当不是缩放样式的时候(el-menu--collapse)显示正常的自定义样式如果不使用样式穿透,父组件控制子组件的样式只会影响到第一个根元素,其余的会失效 :deep(.sidebar-container-menu:not(.el-menu--collapse)) { @apply w-[var(--sidebar-width)]; } }
pinia:npm install pinia-plugin-persistedstate(持久化) 我们在navbar区域中添加一个按钮来控制侧边栏的收缩然后再pinia中维护一个响应式变量isCollapse, 在src\layout\components\Hamburger下新建一个index.vue放在layout下的总布局页面index.vue中的
显示:
然后这是hamburger下的index.vue的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <template> <div class="hamburger-container" @click="handleClick"> <SvgIcon icon-name="mynaui:arrow-left-right-solid" :custom-class="`hamburger ${isCollapse ? 'rotated' : ''}`" ></SvgIcon> </div> </template> <script setup lang="ts"> import { useAppStore } from "@/stores/app" const store = useAppStore()//使用pinia const { isCollapse } = storeToRefs(store) const handleClick = () => { store.toggleCollapse() } </script> <style scoped lang="scss"> .hamburger-container { @apply h-[50px] w-[50px] flex items-center justify-center cursor-pointer px-[10px] hover:(bg-black/5); } .hamburger { @apply w-30px h-30px text-align-center transition-transform duration-300; &.rotated {//点击旋转图标 transform: rotate(180deg); } } </style>
然后这个是store下新建的app.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 export const useAppStore = defineStore( "app", () => { //侧边栏折叠状态 const isCollapse = ref(false) //切换折叠状态 const toggleCollapse = () => { isCollapse.value = !isCollapse.value } const a = ref(1) return {//必须要导出 isCollapse, toggleCollapse, a } }, { persist: { //持久化存储 storage: window.localStorage, key: "app-store", pick: ["a", "isCollapse"] } } )