Web前端主题切换方案

前端主题切换计划
现在咋们经常能够看到一些网站会有相似暗黑形式/白-天形式的主题切换功效,功效也是十分炫酷,在平时的开拓场景中也有越发多这样的需要,这里大要枚举一些罕见的主题切换计划并剖析其利害,我们可依照需要综合剖析得出一套适用的计划嗯。
计划一、link标签消息引入
其做法即是提早准备好几套CSS主题样式文件,在必-要的时刻,建立link标签消息加载到head标签中,或者者是消息更改link标签的href属性嗯。
体现功效以下
网络乞求以下
利益
完变成了按需加载,提升了首屏加载时的功效
弱点和缺点
消息加载样式文件,如果文件过大网络情形欠安的情形下应该会有加载延迟,致使样式切换不流通
如果主题样式表内界说欠妥,会有优先级疑
各个主题样式是写死的,后续针对某一主题样式表修正或者者新增主题也食用题
计划二、提早引入一切主题样式,做类名切换
这类计划与第一种对比相似,为理处置重复加载样式文件疑提早将样式所有引入,在必-要切换主题的时刻将指定的根元素类名替换,十分于直-接做了样式笼罩,在该类名下的各个样式就统一地替换了嗯。其基本办法以下
/* day样式主题 */ body.day .box /* dark样式主题 */ body.dark .box .box
hello 选择样式 day dark
function change(theme)
体现功效以下
利益
没必-要重新加载样式文件,在样式切换时不会有卡顿
弱点和缺点
首屏加载时会逝世一些时刻加载样式资源
如果主题样式表内界说欠妥,也会有优先级疑
各个主题样式是写死的,后续针对某一主题样式表修正或者者新增主题也食用题
计划小结
通过以上两个计划,咋们能够看到关于样式的加载疑上的考量就相似于在纠结是做SPA单页运用仍然MPA多页运用事情事件一样嗯。两种一开始都误伤风雅,可是最主要的是要保证在后续的连续开拓迭代中怎样会更便利嗯。因而咋们还能够基于以上存在的疑和计划做进一步的增强嗯。
在做主题切换技术调研时,看到了网友的一条建议
因而下面的几个计划重如果针对变量来做样式切换
计划三、CSS变量+类名切换
灵感遵照Vue3
在Vue3有一位暗黑形式切换按钮,点击以后就会平滑地过渡,只管Vue3中也有一位v-bind特征能够完成消息样式绑定,但通过视察以后Vue并有无选取这个计划,针对Vue3的v-bind特征在接下去的计划中会细说嗯。
大要思绪跟计划2相似,依然是提早将样式文件载入,切换时将指定的根元素类名替换嗯。可是这里对应灵巧的是,默许在根功效域下界说好CSS变量,只要要在区别的主题下变更CSS变量对应的取值即可嗯。
顺便提一下,在Vue3还运用了color-scheme: dark;将体制的转动条设置为了黑色形式,使样式越发统一嗯。
html.dark
完成计划以下
/* 界说根功效域下的变量 */ :root /* 变更dark类名下变量的取值 */ .dark /* 变更pink类名下变量的取值 */ .pink .box
体现功效以下
利益
没必-要重新加载样式文件,在样式切换时不会有卡顿
在必-要切换主题的场所使用var()绑定变量即可,不存在优先级疑
新增或者修正主题便利灵巧,仅需新增或者修正CSS变量即可,在var()绑定样式变量的场所就会努力替换
弱点和缺点
IE兼容性(忽略不计)
首屏加载时会逝世一些时刻加载样式资源
计划四、Vue3新特征(v-bind)
只管这类办法存在界线性只能在Vue开拓中运用,可是为Vue事情事件开拓者做消息样式变更供应了又一位不错的计划嗯。
简易用法
// 这里可于是本始对-象值,也可于是ref()或者reactive()包裹的值,依照详细需要而定 const theme = hello p
Vue3中在style样式通过v-bind()绑定变量的理由一开始即是给元素绑定CSS变量,在绑定的数据更新时挪用
CSSStyleDeclaration.setProperty更新CSS变量值嗯。
完成思索
前面计划3基于CSS变量绑定样式是在:root上界说变量,然后在各个场所都能够获取到根元素上界说的变量嗯。现在的计划咋们必-要思考的疑是,如果是基于JS层面怎么样在各个组件上文雅地运用统一的样式变量吗?
咋们可以使用Vuex或者Pinia对全局样式变量做统一治理,如果不愿运用相似的插件也能够或者者自行封装一位hook,大要以下
// 界说暗黑主题变量 export default ;
// 界说白-天主题变量 export default ;
import from 'vue'; // 引入主题 import theme_day from './theme_day'; import theme_dark from './theme_dark'; // 界说在全局的样式变量 const theme = shallowRef(); export function useTheme() ; const setDarkTheme = () => ; return ; }
运用自己封装的主题hook
import from './useTheme.ts'; import MyButton from './components/MyButton.vue'; const = useTheme(); Hello .box
import from '../useTheme.ts'; const = useTheme(); const change1 = () => ; const change2 = () => ; dark day .my-btn
体现功效以下
一开始从这里能够看到,跟Vue的照应式理由一样,只要数据发生更改,Vue就会把绑定了变量的场所一切更新嗯。
利益
没必-要重新加载样式文件,在样式切换时不会有卡顿
在必-要切换主题的场所使用v-bind绑定变量即可,不存在优先级疑
新增或者修正主题便利灵巧,仅需新增或者修正JS变量即可,在v-bind()绑定样式变量的场所就会努力替换
弱点和缺点
IE兼容性(忽略不计)
首屏加载时会逝世一些时刻加载样式资源
这类办法只想如果在组件上绑定了消息样式的场所都市有对应的编译成哈希化的CSS变量,而不像计划3统一地就在:root上设置(未必在到达肯定量级以后的功效),也应该即是这样,Vue也并未采用此办法做全站的主题切换
计划五、SCSS + mixin + 类名切换
重如果运用SCSS的混淆+CSS类名切换,其理由重如果将运用到mixin混淆的场所编译为牢固的CSS以后,再通过类名切换去做样式的笼罩,完成计划以下
界说SCSS变量
/* 字体界说标-准 */ $font_samll:12Px; $font_medium_s:14Px; $font_medium:16Px; $font_large:18Px; /* 布景致标-准(主要) */ $background-color-theme: d43c33;//布景主题色默许(网易红) $background-color-theme1: 42b983;//布景主题色1(QQ绿) $background-color-theme2: 333;//布景主题色2(夜间形式) /* 布景致标-准(次要) */ $background-color-sub-theme: f5f5f5;//布景主题色默许(网易红) $background-color-sub-theme1: f5f5f5;//布景主题色1(QQ绿) $background-color-sub-theme2: 444;//布景主题色2(夜间形式) /* 字体色标-准(默许) */ $font-color-theme : 666;//字体主题色默许(网易) $font-color-theme1 : 666;//字体主题色1(QQ) $font-color-theme2 : ddd;//字体主题色2(夜间形式) /* 字体色标-准(激活) */ $font-active-color-theme : d43c33;//字体主题色默许(网易红) $font-active-color-theme1 : 42b983;//字体主题色1(QQ绿) $font-active-color-theme2 : ffcc33;//字体主题色2(夜间形式) /* 边框色 */ $border-color-theme : d43c33;//边框主题色默许(网易) $border-color-theme1 : 42b983;//边框主题色1(QQ) $border-color-theme2 : ffcc33;//边框主题色2(夜间形式) /* 字体图标色 */ $icon-color-theme : ffffff;//边框主题色默许(网易) $icon-color-theme1 : ffffff;//边框主题色1(QQ) $icon-color-theme2 : ffcc2f;//边框主题色2(夜间形式) $icon-theme : d43c33;//边框主题色默许(网易) $icon-theme1 : 42b983;//边框主题色1(QQ) $icon-theme2 : ffcc2f;//边框主题色2(夜间形式)
界说混淆mixin
@import "./variable.scss"; @mixin bg_color() [data-theme=theme2] & } @mixin bg_sub_color() [data-theme=theme2] & } @mixin font_color() [data-theme=theme2] & } @mixin font_active_color() [data-theme=theme2] & } @mixin icon_color() [data-theme=theme2] & } @mixin border_color() [data-theme=theme2] & }
左侧 中心 右侧 export default } } @import "../assets/css/variable"; @import "../assets/css/mixin"; .header
体现功效以下
能够觉察,运用mixin混淆在SCSS编译后一样也是将一切包罗的样式所有加载
这类计划最终获得的结局与计划2相似,不过在界说主题时由因而直-接操做的SCSS变量,会越发灵巧嗯。
利益
没必-要重新加载样式文件,在样式切换时不会有卡顿
在必-要切换主题的场所使用mixin混淆绑定变量即可,不存在优先级疑
新增或者修正主题便利灵巧,仅需新增或者修正SCSS变量即可,通过编译后会将一切主题所有编译进去
弱点和缺点
首屏加载时会逝世一些时刻加载样式资源
计划六、CSS变量+消息setProperty
此计划较于前几种会越发灵巧,可是视情形而定,这个计划适用于由用户依照色面板自行设定种种色主题,这类是主题色未必的情形,而前几种计划更适用于界说预设的几种主题嗯。
计划遵照vue-element-plus-admin
主要完成思绪以下
只要在全局中设置好预设的全局CSS变量样式,无需独自为每逐一位主题类名下重新设定CSS变量值,由于主题是由用户消息决定嗯。
:root
界说一位器械类办法,用于修正指定的CSS变量值,挪用的是
CSSStyleDeclaration.setProperty
export const setCssVar = (prop: string, val: any, dom = document.documentElement) =>
在样式发生更改时挪用此办法即可
setCssVar('--theme-color', color)
体现功效以下
vue-element-plus-admin主题切换源码
这里还用了vueuse的useCssVar可是功效和Vue3中运用v-bind绑定消息样式是差一点的,底层全是挪用的
CSSStyleDeclaration.setProperty这个api,这里就不多赘述vueuse中的用法嗯。
利益
没必-要重新加载样式文件,在样式切换时不会有卡顿
负-责 专心 钻研能够觉察其理由跟计划4使用Vue3的新特征v-bind是一样的,只可是此计划只在:root上消息变更CSS变量而Vue3中会将CSS变量绑定就任何依赖该变量的节点上嗯。
必-要切换主题的场所只用在:root上消息变更CSS变量值即可,不存在优先级疑
新增或者修正主题便利灵巧
弱点和缺点
IE兼容性(忽略不计)
首屏加载时会逝世一些时刻加载样式资源(对应前几种预设好的主题,这类办法的样式界说在首屏加载基本色够忽略不计)
计划总结
声明两种主题计划都支持一开始不代表肯定是最好计划,视详细情形而定嗯。
计划/主题样式
牢固预设主题样式
主题样式不牢固
计划一、link标签消息引入
√(文件过大,切换延时,不引荐)
×
计划二、提早引入一切主题样式,做类名切换

×
计划三、CSS变量+类名切换
√(引荐)
×
计划四、Vue3新特征(v-bind)
√(功效未必)
√(功效未必)
计划五、SCSS + mixin + 类名切换
√(引荐,最终出现功效与计划2相似,但界说和运用越发灵巧)
×
计划六、CSS变量+消息setProperty
√(更引荐计划3)
√(引荐)


除非特别注明,本站所有文字均为原创文章,作者:admin

No Comment

留言

电子邮件地址不会被公开。 必填项已用*标注

感谢你的留言。。。