Vue项目使用CSS变量实现主题化
主题化管理经常能在网站上看到,一般的思路都是将主题相关的CSS样式独立出来,在用户选择主题的时候加载相应的CSS样式文件。现在大部分浏览器都能很好的兼容CSS变量,主题化样式更容易管理了。最近,使用CSS变量在Vue项目中做了一个主题化实践,下面来看看整个过程。
可行性测试
为了检验方法的可行性,在public文件夹下新建一个themes文件夹,并在themes文件夹新建一个default.css文件:
:root {
--color: red;
}
在public文件夹的index.html文件中引入外部样式theme.css,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>vue-skin-peeler-demo</title>
<!-- 引入themes文件夹下的default.css -->
<link rel="stylesheet" type="text/css" href="src/themes/default.css" rel="external nofollow">
</head>
<body>
<noscript>
<strong>We're sorry but vue-skin-peeler-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
然后,在Home.vue中使用CSS变量:
<template>
<div class="home">
<div :class="$style.demo">变红色</div>
</div>
</template>
<script>
export default {
name: 'home'
}
</script>
<style module lang="scss">
.demo {
color: var(--color);
}
</style>
然后,运行项目并在浏览器中打开页面,页面显示效果正常。
注意:@vue/cli使用link标签引入css样式可能报错“We're sorry but vue-skin-peeler-demo doesn't work properly without JavaScript enabled. Please enable it to continue.”。这是因为@vue/cli将src目录下的文件都通过webpack打包所引起,所以,静态文件资源要放在public(如果是@vue/cli 2.x版本放在static)文件夹下。
实现主题切换
这里主题切换的思路是替换link标签的href属性,因此,需要写一个替换函数,在src目录下新建themes.js文件,代码如下:
// themes.js
const createLink = (() => {
let $link = null
return () => {
if ($link) {
return $link
}
$link = document.createElement('link')
$link.rel = 'stylesheet'
$link.type = 'text/css'
document.querySelector('head').appendChild($link)
return $link
}
})()
/**
* 主题切换函数
* @param {string} theme - 主题名称, 默认default
* @return {string} 主题名称
*/
const toggleTheme = (theme = 'default') => {
const $link = createLink()
$link.href = `./themes/${theme}.css`
return theme
}
export default toggleTheme
然后,在themes文件下创建default.css和dark.css两个主题文件。创建CSS变量,实现主题化。CSS变量实现主题切换请参考另一篇文章初次接触css变量
兼容性
IE浏览器以及一些旧版浏览器不支持CSS变量,因此,需要使用css-vars-ponyfill,是一个ponyfill,可在旧版和现代浏览器中为CSS自定义属性(也称为“ CSS变量”)提供客户端支持。由于要开启watch监听,所以还有安装MutationObserver.js。
安装:
npm install css-vars-ponyfill mutationobserver-shim --save
然后,在themes.js文件中引入并使用:
// themes.js
import 'mutationobserver-shim'
import cssVars from 'css-vars-ponyfill'
cssVars({
watch: true
})
const createLink = (() => {
let $link = null
return () => {
if ($link) {
return $link
}
$link = document.createElement('link')
$link.rel = 'stylesheet'
$link.type = 'text/css'
document.querySelector('head').appendChild($link)
return $link
}
})()
/**
* 主题切换函数
* @param {string} theme - 主题名称, 默认default
* @return {string} 主题名称
*/
const toggleTheme = (theme = 'default') => {
const $link = createLink()
$link.href = `./themes/${theme}.css`
return theme
}
export default toggleTheme
开启watch后,在IE 11浏览器点击切换主题开关不起作用。因此,每次切换主题时都重新执行cssVars(),还是无法切换主题,原因是开启watch后重新执行cssVars()是无效的。最后,只能先关闭watch再重新开启。成功切换主题的themes.js代码如下:
// themes.js
import 'mutationobserver-shim'
import cssVars from 'css-vars-ponyfill'
const createLink = (() => {
let $link = null
return () => {
if ($link) {
return $link
}
$link = document.createElement('link')
$link.rel = 'stylesheet'
$link.type = 'text/css'
document.querySelector('head').appendChild($link)
return $link
}
})()
/**
* 主题切换函数
* @param {string} theme - 主题名称, 默认default
* @return {string} 主题名称
*/
const toggleTheme = (theme = 'default') => {
const $link = createLink()
$link.href = `./themes/${theme}.css`
cssVars({
watch: false
})
setTimeout(function () {
cssVars({
watch: true
})
}, 0)
return theme
}
export default toggleTheme
查看所有代码,请移步Github项目地址。
记住主题
实现记住主题这个功能,一是可以向服务器保存主题,一是使用本地存储主题。为了方便,这里主要使用本地存储主题的方式,即使用localStorage存储主题。具体实现请移步Github项目地址。
Vue项目使用CSS变量实现主题化的更多相关文章
- <转载> VUE项目中CSS管理
vue的scoped 在vue项目中,当 .vue文件中 <style> 标签有 *scoped 属性时,它的 CSS 只作用于当前组件中的元素,很好的实现了样式私有化的目的. 使用sco ...
- 关于使用css变量实现主题的切换效果
现在要实现网页主题的切换成本较小的一种方案就是使用css的变量来实现 HTML 在HTML的body标签上先定义一个id元素属性 <body id="sm-theme"> ...
- vue项目的环境变量
关于项目中环境变量的总结 背景 项目环境一般分为开发环境,测试环境,线上环境 因为每个环境的接口域名.webpack 配置都是不同的,所以在打包构建时,我们需要区分这些环境,这时就用到了环境变量 在工 ...
- 解决vue项目中使用ivew定制主题报 .bezierEasingMixin();错误
背景:在使用view-design(iview)定制主体时(覆盖变量方式)出现less错误 完整错误如下 解决方法: 在vue.config.js中添加 less-loader:5.0.x modul ...
- vue项目中使用组件化开发
最近在使用vue-cli结合webpack打包工具开发一个后台管理系统,使用vue难免需要运用组件化思想,而这也正是vue的一大特点. 在之前做的vue项目中,稍微有一点组件化的思想,可能是对组件化不 ...
- 初次接触CSS变量
本文的目的主要是展示CSS变量是如何工作的.随着Web应用程序变得越来越大,CSS变得越来越大,越来越多,而且很多时候都很乱,在良好的上下文中使用CSS变量,为您提供重用和轻松更改重复出现的CSS属性 ...
- python 全栈开发,Day58(bootstrap组件,bootstrap JavaScript 插件,后台模板,图表插件,jQuery插件库,Animate.css,swiper,运行vue项目)
一.bootstrap组件 无数可复用的组件,包括字体图标.下拉菜单.导航.警告框.弹出框等更多功能. 组件和插件的区别? 插件:一个功能,比如js文件 组件:html css js 组件包含插件 面 ...
- vue项目中postcss-pxtorem的使用及webpack中的配置 css中单位px和em,rem的区别
移动手机版要求我们在制作嵌入h5的时候去适配不同的手机.适配有多重模式,有flex.百分比等.字体大小的控制也有px.百分比.rem等单位,webpack中 px转rem. vue项目中postcss ...
- vue-cli构建的vue项目打包后css引入的背景图路径不对的问题
使用vue-cli构建vue项目后,再打包遇到一个css引入的背景图片路径的问题,就是css代码中背景图片是根据相对路径来写的,如下图: 当使用npm run dev命令本地访问的时候,背景图片是正常 ...
随机推荐
- 【Labview入门】工具的使用
labview版本:Labview2015 在你使用labview时你可能已经发现,在鼠标移动到连线上时,鼠标会自动的变化,其实这是你选择了自动识别的工具,然后鼠标会根据你所指示的东西自动切换工具类型 ...
- selenium-模块概述(1)
Selenium是一个用于Web应用程序自动化测试工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样. 1.目录结构如下: D:\soft\python36\Lib\site-pa ...
- ASP.NET Core 3.0 一个 jwt 的轻量角色/用户、单个API控制的授权认证库
目录 说明 一.定义角色.API.用户 二.添加自定义事件 三.注入授权服务和中间件 三.如何设置API的授权 四.添加登录颁发 Token 五.部分说明 六.验证 说明 ASP.NET Core 3 ...
- Java描述设计模式(16):代理模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 在电商高速发展的今天,快递的数量十分庞大,甚至出现了快递代理行业,简单的说就是快递的主人没有时间收快递,会指定一个 ...
- 解析 Microsoft.Extensions.DependencyInjection 2.x 版本实现
项目使用了 Microsoft.Extensions.DependencyInjection 2.x 版本,遇到第2次请求时非常高的内存占用情况,于是作了调查,本文对 3.0 版本仍然适用. 先说结论 ...
- javascript单线程,异步与执行机制
js的单线程模型与游览器的进程/线程息息相关,在了解js单线程与异步的时候,建议先看看这篇文章 为什么是单线程 由于js是可操作dom的,如果js是多线程,在多线程的交互下,处于界面中的dom节点就可 ...
- markdown语法(转)
markdown语法 1.标题代码 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题 2.引用代码 >你好 >> 您好 ...
- .NET webAPI中集成swagger
最近做的项目使用winform三层+webapi,对于webAPI路由文档管理一直觉得单独做一些管理比较麻烦,并且测试的时候项目内的代码测试运行起来也比较麻烦,所以在网上开始检索相关办法,发现热度比较 ...
- Kong05-Kong 的健康检查和监控
您可以让 Kong 代理的 API 使用 ring-balancer , 通过添加包含一个或多个目标实体的upstream 实体来配置,每个目标指向不同的IP地址(或主机名)和端口.ring-bala ...
- [爬虫]用python的requests模块爬取糗事百科段子
虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Humans”,说明使用更 ...