vue3 + Element-plus 开发后台管理系统(25)

132 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情

后台项目前端综合解决方案之通用功能开发

element-plus 新主题的立即生效

到目前为止,我们已经完成了 element-plus 的主题变更,但是当前的主题变更还有一个问题,那就是在页面刷新后,主题就会失效

出现这个问题的原因其实非常简单就是因为没有写入新的 style

那么我们只需要在应用加载后立即写入 style 即可

那么写入的时机,我们可以放到 app.vue

<script setup>
import { useStore } from 'vuex'
import { generateNewStyle, writeNewStyle } from '@/utils/theme'

const store = useStore()
generateNewStyle(store.getters.mainColor).then(newStyleText => {
  writeNewStyle(newStyleText)
})
</script>

自定义主题变更

自定义主题变更相对来说比较简单,因为自己的代码是可控的

目前在我们的项目中,需要进行自定义主题变更的为 menu 菜单的背景色

而目前指定 menu 菜单背景色的位置在 layout/components/sidebar/SidebarMenu.veu

  <el-menu
    :default-active="activeMenu"
    :collapse="!$store.getters.sidebarOpened"
    :background-color="$store.getters.cssVar.menuBg"
    :text-color="$store.getters.cssVar.menuText"
    :active-text-color="$store.getters.cssVar.menuActiveText"
    :unique-opened="true"
    router
  >

此处的背景色是通过 getters 进行指定的,该 cssVargetters 为:

  cssVar: state => variables

所以我们想要修改自定义主题,只需要修改这一部分即可

根据当前保存的 mainColor 覆盖原有的默认色值

import variables from '@/styles/variables.scss'
import { MAIN_COLOR } from '@/constant'
import { getItem } from '@/utils/storage'
import { generateColors } from '@/utils/theme'

const getters = {
  cssVar: state => {
    return {
      ...variables,
      ...generateColors(getItem(MAIN_COLOR))
    }
  },
}
export default getters

但是这样做完,还存在两个问题

1、menu 背景颜色没有变化

这个问题的原因在于我们的 sidebar 的背景色未被替换,所以我们可以在 layout/index 中设置 sidebarbackgoundColor

<sidebar
  id="guide-sidebar"
  class="sidebar-container"
  :style="{ backgroundColor: $store.getters.cssVar.menuBg }"
/>

2、主题色替换之后需要刷新页面才可以响应

这是因为 getters 中没有监听到依赖值的响应变化,所以我们希望修改依赖值

store/modules/theme

import variables from '@/styles/variables.scss'
export default {
  namespaced: true,
  state: () => ({
    variables
  }),
  mutations: {
    /**
     * 设置主题色
     */
    setMainColor(state, newColor) {
      state.variables.menuBg = newColor
    }
  }
}

getters

const getters = {
  cssVar: state => {
    return {
      ...state.theme.variables,
      ...generateColors(getItem(MAIN_COLOR))
    }
  },
}
export default getters

自定义主题方案总结

对于自定义主题而言,和新的原理其实就是修改 scss 变量来进行实现主题色变化

明确好了原理之后,对后续的实现步骤就需要具体情况具体分析了

1、对于 element-plus 而言,它是不可控的,那么对于这种最简单直白的方案就是直接闹到他编译后的 css 进行色值的替换,利用 style 内部样式表优先级高于外部样式表的特性,进行主题替换

2、对于自定义的主题而言,因为这些我们自己的代码,它是完全可控的,所以我们实现起来就简单的多了,只需要修改对应的 scss 变量即可