Vue 3 样式绑定完全指南
本文档从零开始讲解 Vue 3 的样式绑定:如何用数据动态控制 class 和 style,以及单文件组件里的 scoped、深度选择器、在 CSS 里使用响应式数据 等,配有大量示例,适合新手系统学习。
一、为什么需要“样式绑定”?
1.1 静态 vs 动态
写死 class 或 style 很简单:
<p class="title">标题</p>
<p style="color: red;">红色文字</p>
但实际开发里,样式经常要跟着数据变,例如:
- 当前选中的 Tab 要高亮(加个
activeclass) - 主题切换(亮色/暗色,整页的 class 或 CSS 变量要变)
- 根据状态显示不同颜色(成功绿、失败红)
- 根据后端返回的数值动态设置宽度、颜色
在 Vue 里,用 :class 和 :style(即 v-bind:class / v-bind:style)把数据和样式绑在一起:数据变,样式自动变。
二、绑定 class(:class)
2.1 对象语法:按条件加 class
语法: :class="{ 类名: 条件 }"
对象的 键 是 class 名,值 是“是否加上这个 class”的条件(真则加,假则不加)。
<template>
<div>
<p :class="{ active: isActive, 'text-danger': hasError }">段落</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isActive = ref(true)
const hasError = ref(false)
</script>
<style scoped>
.active {
font-weight: bold;
}
.text-danger {
color: red;
}
</style>
isActive为 true → 有activeclass。hasError为 true → 有text-dangerclass。- 类名里有横线(如
text-danger)要加引号,否则会被当成减号。
多个条件、一个 class:
<p :class="{ active: isActive && isValid }">段落</p>
2.2 对象语法:直接绑定一个对象变量
不必把对象写在模板里,可以放在 script 里(或计算属性),更清晰:
<template>
<p :class="classObject">段落</p>
</template>
<script setup>
import { ref, computed } from 'vue'
const isActive = ref(true)
const hasError = ref(false)
const classObject = computed(() => ({
active: isActive.value,
'text-danger': hasError.value
}))
</script>
2.3 数组语法:多个 class 一起绑
语法: :class="[类名1, 类名2, ...]"
数组里可以是字符串(固定 class)、变量、或对象(按条件加)。最终会合并成一个 class 列表。
<template>
<div>
<p :class="[classA, classB]">段落</p>
<p :class="[classA, { active: isActive }]">段落</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const classA = ref('title')
const classB = ref('bold')
const isActive = ref(true)
</script>
- 第一个
<p>:class 为title bold。 - 第二个
<p>:class 为title,并且若isActive为 true 还会加active。
2.4 数组 + 条件:用三元或对象
<template>
<p :class="[baseClass, isActive ? 'active' : '']">段落</p>
<p :class="[baseClass, { active: isActive, error: hasError }]">段落</p>
</template>
<script setup>
import { ref } from 'vue'
const baseClass = ref('box')
const isActive = ref(true)
const hasError = ref(false)
</script>
2.5 和静态 class 一起写
:class 可以和静态的 class 共存,最终会合并:
<p class="static-title" :class="{ active: isActive }">段落</p>
渲染结果可能是:class="static-title active"(当 isActive 为 true 时)。
三、绑定内联 style(:style)
3.1 对象语法:键为 CSS 属性,值为样式值
语法: :style="{ 属性名: 值 }"
属性名可以用 驼峰(如 fontSize)或短横线(需引号,如 'font-size')。
值为字符串或数字;数字会默认加单位 px(部分属性如 opacity 不加)。
<template>
<div>
<p :style="{ color: textColor, fontSize: fontSize + 'px' }">彩色文字</p>
<p :style="{ color: 'blue', 'font-size': '20px' }">蓝色大字</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const textColor = ref('red')
const fontSize = ref(16)
</script>
- 第一个:颜色、字号来自变量;字号若想用数字自动加 px,可写
fontSize: fontSize(Vue 会加 px)。 - 第二个:短横线属性名要加引号。
3.2 自动加 px(数字型属性)
多数数字类型的 CSS 属性,Vue 会自动加 px:
<p :style="{ width: 100, height: 50 }">盒子</p>
渲染为 style="width: 100px; height: 50px;"。
若需要 rem、%、em 等,自己写成字符串即可:width: '10rem'。
3.3 绑定一个 style 对象变量
和 class 一样,可以把对象放在 script 或计算属性里:
<template>
<p :style="styleObject">段落</p>
</template>
<script setup>
import { ref } from 'vue'
const styleObject = ref({
color: 'red',
fontSize: '18px',
backgroundColor: 'lightyellow'
})
</script>
3.4 数组语法:多个 style 对象合并
语法: :style="[对象1, 对象2, ...]"
后面的对象会覆盖前面同名字段,适合“基础样式 + 覆盖样式”:
<template>
<p :style="[baseStyle, overrideStyle]">段落</p>
</template>
<script setup>
import { ref } from 'vue'
const baseStyle = ref({
color: 'blue',
fontSize: '14px'
})
const overrideStyle = ref({
fontSize: '20px'
})
</script>
最终 fontSize 为 20px,color 仍为 blue。
3.5 需要浏览器前缀时
某些属性需要前缀(如 transform),可以写多个键,Vue 会根据需要处理;复杂情况也可在对象里写带前缀的键:
<p :style="{ transform: 'scale(1.1)' }">放大</p>
Vue 会对需要前缀的属性自动加前缀(如 -webkit-transform 等)。
四、class 与 style 绑定小结
| 类型 | 写法示例 |
|---|---|
| class 对象 | :class="{ active: isActive }" |
| class 数组 | :class="[classA, classB]" |
| class 数组+对象 | :class="[classA, { active: isActive }]" |
| style 对象 | :style="{ color: c, fontSize: size + 'px' }" |
| style 数组 | :style="[baseStyle, overrideStyle]" |
| 与静态共存 | class="static" :class="dynamic"、style="..." :style="..." |