侧边栏添加logo

image.png
也可以控制显示和隐藏
image.png

image.png

3-1 修改Settings

添加logo切换按钮

image.png
src/layout/components/Settings/index.vue

  1. <template>
  2. <div class="drawer-container">
  3. <div class="drawer-item">
  4. <span>主题色</span>
  5. <theme-picker />
  6. </div>
  7. <div class="drawer-item">
  8. <span>Open Tags-View</span>
  9. <el-switch v-model="tagsView" class="drawer-switch" />
  10. </div>
  11. <!-- 侧边栏logo -->
  12. <div class="drawer-item">
  13. <span>Sidebar Logo</span>
  14. <el-switch v-model="showSidebarLogo" class="drawer-switch" />
  15. </div>
  16. </div>
  17. </template>
  18. <script lang="ts">
  19. import { defineComponent, computed } from 'vue'
  20. import ThemePicker from '@/components/ThemePicker/index.vue'
  21. import { useStore } from '@/store'
  22. export default defineComponent({
  23. name: 'Settings',
  24. components: {
  25. ThemePicker
  26. },
  27. setup() {
  28. const store = useStore()
  29. const tagsView = computed({
  30. get() {
  31. return store.state.settings.tagsView
  32. },
  33. set(val) {
  34. store.dispatch('settings/changeSetting', {
  35. key: 'tagsView',
  36. value: val
  37. })
  38. }
  39. })
  40. const showSidebarLogo = computed({
  41. get() {
  42. return store.state.settings.sidebarLogo
  43. },
  44. set(val) {
  45. store.dispatch('settings/changeSetting', {
  46. key: 'sidebarLogo',
  47. value: val
  48. })
  49. }
  50. })
  51. return {
  52. tagsView,
  53. showSidebarLogo
  54. }
  55. }
  56. })
  57. </script>
  58. <style lang="scss" scoped>
  59. .drawer-container {
  60. padding: 24px;
  61. font-size: 14px;
  62. line-height: 1.5;
  63. word-wrap: break-word;
  64. .drawer-item {
  65. display: flex;
  66. justify-content: space-between;
  67. padding: 12px 0;
  68. font-size: 16px;
  69. color: rgba(0, 0, 0, .65);
  70. }
  71. }
  72. </style>

3-2 store中添加状态

image.png
src/store/modules/settings.ts

  1. import { MutationTree, ActionTree } from 'vuex'
  2. import variables from '@/styles/variables.scss'
  3. import { IRootState } from '@/store'
  4. export interface ISettingsState {
  5. theme: string;
  6. tagsView: boolean;
  7. originalStyle: string;
  8. sidebarLogo: boolean;
  9. }
  10. // 定义state
  11. const state: ISettingsState = {
  12. theme: variables.theme,
  13. tagsView: true,
  14. originalStyle: '',
  15. sidebarLogo: true
  16. }
  17. // 动态key的情况下 根据不同的key 约束对应value
  18. // http://www.voidcn.com/article/p-wtmkdcie-byz.html
  19. type ValueOf<T> = T[keyof T];
  20. interface ISettings { // 约束payload类型
  21. key: keyof ISettingsState; // 约束为ISettingsState中key
  22. value: ValueOf<ISettingsState>; // 约束为ISettingsState中value的类型
  23. }
  24. // 定义mutations
  25. const mutations: MutationTree<ISettingsState> = {
  26. CHANGE_SETTING(state, { key, value }: ISettings) {
  27. if (key in state) {
  28. (state[key] as ValueOf<ISettingsState>) = value
  29. }
  30. }
  31. }
  32. const actions: ActionTree<ISettingsState, IRootState> = {
  33. changeSetting({ commit }, data) {
  34. commit('CHANGE_SETTING', data)
  35. }
  36. }
  37. export default {
  38. namespaced: true,
  39. state,
  40. mutations,
  41. actions
  42. }

3-3 创建logo组件

src/layout/components/Sidebar/Logo.vue

  1. <template>
  2. <div class="sidebar-logo-container" :class="{collapse: collapse}">
  3. <transition name="sidebarLogoFade">
  4. <!-- sidebar收起状态下 -->
  5. <router-link
  6. v-if="collapse"
  7. key="collapse"
  8. to="/"
  9. class="sidebar-logo-link"
  10. >
  11. <img
  12. v-if="logo"
  13. :src="logo"
  14. class="sidebar-logo"
  15. alt="VueElementAdmin"
  16. >
  17. <h1
  18. v-else
  19. class="sidebar-title"
  20. >{{ title }}</h1>
  21. </router-link>
  22. <router-link
  23. v-else
  24. key="expand"
  25. to="/"
  26. class="sidebar-logo-link"
  27. >
  28. <img
  29. v-if="logo"
  30. :src="logo"
  31. class="sidebar-logo"
  32. alt="VueElementAdmin"
  33. >
  34. <h1 class="sidebar-title">{{ title }}</h1>
  35. </router-link>
  36. </transition>
  37. </div>
  38. </template>
  39. <script lang="ts">
  40. import { defineComponent } from 'vue'
  41. export default defineComponent({
  42. name: 'Logo',
  43. props: {
  44. collapse: {
  45. type: Boolean,
  46. required: true
  47. }
  48. },
  49. setup() {
  50. return {
  51. title: 'Vue Element Admin',
  52. logo: require('@/assets/logo.png')
  53. // logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
  54. }
  55. }
  56. })
  57. </script>
  58. <style lang="scss" scoped>
  59. .sidebar-logo-container {
  60. width: 100%;
  61. height: 50px;
  62. line-height: 50px;
  63. text-align: center;
  64. background: #2b2f3a;
  65. overflow: hidden;
  66. .sidebar-logo-link {
  67. display: block;
  68. width: 100%;
  69. height: 100%;
  70. .sidebar-logo {
  71. width: 32px;
  72. height: 32px;
  73. vertical-align: middle;
  74. margin-right: 12px;
  75. }
  76. .sidebar-title {
  77. display: inline-block;
  78. color: #fff;
  79. margin: 0;
  80. font-weight: 600;
  81. line-height: 50px;
  82. font-size: 14px;
  83. font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
  84. vertical-align: middle;
  85. }
  86. }
  87. &.collapse {
  88. .sidebar-logo {
  89. margin-right: 0;
  90. }
  91. }
  92. }
  93. .sidebarLogoFade-enter-active {
  94. transition: opacity 1.5s;
  95. }
  96. .sidebarLogoFade-enter-from,
  97. .sidebarLogoFade-leave-to {
  98. opacity: 0;
  99. }
  100. </style>

3-4 sidebar里添加logo

image.png

  1. <template>
  2. <div>
  3. <logo v-if="showLogo" :collapse="isCollapse" />
  4. <el-menu
  5. class="sidebar-container-menu"
  6. mode="vertical"
  7. :default-active="activeMenu"
  8. :background-color="scssVariables.menuBg"
  9. :text-color="scssVariables.menuText"
  10. :active-text-color="themeColor"
  11. :collapse="isCollapse"
  12. :collapse-transition="true"
  13. >
  14. <sidebar-item
  15. v-for="route in menuRoutes"
  16. :key="route.path"
  17. :item="route"
  18. :base-path="route.path"
  19. />
  20. </el-menu>
  21. </div>
  22. </template>
  23. <script lang="ts">
  24. import { defineComponent, computed } from 'vue'
  25. import { useRoute } from 'vue-router'
  26. import variables from '@/styles/variables.scss'
  27. import { routes } from '@/router'
  28. import SidebarItem from './SidebarItem.vue'
  29. import { useStore } from '@/store'
  30. import Logo from './Logo.vue'
  31. export default defineComponent({
  32. name: 'Sidebar',
  33. components: {
  34. Logo,
  35. SidebarItem
  36. },
  37. setup() {
  38. const route = useRoute()
  39. const store = useStore()
  40. // 根据路由路径 对应 当前激活的菜单
  41. const activeMenu = computed(() => {
  42. const { path, meta } = route
  43. // 可根据meta.activeMenu指定 当前路由激活时 让哪个菜单高亮选中
  44. if (meta.activeMenu) {
  45. return meta.activeMenu
  46. }
  47. return path
  48. })
  49. // scss变量
  50. const scssVariables = computed(() => variables)
  51. // 展开收起状态 稍后放store 当前是展开就让它收起
  52. const isCollapse = computed(() => !store.getters.sidebar.opened)
  53. // 渲染路由
  54. const menuRoutes = computed(() => routes)
  55. // 获取主题色
  56. const themeColor = computed(() => store.getters.themeColor)
  57. // 是否显示logo
  58. const showLogo = computed(() => store.state.settings.sidebarLogo)
  59. return {
  60. // ...toRefs(variables), // 不有toRefs原因 缺点variables里面变量属性来源不明确
  61. scssVariables,
  62. isCollapse,
  63. activeMenu,
  64. menuRoutes,
  65. themeColor,
  66. showLogo
  67. }
  68. }
  69. })
  70. </script>

本节参考源码

https://gitee.com/brolly/vue3-element-admin/commit/3d782444f64ffcaa061f832771d4dcf7700eeb4d