在 Vue 3 项目里,“CSS / Less 能不能接收 JS 变量?” 要分两层回答:


  1. 标准 CSS / Less 本身
    浏览器只认静态样式,不可能直接拿到运行时的 JS 数据
    Less 变量也只是在“编译阶段”生效,最终会被编译成纯静态 CSS。


  1. Vue 提供的“曲线救国”官方方案 —— v-bind()
    Vue 3.2+ 引入了真正的 “运行时 CSS 变量注入”,支持 <style scoped> 里直接写 v-bind()任何响应式数据都能用;Less/Sass/PostCSS 都能共存。


一、Vue 3 原生用法(推荐,零依赖)

vue

复制

<template>
  <h1>Hello</h1>
</template>

<script setup>
import { ref } from 'vue'
const color = ref('#ff6600')   // 响应式
const size = ref(32)
</script>

<style scoped lang="less">
h1 {
  /* 注意:v-bind() 里写 JS 表达式,字符串记得加引号 */
  color: v-bind(color);
  font-size: v-bind(size + 'px');
  /* Less 语法继续用 */
  &:hover { opacity: 0.8; }
}
</style>
  • 编译后 Vue 会把 v-bind(color) 转成 CSS 自定义属性
    color: var(--<hash>-color)
    并在运行时把 --<hash>-color 动态设成 #ff6600
    所以完全响应式color.value = '#00ff00' 立即生效。

  • Less 变量与 v-bind 可以混用

less

复制

@base: 1.5;
h1 { line-height: @base * v-bind(size / 16); }

二、旧浏览器 / 非 scoped 样式 也能用

v-bind() 写在 :root 或任意选择器里即可:

vue

复制

<style lang="less">
:root {
  --theme: v-bind(themeColor);   // 全局变量
}
</style>

三、与 Less “传参”误区澄清

  • Less 变量不能在运行时“再赋值”
    下面这种不行(编译阶段就定死了):

less

复制

// 错误示例
@color: v-bind(color);   // Less 编译器会报错
  • 正确姿势:在 Less 里用 v-bind() 代替需要运行时变化的部分,其余仍用 Less 变量、函数、嵌套。


四、实战小例子 —— 主题切换

vue

复制

<script setup>
import { ref } from 'vue'
const primary = ref('#409eff')
const radius = ref(4)
function toggle() {
  primary.value = primary.value === '#409eff' ? '#ff6600' : '#409eff'
}
</script>

<style scoped lang="less">
.btn {
  background: v-bind(primary);
  border-radius: v-bind(radius + 'px');
  transition: all .3s;
}
</style>

五、一句话总结

  • 浏览器层面 CSS 拿不到 JS;

  • Vue 3 的 v-bind() 帮你把“响应式数据”自动映射成 CSS 变量,Less/Sass 照常用

  • 想“传变量”给样式 → 用 v-bind() 就行,别的都是编译时,跑不到运行时。

更多推荐