能否通过Vite插件在Vue中从JS获取Style块内的SCSS变量?
可以实现,以下是具体方案
核心思路
通过开发Vite插件,利用Vite的代码转换钩子拦截Vue单文件组件,提取<style lang="scss">块中的变量,将其转换为JS对象后注入组件的脚本部分,最终让组件能通过自定义方法访问这些变量。
实现步骤与代码示例
1. 安装依赖
需要用到PostCSS解析SCSS语法,若要获取变量引用后的最终计算值,可额外安装Sass:
npm install postcss postcss-scss --save-dev # 如需处理变量引用,补充安装sass npm install sass --save-dev
2. 编写Vite插件
创建plugins/vite-plugin-extract-scss-vars.js文件,实现核心逻辑:
import postcss from 'postcss'; import scssSyntax from 'postcss-scss'; // 如需计算变量最终值,引入sass // import sass from 'sass'; export default function vitePluginExtractScssVars() { return { name: 'vite-plugin-extract-scss-vars', async transform(code, id) { // 仅处理Vue单文件组件 if (!id.endsWith('.vue')) return code; // 匹配<style lang="scss">块(兼容带scoped的情况) const scssStyleMatch = code.match(/<style lang="scss"(?: scoped)?>(.*?)<\/style>/s); if (!scssStyleMatch) return code; const scssContent = scssStyleMatch[1]; const scssVars = {}; // 方式1:用PostCSS提取原始变量定义(不处理变量引用) await postcss([ { postcssPlugin: 'extract-scss-vars', Declaration(decl) { // 识别SCSS变量(以$开头的声明) if (decl.variable) { const varName = decl.prop.slice(1); scssVars[varName] = decl.value.trim(); } } } ]).process(scssContent, { syntax: scssSyntax }); // 方式2:用Sass编译获取计算后的变量值(处理变量引用,如$bar: $foo) /* sass.compileString(` ${scssContent} @function collect-vars() { $map: (); @each $var in variables($global) { $map: map-merge($map, ($var: $#{$var})); } @return $map; } @debug collect-vars(); `, { functions: { 'variables($scope)': (scope) => { const vars = scope.vars[scope.getValue()]; return new sass.types.Map(vars.size); } }, onWarning(warning) { if (warning.message.startsWith('DEBUG:')) { const parsedVars = JSON.parse(warning.message.replace('DEBUG: ', '')); Object.assign(scssVars, parsedVars); } } }); */ // 将变量转换为JS对象字符串 const varsStr = JSON.stringify(scssVars); // 注入getScssVariables方法到<script setup> const injectCode = `\nconst __scssVars__ = ${varsStr};\nfunction getScssVariables() { return __scssVars__; }\n`; if (code.includes('<script setup>')) { // 已有<script setup>,在开头注入代码 code = code.replace('<script setup>', `<script setup>${injectCode}`); } else { // 没有<script setup>,添加新的脚本块 code = `<script setup>${injectCode}</script>\n${code}`; } return code; } }; }
3. 在Vite配置中引入插件
修改vite.config.js:
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import extractScssVars from './plugins/vite-plugin-extract-scss-vars'; export default defineConfig({ plugins: [vue(), extractScssVars()] });
4. 在Vue组件中使用
现在可以直接按示例调用方法:
<script setup> const variables = getScssVariables(); console.log(variables); // { foo: "30px", bar: "400ms" } </script> <template> <div :style="{ width: variables.foo, transition: variables.bar }">示例内容</div> </template> <style lang="scss"> $foo: 30px; $bar: 400ms; </style>
注意事项
- 若SCSS变量存在嵌套引用(如
$bar: $foo),PostCSS仅能提取原始定义,需使用Sass编译方式获取最终计算值。 - 插件自动兼容带
scoped的
相关产品推荐
相关产品推荐

