Vue3 JS 与 SCSS 变量相互使用
在开发中会遇到如下需求:
- JS 中使用 SCSS 变量。如在 scss 中定义了一个颜色,el-menu 组件使用该颜色作为背景色,此时需要获取 scss 变量,通过 background-color 属性将该变量值传递给 el-menu 组件(当然你也可以在 JS 中重新定义一个变量存储该颜色)。
- SCSS 中使用 JS 变量。如动态换肤功能,用户选中某个颜色作为主题色,整个系统的主题色都切换为这个主题色。用户选择的这个颜色使用 JS 变量存储,SCSS 中需要使用该 JS 变量存储的颜色。类似的场景还有暗黑模式等。
本文提供解决上述问题的思路。
1 JS 使用 SCSS 变量
1.1 创建 SCSS 变量文件
在 src 目录下创建 scss 目录,该目录存储 scss 文件。这里需要注意,如果 JS 要使用 SCSS 文件中定义的变量,在 vue3 中,存储变量的 SCSS 文件名格式为 xxx.module.scss,
如 variables.module.scss。与 vue 2.x 不同,这里的 .module 不能省略,在 vue 2.x 不要求文件名使用 xxx.module.scss 的方式。
在 src/scss/ 目录下创建
config.module.scss 文件,该文件用于定义 scss 变量:
$titleColor: #FF0000;
1.2 导出 SCSS 变量
上面创建的 config.module.scss 文件中定义了一个变量:$titleColor。
如果咱们只是在其他 scss 文件或 vue 文件的 style 标签中使用,只需要在对应文件使用 @import 引入 config.module.scss 即可。但如果需要在 script 中的 JS/TS 中使用,还需要通过 export 将需要使用的变量导出:
$titleColor: #FF0000;
:export {
titleColor: $titleColor;
}
这样便将 $titleColor 的值通过变量名 titleColor 导出给 JS/TS。
1.3 使用 SCSS 变量
在 vue 文件的 script 中如果要使用上面的变量,先导入该 scss 文件:
import config from '@/scss/config.module.scss'
config 的值就是 scss 文件 :export 的对象。输出 config 对象:
console.log(config)
控制台输出:
{titleColor: '#FF0000'}
此时便可通过 config.titleColor 获取 scss 文件中 $titleColor 的值。
vue 代码如下:
<template>
<div>
<h1 :style="{color: color}">JS 获取 SCSS 变量值</h1>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import config from '@/scss/config.module.scss'
const color = ref(config.titleColor)
</script>
2 CSS 变量
在讨论 SCSS 代码使用 JS 变量前,咱需要先聊聊 CSS Next 中的 CSS 变量。CSS 2、CSS 3 大部分哥们都耳熟能详,CSS Next 也不是什么新鲜事物了。其中 CSS Next 很厉害的一个能力就是 CSS 变量。
2.1 全局 CSS 变量
咱可以在上面的 src/scss 目录下创建 test.css 文件来尝试使用 css 变量。
:root {
--bgColor: pink;
}
body {
background-color: var(--bgColor);
}
:root 中定义了全局 CSS 变量,CSS变量的命名约定以两个 - 开头,上面定义了一个全局 CSS 变量,变量名为 --bgColor。
使用变量时使用 CSS 的 var() 函数。
在 main.ts 中引入该文件:
import '@/scss/test.css'
此时在浏览器中可以看到背景色变成粉红色。
2.2 组件内 CSS 变量
在组件中也可以使用 CSS 变量。在对应的选择器中定义变量即可。
<template>
<div class="demo">
<div class="css-div">CSS 变量</div>
</div>
</template>
<script lang="ts" setup>
</script>
<style scoped lang="scss">
.demo {
--font-size: 30px;
.css-div {
--textColor: blue;
font-size: var(--font-size);
color: var(--textColor);
}
}
</style>
有了 CSS 变量的基础,接下来就可以讨论 scss 中如何使用 JS 变量了。
3 SCSS 使用 JS 变量
咱们用一个 demo 来说明 scss 中如何使用 js 变量:有三个按钮和一个 div,点击三个按钮会切换 div 的背景色和文字颜色。
3.1 基础代码
首先实现页面的基础代码:
<template>
<div class="demo">
<button v-for="(item, index) in btns"
:key="index"
@click="onBtnClick(item.bgColor, item.textColor)"
>{{ item.title }}</button>
<div>
<div class="example">Hello World</div>
</div>
</div>
</template>
<script lang="ts" setup>
const btns = [
{ title: '红色主题', bgColor: '#FF9191', textColor: '#FF0000' },
{ title: '蓝色主题', bgColor: '#B3C4FF', textColor: '#042BA9' },
{ title: '默认主题', bgColor: '#333333', textColor: '#FFFFFF' }
]
const onBtnClick = (bgColor: string, textColor: string) => {
console.log(bgColor, textColor)
}
</script>
<style scoped lang="scss">
.demo {
padding: 10px;
.example {
--textColor: #FFFFFF;
--bgColor: #333333;
display: inline-block;
margin-top: 20px;
font-size: 20px;
padding: 20px 50px;
color: var(--textColor);
background: var(--bgColor);
}
}
</style>
页面如下:
上面代码比较简单,btns 变量定义了三个按钮,通过 v-for 显示三个按钮。点击按钮的时候传递 bgColor 和 textColor 两个参数给点击事件 onBtnClick 函数。显示 Hello World 的 div,通过 --textColor 和 --bgColor 两个变量来控制背景色和文字颜色。
接下来便是实现点击不同按钮时,使用不同的文字颜色和背景色。
Vue3 中提供了两种方式来实现动态改变 css 变量。下面两种方式都基于上面的基础代码实现:
3.2 方式1:setProperty
Vue 提供了 setProperty 的方式来改变 CSS 变量。
- 为目标 div 添加 ref 属性:
<template>
...
<div>
<div class="example" ref="exampleRef">Hello World</div>
</div>
</div>
</template>
- 获取到该 div 的引用(ref):
import { ref } from 'vue'
const exampleRef = ref<HTMLDivElement | null>()
...
- 调用该引用 style 属性的 setProperty 方法:
<script lang="ts" setup>
...
const onBtnClick = (bgColor: string, textColor: string) => {
if (exampleRef.value) {
exampleRef.value?.style.setProperty('--textColor', textColor)
exampleRef.value?.style.setProperty('--bgColor', bgColor)
}
}
</script>
...
3.3 方式2:v-bind
Vue3 中为 vue 文件的 style 提供了 v-bind 函数,实现了将 JS/TS 变量绑定到 CSS 变量上。
- 在 TS 中定义两个变量存储点击事件时传递的两个参数:
const currentBgColor = ref('#333333')
const currentTextColor = ref('#FFFFFF')
- 点击事件中点参数赋值给上面两个变量:
const onBtnClick = (bgColor: string, textColor: string) => {
currentBgColor.value = bgColor
currentTextColor.value = textColor
}
- 在 style 中使用 v-bind 绑定上面两个 JS 变量:
.demo {
...
.example {
--textColor: v-bind(currentTextColor);
--bgColor: v-bind(currentBgColor);
...
color: var(--textColor);
background: var(--bgColor);
}
}
上面两种方式根据自己的喜好使用。大家可以根据上面的思路尝试实现主题切换、动态换肤等功能,在后面的实战系列文章中咱在继续讨论这个话题。
感谢你阅读本文,如果本文给了你一点点帮助或者启发,还请三连支持一下,点赞、关注、收藏,作者会持续与大家分享更多干货
Vue3 JS 与 SCSS 变量相互使用的更多相关文章
- 为什么 Vue3.js / Element+ 组件属性前面有的需要添加冒号,有的不需要?
背景 使用 Element+ Layout 布局: <el-row> <el-col :span="12"><div class="grid ...
- js学习之变量、作用域和内存问题
js学习之变量.作用域和内存问题 标签(空格分隔): javascript 变量 1.基本类型和引用类型: 基本类型值:Undefined, Null, Boolean, Number, String ...
- js对象私有变量公有变量问题
0 js对象私有变量公有变量问题5 小弟初学JS面向对象编程 现有一问题 请教各位大虾: Person=function (){ //私有变量定义 var name; vae age; var Ale ...
- js 函数和变量的提升
js 函数和变量的提升 1. 函数的作用域: js中 ,函数的作用域为函数,而不是大括号. var hei = 123;if(true){ hei = 456;}console.log(hei);// ...
- JS函数和变量
JS函数和变量 函数: 函数是由事件或者当它被调用时执行的可重复使用的代码块. 是一个独立的代码块,实现特定功能模块. 函数他不进行调用触发的话,不会自己主动执行. 像ATM机一样,不去取钱的话不会 ...
- 没做过编译器就是被人欺——从一道变态的i++题猜编译器的行为(表达式从左往右扫描,同一变量相互影响)
首先不要被人蒙了,如果是这样,根本编译不过: int i=1; int b=i+++++i; printf("%d %d\n", b ,i); Mingw报错:error: lva ...
- Js中执行变量中的命令语句,也就是所谓的宏替换(很实用的例子)
Js中执行变量中的命令语句,也就是所谓的宏替换(很实用的例子) 由其做动态编程时非常有用,必须符合js中的语法,用eval能够执行. var aaa="alert('这是变量中的语句')&q ...
- Javascript开发技巧(JS中的变量、运算符、分支结构、循环结构)
一.Js简介和入门 继续跟进JS开发的相关教程. <!-- [使用JS的三种方式] 1.HTML标签中内嵌JS(不提倡使用): 示例:<button onclick="javas ...
- 从零开始的JS生活(一)——JS简介、变量及基本结构
本K在经过三个静态站制作的狂风暴雨之后,终于开始了JavaScript的学习.作为一只从来没有正儿八经接受过计算机语言的小白,居然能够跟上浩哥的课程进度,我的内心都被我的才智震惊到了,果然本K是天生丽 ...
随机推荐
- kubernetes之DaemonSet以及滚动更新
1.什么是DaemonSet? 1.1DaemonSet是Pod控制器的又一种实现方式,用于在集群中的全部节点上同时运行一份指定的Pod资源副本,后续加入集群的节点也会自动创建一个相关的Pod对象,当 ...
- 人理解迭代,神则体会递归,从电影艺术到Python代码实现神的逆向思维模式
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_186 "从来如此,便对么?",鲁迅先生在<狂人日记>中借狂人之口在月光下发出的质疑与呐喊,是的,从 ...
- Blazor和Vue对比学习(进阶2.2.4):状态管理之持久化保存(2),Cookie/Session/jwt
注:本节涉及到前后端,这个系列的对比学习,还是专注在前端Vue和Blazor技术,所以就不撸码了,下面主要学习概念. 我们知道,Http是无状态协议,客户端请求服务端,认证一次后,如果再次请求,又要重 ...
- 3.26省选模拟+NOI-ONLINE
今日趣闻: 这三个人都是同机房的,卡最优解(大常数选手不参与)....以至于最优解第一页都是我们机房的(有图为证,共三人) $NOI\ online$ $T1$ 首先模拟一遍记录这个点当前单调栈前面位 ...
- 通过重新构建Kubernetes来实现更具弹性的容器编排系统
通过重新构建Kubernetes来实现更具弹性的容器编排系统 译自:rearchitecting-kubernetes-for-the-edge 摘要 近年来,kubernetes已经发展为容器编排的 ...
- Spring核心思想Ioc和Aop (面试)
Spring核心思想Ioc和Aop (面试) 注意: Ioc和Aop并不是Spring提出的,在Spring之前就已经存在,Spring只是在技术层面给这两个思想做了非常好的实现. 1 Ioc 1.1 ...
- C#基础_枚举
一.在学习枚举之前,首先来听听枚举的优点. 1.枚举能够使代码更加清晰,它允许使用描述性的名称表示整数值. 2.枚举使代码更易于维护,有助于确保给变量指定合法的.期望的值. 3.枚举使代码更易输入. ...
- E - Road Reduction
E - Road Reduction (atcoder.jp) 题意:一棵树n个点,m条路, di表示1-i的距离,问怎么选择边可以使得d2+...dn最短. 题解: 很明显,就是直接套最短路板子,判 ...
- 手撸Router,还要啥Router框架?react-router/vue-router躺一边去
有没有发现,在大家使用React/Vue的时候,总离不开一个小尾巴,到哪都得带着他,那就是react-router/vue-router,而基于它们的第三方框架又出现很多个性化约定和扩展,比如nuxt ...
- losf命令详解
一.概念:lsof全名list opened files,也就是列举系统中已经被打开的文件,进程打开的端口(TCP.UDP).linux环境中,任何事物都是文件,设备是文件,目录是文件,甚至socke ...