Vue.js: Class 与 Style 绑定
最后更新:2026-10-20
:class 和 :style 是 Vue 最常用的两个绑定——让你能根据数据动态切换 CSS 类名和内联样式。本质上是 v-bind 的两个特殊语法,因为它们用得太多所以做了"语法糖"。
掌握 5 种写法就够覆盖 95% 的场景:对象语法、数组语法、三元、计算属性、字符串拼接。
1. 你将学到
:class对象语法:根据条件切换单个/多个 class:class数组语法:同时应用多个 class- 数组 + 对象混合:复杂的类名组合
:style对象语法:动态内联样式:style数组语法:合并多个样式对象- CSS 变量绑定(Vue 3 推荐)
2. 一个订单状态标签的样式难题
(1) 痛点:5 种状态,5 个 if 判断
Alice 需要在后台中用不同颜色显示 5 种订单状态:
HTML
<!-- ❌ 翻车版:5 个 v-if 加 class -->
<span v-if="status === 'pending'" class="badge yellow">Pending</span>
<span v-else-if="status === 'paid'" class="badge green">Paid</span>
<span v-else-if="status === 'shipped'" class="badge blue">Shipped</span>
<span v-else-if="status === 'delivered'" class="badge gray">Delivered</span>
<span v-else class="badge red">Cancelled</span>
产品经理 Charlie:
"Alice,这太丑了。下个月要加 3 个状态怎么办?你不能一直复制粘贴。我们需要一种干净的动态方案。"
(2) Vue :class 解法:1 行搞定 5 状态
(3) 收益
- HTML 减少:5 行 if-else → 1 行 :class
- 可维护:加新状态只需改 computed,模板不动
- 可读:状态类映射集中在一处,逻辑清晰
3. :class 5 种写法
(1) 字符串语法
(2) 对象语法(最常用)
(3) 数组语法
(4) 与静态 class 共存
(5) 组件上的 class
▶ 示例:5 种 :class 写法
▶ 试一试输出:
TEXT
1. 字符串 实际 class="badge"
2. 对象 实际 class="active"(hasError 为 false,error 不生效)
3. 数组 实际 class="active error"
4. 数组+对象 实际 class="active"(canEdit 为 true,无 disabled)
5. 计算属性 实际 class="active"
4. :style 5 种写法
(1) 对象语法
(2) CSS 属性名转换
Vue 自动把 JS 命名转为 CSS 命名:
(3) 数组语法(合并多个对象)
(4) 自动加前缀
Vue 3 自动给 CSS 属性加浏览器前缀(用浏览器引擎判断):
JS
// 写:
{ transform: 'rotate(45deg)' }
// Vue 自动加:
{
-webkit-transform: 'rotate(45deg)',
transform: 'rotate(45deg)'
}
(5) CSS 变量(Vue 3 推荐)
▶ 示例:5 种 :style 写法
▶ 试一试输出:
TEXT
1. 基础对象 红色文字、16px 字号
2. 多个属性 #42b883 绿底 + 20px 内边距
3. 数组合并 白字 + 绿底(themeStyles 覆盖 baseStyles)
4. CSS 变量 外观不变,只在元素上写入 --theme-color: #35495e
5. 计算属性 白字 + 深蓝底(#35495e)+ 20px 内边距
5. 完整示例:动态订单状态
▶ 示例:订单状态徽章(5 状态切换)
▶ 试一试输出:
TEXT
黄色圆角徽章显示 Pending(初始 status = 'pending')
点 paid → 变绿显示 Paid;点 shipped → 变蓝显示 Shipped
点 delivered → 变灰显示 Delivered;点 cancelled → 变红显示 Cancelled
(1) 📊 5 个常见错误
| 错误 | 现象 | 解决 |
|---|---|---|
| 字符串 class 不响应 | class 写死不切换 | 用 :class 绑定 |
| 数组 class 拼错 | 多个 class 重名覆盖 | 用对象语法 |
| style 单位遗漏 | 数字 16 当成 16px 失效 | 写 '16px' 字符串 |
| CSS 属性名错 | font-size 应为 fontSize |
用驼峰或引号 |
| :class 冲突 | 静态 + 动态重名 | Vue 自动合并,OK |
(2) 📊 5 个性能对比
| 写法 | 编译产物 | 性能 | 适用 |
|---|---|---|---|
| 字符串 | 直接字符串拼接 | ⭐⭐⭐⭐⭐ | 简单 |
| 对象 | 静态分析 | ⭐⭐⭐⭐ | 中等 |
| 数组 | 字符串拼接 | ⭐⭐⭐⭐ | 多 class |
| 数组+对象 | 混合处理 | ⭐⭐⭐ | 复杂 |
| 计算属性 | 缓存值 | ⭐⭐⭐⭐⭐ | 复杂逻辑 |
(3) 📊 class vs style 5 大区别
| 维度 | class | style |
|---|---|---|
| 推荐度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| CSS 复用 | 容易(class 名复用) | 难(style 散落) |
| 性能 | 更高(浏览器优化) | 略低 |
| 优先级 | 取决于选择器 | 内联(最高) |
| 主题切换 | 容易(换 class) | 容易(换 CSS 变量) |
❓ 常见问题
Q class 和 style 绑定可以共存吗?
A 可以。静态
class="x" + 动态 :class="{active: y}" 会自动合并(最终 class="x active" 或 "x")。Q 为什么 style 要写成对象,不能直接写 CSS 字符串?
A 可以。
<div style="color: red"> 是 HTML 原生写法,<div :style="'color: red'"> 也是字符串写法。但用对象 :style="{ color: 'red' }" 能动态绑定变量。推荐对象。Q CSS 变量怎么用?
A 在 :style 中用
{'--my-var': value},CSS 中用 var(--my-var)。Vue 3 推荐用 CSS 变量做主题切换,比直接绑定 style 更高效(只需更新 1 个变量,DOM 不重排)。Q 组件怎么接收外部 class?
A 单根组件自动继承
class 属性(Vue 3 默认行为)。多根组件用 $attrs.class 显式绑定到某个元素。Q 数组语法的 class 顺序?
A 按数组顺序拼接,但顺序不影响 CSS 优先级(优先级由 CSS 选择器特异性决定)。
Q :class 和 v-if 一起用?
A 可以。
<div v-if="show" :class="{ active: isActive }"> 当 show=false 时整个不渲染,isActive 也不生效。Q 动态切换主题怎么做?
A 推荐 CSS 变量。
:style="{ '--primary': theme.primary }",所有元素 color: var(--primary)。切换主题只改 1 个变量,比切换 100 个 class 高效。📖 小节
:class和:style是 v-bind 的语法糖,用得最多所以简化- :class 5 种写法:字符串、对象、数组、数组+对象、计算属性
- :style 5 种写法:对象、数组、数组+对象、CSS 变量、计算属性
- 静态 class 和动态 :class 自动合并
- Vue 3 自动加 CSS 浏览器前缀
- CSS 变量是 Vue 3 推荐的主题切换方案(比 style 切换高效)
- 性能:对象/计算属性 > 数组 > 字符串
📝 作业
-
基础题(难度⭐) 用 :class 对象语法实现 3 种按钮状态:
- primary:蓝底白字
- success:绿底白字
- danger:红底白字
数据:
const variant = ref('primary') -
进阶题(难度⭐⭐) 实现一个订单列表,每行根据订单状态显示不同颜色徽章:
- 5 种状态(pending/paid/shipped/delivered/cancelled)
- 用计算属性返回 class 对象
- :style 添加状态对应的 icon 颜色
-
挑战题(难度⭐⭐⭐) 实现一个完整的主题切换系统:
- 3 套主题(light/dark/high-contrast)
- 用 CSS 变量绑定主题色(primary/secondary/background/text)
- :class 切换主题类名
- localStorage 记住用户选择
- 切换主题不刷新页面(响应式自动更新)