vue两种换肤原理解析

假设读者已经熟悉sass,bootstrap4,vue,es6等,不然不知道我在说什么,换肤功能很常见,但哪一种方式才是最佳实践呢?下面主要分析两种常见换肤原理

第一种

传统方式,在body加一个样式(如:.theme-red)来控制换肤,典型例子:AdminLTE

components/_tabs.scss style.scss theme/_theme-default.scss theme/_theme-red.scss
// tab组件
@mixin tabTheme($color) {
    .test {
        color: $color;
    }
}
@import “components/tabs”;

@import “theme/theme-default”;
@import “theme/theme-red”;
$primary: #1890ff;
body {
    @include tabTheme($primary);
}
$primary: #f00;
.theme-red {
    @include tabTheme($primary);
}

要创建一种主题也很简单,照着上面的theme-red就行,我这里主要运用了@mixin和@include。可以简化,使用gulp来建(参考element-theme

vue的话主题可以不打到style.css,比如单独的theme-red.css,在需要的页面在引入

优点:自定义性强,可以只控制某个组件

缺点:style.css会比较大,theme是固定的几个

第二种

动态插入<style>标签,假设我们的vue项目引用了style.css(好比上面的style.scss只加入了theme-default主题)

sass里有一个方法:export{},类似ES6的export,这样我们就可以在js里拿到_variables.scss里的变量

1
2
3
4
5
// _variables.scss
$primary: #1890ff;
:export {
themePrimary: $primary;
}

这个值可以存到$store.state.settings.themePrimary

然后在组件里的watch监听这个值有没有被改变(颜色选择器点击的时候触发改变为红色#f00),这时候有两个值:val(#f00)和oldVal(#1890ff)

改变的话,我们再去下载style.css,用正则把oldVal(#1890ff)替换为val(#f00),得到新的样式

最后创建一个style标签,把上面修改过的新样式放入style标签,然后追加到document.head,从而实现主题覆盖

优点:无需准备多套主题,可以自由动态换肤

缺点:自定义不够,只支持基础颜色的切换

参考

Author: kyxiao
Link: https://kyxiao.github.io/2019/08/15/vue两种换肤原理解析/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.