右边设置面板添加 标签导航显示控制

效果
image.png
切换后
image.png

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

可以缓存到sesstion storage大家可以写下 sotre/index.ts里添加下 settings.tagsView

2-2 修改Settings组件添加切换按钮

element.ts中导入el-switch组件

image.png

修改settings组件

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. </div>
  12. </template>
  13. <script lang="ts">
  14. import { defineComponent, computed } from 'vue'
  15. import ThemePicker from '@/components/ThemePicker/index.vue'
  16. import { useStore } from '@/store'
  17. export default defineComponent({
  18. name: 'Settings',
  19. components: {
  20. ThemePicker
  21. },
  22. setup() {
  23. const store = useStore()
  24. const tagsView = computed({
  25. get() {
  26. // 获取store中tagsView状态
  27. return store.state.settings.tagsView
  28. },
  29. set(val) {
  30. // switch修改后 派发action同步store中tagsview值
  31. store.dispatch('settings/changeSetting', {
  32. key: 'tagsView',
  33. value: val
  34. })
  35. }
  36. })
  37. return {
  38. tagsView
  39. }
  40. }
  41. })
  42. </script>
  43. <style lang="scss" scoped>
  44. .drawer-container {
  45. padding: 24px;
  46. font-size: 14px;
  47. line-height: 1.5;
  48. word-wrap: break-word;
  49. .drawer-item {
  50. display: flex;
  51. justify-content: space-between;
  52. padding: 12px 0;
  53. font-size: 16px;
  54. color: rgba(0, 0, 0, .65);
  55. }
  56. }
  57. </style>

2-3 Layout中添加条件控制

image.png
src/layout/index.vue

  1. <template>
  2. <div class="app-wrapper">
  3. <div class="sidebar-container">
  4. <Sidebar />
  5. </div>
  6. <div class="main-container">
  7. <div class="header">
  8. <navbar @showSetting="openSetting" />
  9. <!-- 控制tagsview显示 -->
  10. <tags-view v-if="showTagsView" />
  11. </div>
  12. <!-- AppMain router-view -->
  13. <app-main />
  14. </div>
  15. <right-panel
  16. v-model="showSetting"
  17. title="样式风格设置"
  18. :size="SettingsPanelWidth"
  19. >
  20. <settings />
  21. </right-panel>
  22. </div>
  23. </template>
  24. <script lang="ts">
  25. import { defineComponent, ref, computed } from 'vue'
  26. import Sidebar from './components/Sidebar/index.vue'
  27. import AppMain from './components/AppMain.vue'
  28. import Navbar from './components/Navbar.vue'
  29. import TagsView from './components/TagsView/index.vue'
  30. import RightPanel from '@/components/RightPanel/index.vue'
  31. import Settings from './components/Settings/index.vue'
  32. import varibalse from '@/styles/variables.scss'
  33. import { useStore } from '@/store'
  34. export default defineComponent({
  35. components: {
  36. Sidebar,
  37. AppMain,
  38. Navbar,
  39. TagsView,
  40. RightPanel,
  41. Settings
  42. },
  43. setup() {
  44. const store = useStore()
  45. const showSetting = ref(false)
  46. const openSetting = () => {
  47. showSetting.value = true
  48. }
  49. // 是否显示tagsview
  50. const showTagsView = computed(() => store.state.settings.tagsView)
  51. return {
  52. showSetting,
  53. openSetting,
  54. showTagsView,
  55. SettingsPanelWidth: varibalse.settingPanelWidth
  56. }
  57. }
  58. })
  59. </script>
  60. <style lang="scss" scoped>
  61. .app-wrapper {
  62. display: flex;
  63. width: 100%;
  64. height: 100%;
  65. .main-container {
  66. flex: 1;
  67. display: flex;
  68. flex-direction: column;
  69. overflow: hidden;
  70. .app-main {
  71. /* 50= navbar 50 如果有tagsview + 34 */
  72. min-height: calc(100vh - 84px);
  73. }
  74. }
  75. }
  76. </style>

本节参考源码

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