Vue3样式绑定

Vue 3 样式绑定完全指南

本文档从零开始讲解 Vue 3 的样式绑定:如何用数据动态控制 classstyle,以及单文件组件里的 scoped深度选择器在 CSS 里使用响应式数据 等,配有大量示例,适合新手系统学习。


一、为什么需要“样式绑定”?

1.1 静态 vs 动态

写死 class 或 style 很简单:

<p class="title">标题</p>
<p style="color: red;">红色文字</p>

但实际开发里,样式经常要跟着数据变,例如:

  • 当前选中的 Tab 要高亮(加个 active class)
  • 主题切换(亮色/暗色,整页的 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 → 有 active class。
  • hasError 为 true → 有 text-danger class。
  • 类名里有横线(如 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="..."

五、单文件组件里的