在開發中會遇到如下需求:
- JS 中使用 SCSS 變數。如在 scss 中定義了一個顏色,el-menu 元件使用該顏色作為背景色,此時需要獲取 scss 變數,通過 background-color 屬性將該變數值傳遞給 el-menu 元件(當然你也可以在 JS 中重新定義一個變數儲存該顏色)。
- SCSS 中使用 JS 變數。如動態換膚功能,使用者選中某個顏色作為主題色,整個系統的主題色都切換為這個主題色。使用者選擇的這個顏色使用 JS 變數儲存,SCSS 中需要使用該 JS 變數儲存的顏色。類似的場景還有暗黑模式等。
本文提供解決上述問題的思路。
在 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;
上面建立的 config.module.scss 檔案中定義了一個變數:$titleColor。
如果咱們只是在其他 scss 檔案或 vue 檔案的 style 標籤中使用,只需要在對應檔案使用 @import 引入 config.module.scss 即可。但如果需要在 script 中的 JS/TS 中使用,還需要通過 export 將需要使用的變數匯出:
$titleColor: #FF0000;
:export {
titleColor: $titleColor;
}
這樣便將 $titleColor 的值通過變數名 titleColor 匯出給 JS/TS。
在 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>
在討論 SCSS 程式碼使用 JS 變數前,咱需要先聊聊 CSS Next 中的 CSS 變數。CSS 2、CSS 3 大部分哥們都耳熟能詳,CSS Next 也不是什麼新鮮事物了。其中 CSS Next 很厲害的一個能力就是 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'
此時在瀏覽器中可以看到背景色變成粉紅色。
在元件中也可以使用 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 變數了。
咱們用一個 demo 來說明 scss 中如何使用 js 變數:有三個按鈕和一個 div,點選三個按鈕會切換 div 的背景色和文字顏色。
首先實現頁面的基礎程式碼:
<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 變數。下面兩種方式都基於上面的基礎程式碼實現:
Vue 提供了 setProperty 的方式來改變 CSS 變數。
<template>
...
<div>
<div class="example" ref="exampleRef">Hello World</div>
</div>
</div>
</template>
import { ref } from 'vue'
const exampleRef = ref<HTMLDivElement | null>()
...
<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>
...
Vue3 中為 vue 檔案的 style 提供了 v-bind 函數,實現了將 JS/TS 變數繫結到 CSS 變數上。
const currentBgColor = ref('#333333')
const currentTextColor = ref('#FFFFFF')
const onBtnClick = (bgColor: string, textColor: string) => {
currentBgColor.value = bgColor
currentTextColor.value = textColor
}
.demo {
...
.example {
--textColor: v-bind(currentTextColor);
--bgColor: v-bind(currentBgColor);
...
color: var(--textColor);
background: var(--bgColor);
}
}
上面兩種方式根據自己的喜好使用。大家可以根據上面的思路嘗試實現主題切換、動態換膚等功能,在後面的實戰系列文章中咱在繼續討論這個話題。
感謝你閱讀本文,如果本文給了你一點點幫助或者啟發,還請三連支援一下,點贊、關注、收藏,作者會持續與大家分享更多幹貨