Skip to content

类与样式绑定 👌

通过 v-bind(缩写为 :)可以为元素动态绑定 classstyle,用以切换状态类、组合多套样式或在运行时计算样式值。

基本概念与对比

模板中使用 :class:style 绑定变量或表达式:

vue
<template>
  <div :class="{ active: isActive }" :style="styleObj">内容</div>
  <button :class="buttonClasses" :style="buttonStyle">提交</button>
  <p :class="[baseClass, isError ? 'error' : '', extraClass]">提示</p>
  <div :style="[baseStyle, themeStyle, hoverStyle]">卡片</div>
  <div :class="{ [dynamicClass]: isOn }" :style="{ [prop]: value }">
    动态键名
  </div>
  <div class="box" :style="{ '--box-color': color }">CSS 变量</div>
</template>

<script setup>
import { ref, computed } from "vue";

const isActive = ref(true);
const isError = ref(false);
const isOn = ref(true);
const dynamicClass = ref("highlight");
const prop = ref("width");
const value = ref("120px");
const color = ref("#42b883");

const styleObj = ref({ color: "#333", fontSize: "16px" });

const buttonClasses = computed(() => ({ primary: true, loading: false }));
const buttonStyle = computed(() => ({
  padding: "8px 12px",
  borderRadius: "6px",
}));

const baseClass = "message";
const extraClass = "rounded";

const baseStyle = { padding: "12px", borderRadius: "8px" };
const themeStyle = { backgroundColor: "#fff" };
const hoverStyle = { borderColor: "#42b883" };
</script>

<style scoped>
.box {
  background-color: var(--box-color);
}
</style>

何时用 class 与 style

  • class 适合可复用的规则(由 CSS 定义),能配合伪类、媒体查询与层叠。
  • style 适合少量、数据驱动的具体值(如宽高、定位、颜色)。

绑定类:对象语法

对象语法以「键为类名、值为布尔条件」决定是否应用类:

vue
<template>
  <div :class="{ active: isActive, disabled: isDisabled }">按钮</div>
</template>

<script setup>
import { ref } from "vue";
const isActive = ref(true);
const isDisabled = ref(false);
</script>
  • 条件为True应用类;为False移除类。
  • 可使用计算属性提升可读性与复用:
vue
<template>
  <div :class="classes">卡片</div>
</template>

<script setup>
import { ref, computed } from "vue";
const selected = ref(false);
const error = ref(false);
const classes = computed(() => ({
  selected: selected.value,
  error: error.value,
  "is-large": true,
}));
</script>

动态键名(计算属性名)

在对象语法中可用计算属性名动态生成类名:

vue
<div :class="{ [dynamicClass]: isOn }"></div>

其中 dynamicClass 为字符串,如 'highlight'

绑定类:数组语法

数组语法适合「组合多个类名」:

vue
<template>
  <div :class="[baseClass, isActive ? 'active' : '', extraClass]">条目</div>
</template>

<script setup>
import { ref } from "vue";
const baseClass = ref("item");
const extraClass = ref("rounded");
const isActive = ref(true);
</script>
  • 数组条目可为字符串、对象或计算结果;False 值会被忽略。
  • 对象条目与对象语法一致,可混合使用:
vue
<div
  :class="['btn', { primary: isPrimary, disabled: isDisabled }, stateClass]"
></div>

合并静态与动态类

静态 class 与动态 :class 会合并应用:

vue
<template>
  <button class="btn" :class="{ primary: isPrimary }">提交</button>
</template>

<script setup>
import { ref } from "vue";
const isPrimary = ref(true);
</script>

合并与覆盖

  • 静态与动态类名同时生效;冲突由选择器优先级与后声明覆盖决定。
  • 将「结构/语义类」放入静态 class,将「状态切换类」交给 :class 更清晰。

可读性与计算类建议

  • 将复杂条件抽到 computed 或方法中,避免模板三元嵌套。
  • 为状态命名语义化类名,如 is-activeis-erroris-loading
  • 在数组语法中,基础类置前,状态类置后,便于覆盖与阅读。
vue
<template>
  <div :class="classes">消息</div>
</template>

<script setup>
import { computed } from "vue";
const severity = "warning";
const unread = true;
const classes = computed(() => [
  "message",
  `message--${severity}`,
  { "message--unread": unread },
]);
</script>

绑定内联样式:对象语法

对象语法以「键为 CSS 属性名、值为属性值」绑定内联样式:

vue
<template>
  <div :style="styleObj">面板</div>
</template>

<script setup>
import { ref } from "vue";
const styleObj = ref({
  color: "#333",
  backgroundColor: "#fafafa",
  border: "1px solid #e5e5e5",
});
</script>

属性名既可用 camelCase(如 backgroundColor),也可用字符串的 kebab-case(如 'background-color')。

单位与数值

  • 大多数长度需带单位字符串,如 '16px''2rem'
  • 少数属性可用数字(浏览器自动处理),如 lineHeight: 1.5zIndex: 10
  • 推荐在 JS 对象中使用 camelCase,与变量书写更一致。

绑定内联样式:数组语法

数组语法可将多份样式对象合并应用,后者覆盖前者:

vue
<template>
  <div :style="[baseStyle, themeStyle, hoverStyle]">卡片</div>
</template>

<script setup>
const baseStyle = { padding: "12px", borderRadius: "8px" };
const themeStyle = { backgroundColor: "#fff" };
const hoverStyle = { borderColor: "#42b883" };
</script>

合并策略

  • 数组后面的样式对象覆盖前面的同名属性值。
  • 用「基础/主题/交互」分层组织样式对象,清晰可控。

进阶:动态键名与 CSS 变量

动态键名适合在运行时决定具体的样式属性:

vue
<template>
  <div :style="{ [prop]: value }">条形图</div>
</template>

<script setup>
const prop = "width";
const value = "120px";
</script>

结合 CSS 变量可轻松实现主题切换:

vue
<template>
  <div class="box" :style="{ '--box-color': color }">主题盒子</div>
  <button @click="toggleColor">切换颜色</button>
</template>

<script setup>
import { ref } from "vue";

const color = ref("#2bd425ff");

const toggleColor = () => {
  color.value = color.value === "#2bd425ff" ? "#ff6b6b" : "#2bd425ff";
};
</script>

<style scoped>
.box {
  background-color: var(--box-color);
}
</style>

CSS 变量优势

  • 天然支持层叠与继承,可在父级统一设置,在子组件中消费。
  • :style 协同,保持动态性同时让规则留在 CSS,便于维护。

常见误区与最佳实践

易错点与规避

  • :class 数组语法中传入布尔值不会转换成类名;请传字符串或对象。
  • 过度使用内联 :style 会降低样式复用与维护性;优先用 class 承载稳定规则。
  • 为同一元素绑定大量动态样式可能影响渲染性能;稳定样式放入 CSS,动态值才用 :style
  • 复杂条件请移入计算属性或方法,模板中保持表达式简洁。
  • 合理职责划分:class 管结构与语义,:style 管数据驱动的具体值。
  • 统一命名风格:状态类以 is-*,尺寸修饰以 --size-* 等约定统一。
  • 静态类提供基础骨架,动态类/样式只表达增量变化,便于覆盖与理解。

小结

  • :class 支持对象/数组语法,适合状态切换与多类组合;静态 class 与其合并。
  • :style 支持对象/数组语法,后者覆盖前者;属性名可用 camelCase'kebab-case'
  • 通过动态键名与 CSS 变量增强可配置性;谨慎使用内联样式,优先复用类。