Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)

一、版本说明(若没有以下中间件,先安装喔)


1.1、具体代码开源到github中,欢迎star 

Node.js      10.13.0

NPM            6.10.3

Vue              2.5.2

vue-router      3.0.1

element-ui      2.11.1

element-theme-chalk     2.11.1        # `npm install element-theme-chalk --save-dev`

webpack-theme-color-replacer    1.2.17        # `npm install webpack-theme-color-replacer --save-dev`

 

二、【原理】利用html的data-属性,动态修改该属性值,达到修改主题的效果,运用Sass+Vuex


2.1、【ElementUI主题修改】原理:通过官网下载几个主题到本地,然后修改主题名(注意与本地文件名一致),然后动态将页面样式通过link标签引入

【下载了三个主题,分别命名为default、green、orange】,放在static目录下

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第1张图片

【封装定义包含ElementUI组件名的数组文件themeArray.js】

//主题文件数组
const themeArray = [
    "Pagination",
    "Dialog",
    "Autocomplete",
    "Dropdown",
    "dropdown-menu",
    "dropdown-item",
    "Menu",
    "Submenu",
    "menu-item",
    "menu-item-group",
    "Input",
    "input-number",
    "Radio",
    "radio-group",
    "radio-button",
    "Checkbox",
    "checkbox-group",
    "Switch",
    "Select",
    "Option",
    "option-group",
    "Button",
    "button-group",
    "Table",
    "table-column",
    "date-picker",
    "time-select",
    "time-picker",
    "Popover",
    "Tooltip",
    "Breadcrumb",
    "breadcrumb-item",
    "Form",
    "form-item",
    "Tabs",
    "tab-pane",
    "Tag",
    "Tree",
    "Alert",
    "Slider",
    "Icon",
    "Row",
    "Col",
    "Upload",
    "Progress",
    "Spinner",
    "Badge",
    "Card",
    "Rate",
    "Steps",
    "Step",
    "Carousel",
    "Scrollbar",
    "carousel-item",
    "Collapse",
    "collapse-item",
    "Cascader",
    "color-picker",
    "Loading",
    "message-box",
    "Message"
  ]


export default themeArray

【封装改变主题的changeTheme.js文件,根据主题名,手动添加link标签到Dom元素中】

具体store中的定义参考下面步骤Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第2张图片

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第3张图片

 

2.2、【自定义样式修改】需要设置主组件的data属性,在入口文件APP.vue中,写上属性"data-theme",初始值存储在vuex的store中(通过改变data-theme的属性值,改变自定义样式的值,如菜单、顶部导航栏、部分文字颜色等)

【当前data-theme的值有:'default-theme'、'green-theme'、'orange-theme'】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第4张图片

 

2.3、【Vuex存储"data-theme"属性值】存储在store对应的文件中,主要变量值:主题属性名"nowThemeInfo",修改变量的函数"setThemeInfo",比如nowThemeInfo属性值从"default-theme"变成"green-theme"(即通过修改nowThemeInfo属性值,控制App.vue组件的data-theme属性值)

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第5张图片

 

2.4、【自定义样式文件】首先新建一个theme.scss文件,里面存放三种主题颜色值,通过定义变量,如$default-theme默认主题名,和自定义修改的函数,如base-color文本hover时的效果,其中结合sass提供Sass Maps的语句、定义变量、获取Map的值、循环Map生成类等,即遍历对应主题下的样式,参考此处

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第6张图片

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第7张图片

 

2.5、【引入到需要的组件中】在需要样式修改的组件中,对应样式处,引入指定map函数即可

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第8张图片

 

2.6、【重点:修改主题的组件】此处是通过单选框进行修改(changeRadio函数),注意computed属性中,引入store的"nowThemeInfo"属性,就不用在data()中return,其中参考mapGetters辅助函数

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第9张图片


传值给上述函数中,参数必须与本地文件夹名字相同!!定义属性themeArr:包含所有主题的数组;属性nowTheme:当前主题值

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第10张图片

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第11张图片


【methods属性中的初始化initRadio函数】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第12张图片


【控制台打印如下】


【methods属性中的改变颜色的changeRadio函数】选择对应的单选框之后,修改主题颜色

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第13张图片


【store中调用修改自定义主题和修改UI组件的函数】Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第14张图片

 

三、出现问题啦

3.1、【当打包时npm run build】报一下错误 (node:7852) UnhandledPromiseRejectionWarning: CssSyntaxError:xxxx.Unknown word

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第15张图片

 

3.2、【解决方法】注释build目录下,webpack.prod.conf.js文件中的以下代码

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第16张图片


【因为,需要判断是测试环境还是生产(打包之后)的环境】

所以先安装 `cross-env`

npm install cross-env --save-dev

然后重新配置package.json文件

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第17张图片

 

 

3.3、【又遇到问题啦】生产环境下,切换主题时,报错`Uncaught RangeError: Maximum call stack size exceeded`  

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第18张图片

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第19张图片

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第20张图片


【是的,修改removeChildNode函数】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第21张图片


【下面查看生产环境下的效果】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第22张图片

 

3.4、【又㕛遇到新问题啦】哈哈哈,就是换肤成功,但ELementUI组件主题刷新就失效,所以需要获取当前主题属性值(存储在localStorage),再设置当前的主题样式(调用changeTheme函数)

【因为刷新,每次会先加载main.js文件,所以引入初始化主题函数initThemeColor】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第23张图片


【文件themeColorClient.js,中的函数initThemeColor如下】getStore函数封装过

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第24张图片


【changeTheme函数中,每次修改时,存储当前主题值到localStorage中】setStore函数封装过

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第25张图片


【setStore、getStore函数如下】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第26张图片

 

3.5、【又㕛叒遇到问题啦】其他组件作为当前页时,换肤没有任何问题;但是!!首页换肤,会出现只有首页子组件,菜单和顶部导航栏都不在啦,嘤嘤嘤,哭死我了,当然找错啦,后来隐隐约约感觉是Breadcrumb 面包屑组件的问题,因为除了首页,其他前面都是有父组件的名字的,确实是面包屑组件的问题哎!!

【首页换肤效果如下】


【查找原因哈】面包屑的原理,通过获取this.$route.matched的值,进行对面包屑的渲染,所以赋值问题,这里应该将浅拷贝换成深拷贝(浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第27张图片

【对比】即首页,只有子组件的名字,没有父组件的名字

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第28张图片

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第29张图片


【控制台打印如下】

 

3.6、【项目标题根据组件名变化】创建配置文件,在main.js入口文件中,结合全局守卫,动态修改网页标题

【配置文件】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第30张图片


【main.js入口文件】

Vue+ElementUI 切换ElementUI主题+自定义颜色的修改(指定几种颜色的换肤)_第31张图片

 

四、效果展示


 

 

总结:

1、实现指定颜色的主题,结合ElementUI官网,下载自己需要的几个主题包

2、根据对应的主题,自定义的修改根据主题变动的组件,如菜单、顶部导航栏、部分文字颜色等

3、自定义的样式,是结合sass提供Sass Maps的语句、定义变量、获取Map的值、循环Map生成类等,即遍历对应主题下的样式

4、需要修改的主题名,存储在Vuex中;然后自定义样式则根据主题名的变化,修改App.vue组件的data属性值;而ElementUI组件的主题修改,根据主题名的变化,动态引入link标签

5、具体代码开源到github中,欢迎star

6、写给自己的随笔,有问题欢迎指出ψ(*`ー´)ψ

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(前端)