侧边栏添加logo
也可以控制显示和隐藏
3-1 修改Settings
添加logo切换按钮
src/layout/components/Settings/index.vue
<template>
<div class="drawer-container">
<div class="drawer-item">
<span>主题色</span>
<theme-picker />
</div>
<div class="drawer-item">
<span>Open Tags-View</span>
<el-switch v-model="tagsView" class="drawer-switch" />
</div>
<!-- 侧边栏logo -->
<div class="drawer-item">
<span>Sidebar Logo</span>
<el-switch v-model="showSidebarLogo" class="drawer-switch" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
import ThemePicker from '@/components/ThemePicker/index.vue'
import { useStore } from '@/store'
export default defineComponent({
name: 'Settings',
components: {
ThemePicker
},
setup() {
const store = useStore()
const tagsView = computed({
get() {
return store.state.settings.tagsView
},
set(val) {
store.dispatch('settings/changeSetting', {
key: 'tagsView',
value: val
})
}
})
const showSidebarLogo = computed({
get() {
return store.state.settings.sidebarLogo
},
set(val) {
store.dispatch('settings/changeSetting', {
key: 'sidebarLogo',
value: val
})
}
})
return {
tagsView,
showSidebarLogo
}
}
})
</script>
<style lang="scss" scoped>
.drawer-container {
padding: 24px;
font-size: 14px;
line-height: 1.5;
word-wrap: break-word;
.drawer-item {
display: flex;
justify-content: space-between;
padding: 12px 0;
font-size: 16px;
color: rgba(0, 0, 0, .65);
}
}
</style>
3-2 store中添加状态
src/store/modules/settings.ts
import { MutationTree, ActionTree } from 'vuex'
import variables from '@/styles/variables.scss'
import { IRootState } from '@/store'
export interface ISettingsState {
theme: string;
tagsView: boolean;
originalStyle: string;
sidebarLogo: boolean;
}
// 定义state
const state: ISettingsState = {
theme: variables.theme,
tagsView: true,
originalStyle: '',
sidebarLogo: true
}
// 动态key的情况下 根据不同的key 约束对应value
// http://www.voidcn.com/article/p-wtmkdcie-byz.html
type ValueOf<T> = T[keyof T];
interface ISettings { // 约束payload类型
key: keyof ISettingsState; // 约束为ISettingsState中key
value: ValueOf<ISettingsState>; // 约束为ISettingsState中value的类型
}
// 定义mutations
const mutations: MutationTree<ISettingsState> = {
CHANGE_SETTING(state, { key, value }: ISettings) {
if (key in state) {
(state[key] as ValueOf<ISettingsState>) = value
}
}
}
const actions: ActionTree<ISettingsState, IRootState> = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
3-3 创建logo组件
src/layout/components/Sidebar/Logo.vue
<template>
<div class="sidebar-logo-container" :class="{collapse: collapse}">
<transition name="sidebarLogoFade">
<!-- sidebar收起状态下 -->
<router-link
v-if="collapse"
key="collapse"
to="/"
class="sidebar-logo-link"
>
<img
v-if="logo"
:src="logo"
class="sidebar-logo"
alt="VueElementAdmin"
>
<h1
v-else
class="sidebar-title"
>{{ title }}</h1>
</router-link>
<router-link
v-else
key="expand"
to="/"
class="sidebar-logo-link"
>
<img
v-if="logo"
:src="logo"
class="sidebar-logo"
alt="VueElementAdmin"
>
<h1 class="sidebar-title">{{ title }}</h1>
</router-link>
</transition>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'Logo',
props: {
collapse: {
type: Boolean,
required: true
}
},
setup() {
return {
title: 'Vue Element Admin',
logo: require('@/assets/logo.png')
// logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
}
}
})
</script>
<style lang="scss" scoped>
.sidebar-logo-container {
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
background: #2b2f3a;
overflow: hidden;
.sidebar-logo-link {
display: block;
width: 100%;
height: 100%;
.sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 12px;
}
.sidebar-title {
display: inline-block;
color: #fff;
margin: 0;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0;
}
}
}
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
.sidebarLogoFade-enter-from,
.sidebarLogoFade-leave-to {
opacity: 0;
}
</style>
3-4 sidebar里添加logo
<template>
<div>
<logo v-if="showLogo" :collapse="isCollapse" />
<el-menu
class="sidebar-container-menu"
mode="vertical"
:default-active="activeMenu"
:background-color="scssVariables.menuBg"
:text-color="scssVariables.menuText"
:active-text-color="themeColor"
:collapse="isCollapse"
:collapse-transition="true"
>
<sidebar-item
v-for="route in menuRoutes"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</el-menu>
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
import { useRoute } from 'vue-router'
import variables from '@/styles/variables.scss'
import { routes } from '@/router'
import SidebarItem from './SidebarItem.vue'
import { useStore } from '@/store'
import Logo from './Logo.vue'
export default defineComponent({
name: 'Sidebar',
components: {
Logo,
SidebarItem
},
setup() {
const route = useRoute()
const store = useStore()
// 根据路由路径 对应 当前激活的菜单
const activeMenu = computed(() => {
const { path, meta } = route
// 可根据meta.activeMenu指定 当前路由激活时 让哪个菜单高亮选中
if (meta.activeMenu) {
return meta.activeMenu
}
return path
})
// scss变量
const scssVariables = computed(() => variables)
// 展开收起状态 稍后放store 当前是展开就让它收起
const isCollapse = computed(() => !store.getters.sidebar.opened)
// 渲染路由
const menuRoutes = computed(() => routes)
// 获取主题色
const themeColor = computed(() => store.getters.themeColor)
// 是否显示logo
const showLogo = computed(() => store.state.settings.sidebarLogo)
return {
// ...toRefs(variables), // 不有toRefs原因 缺点variables里面变量属性来源不明确
scssVariables,
isCollapse,
activeMenu,
menuRoutes,
themeColor,
showLogo
}
}
})
</script>
本节参考源码
https://gitee.com/brolly/vue3-element-admin/commit/3d782444f64ffcaa061f832771d4dcf7700eeb4d