Skip to content

Class 与 Style 绑定

Vueclassstyle提供了特殊的绑定语法,使得在模板中动态地应用样式变得简单

绑定HTML

对象语法

我们可以传给v-bind:class一个对象,以动态地切换class

html
<div v-bind:class="{ active: isActive }"></div>

上面的语法表示active这个class存在与否将取决于数据属性isActive的值

html
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>

上面的语法表示active这个class存在与否将取决于数据属性isActive的值,text-danger这个class存在与否将取决于数据

百年规定的对象不一定需要写成内联字面量的形式,也可以直接绑定一个对象 :

html
<div v-bind:class="classObject"></div>
javascript
const classObject = {
  active: true,
  'text-danger': false,
}

也可以绑定一个返回对象的计算属性

html
<div v-bind:class="classObject"></div>
javascript
const classObject = computed(() => {
  return {
    active: isActive.value,
    'text-danger': hasError.value,
  }
})

数组语法

我们可以把一个数组传给v-bind:class,以应用一个class列表

html
<div v-bind:class="[activeClass, errorClass]"></div>

上面的语法表示activeClasserrorClass这两个class将应用到这个元素上

如果现在数组中有条件的渲染某个class,你可以使用三元表达式

html
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

也可以在数组中嵌套对象

javascript
const activeClass = ref('active')
const errorClass = ref('text-danger')
html
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>

TIP

注意这里的使用方式[activeClass]: isActive

  • [activeClass] 表示这个类名来自 activeClass 变量的值
  • isActive 是布尔值,决定是否应用这个类名

在组件上使用

对于只有一个根元素的组件,当绑定class时,类名会被添加到根元素上,动态绑定时也是一样

html
<my-component v-bind:class="{ active: isActive }"></my-component>

<!--my-component 子组件模板-->
<p class="foo bar">Hi!</p>

<!--渲染出的HTML如下:-->
<p class="foo bar active">Hi!</p>

如果子组件有多个根元素,那么类名会被添加到第一个根元素上

html
<my-component v-bind:class="{ active: isActive }"></my-component>
<!--my-component 子组件模板-->
<p>Hi!</p>
<span>There!</span>
<!--渲染出的HTML如下:-->
<p class="foo bar active">Hi!</p>
<span>There!</span>

也可以在子组件中通过$attrs属性来指定接收的元素

html
<my-component :class="{ active: isActive }"></my-component>
<!--my-component 子组件模板-->
<p :class="$attrs.class">Hi!</p>
<span>There!</span>
<!--渲染出的HTML如下:-->
<p class="active">Hi!</p>
<span>There!</span>

绑定内联样式

绑定对象

:style 绑定也可以绑定一个样式对象,样式对象中的键名对应CSS属性名,并且以驼峰命名法(camelCase)或短横分隔命名(kebab-case,记得用引号括起来)来命名

html
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

<div :style="{ 'font-size': fontSize + 'px' }"></div>

直接绑定一个样式对象可以是模板更加简洁

html
<div v-bind:style="styleObject"></div>
javascript
const styleObject = creactive({
  color: 'red',
  fontSize: '16px',
})

如果样式对象需要更复杂的逻辑,也可以使用返回样式对象的计算属性

html
<div v-bind:style="computedStyleObject"></div>
javascript
const computedStyleObject = computed(() => {
  return {
    color: activeColor.value,
    fontSize: fontSize.value + 'px',
  }
})

:style 属性也可以和常规的style共存

绑定数组

:style绑定一个包含多个样式对象的数组,多个对象会以数组索引的顺序依次应用

html
<div v-bind:style="[baseStyles, overridingStyles]"></div>
javascript
const baseStyles = {
  color: 'blue',
  fontSize: '14px',
}
const overridingStyles = {
  color: 'red',
  fontWeight: 'bold',
}

最后被渲染到结果为 :

html
<div style="color: red; font-size: 14px; font-weight: bold;"></div>

自动前缀

Vue 在运行时动态检测浏览器支持的 CSS 属性,其底层逻辑类似以下步骤:

检测是否支持标准属性(如 transform)。

如果不支持,则依次尝试添加浏览器前缀(如 -webkit-transform、-moz-transform,直到找到支持的属性)。 最终应用第一个有效的属性。

这种机制主要依赖于现代浏览器提供的 CSS.supports() API(即 @supports 的 JS 版本)(Vue3)或通过创建临时 DOM 元素进行特性检测(Vue2)。

注意

性能影响 :
每次渲染都会进行属性检测(极轻量级,但对超高频更新的组件可能有影响)
解决方案:对静态样式改用普通 style 属性或 CSS 类名
>
> 可控性 :
如果需要强制指定前缀(如兼容旧版 Safari),建议直接手动写入:
> <div :style="{ '-webkit-transform': 'rotate(30deg)' }"></div>
>
不支持场景
自定义 CSS 属性(--var)或 Houdini API 需要自行处理前缀。
动画中的 @keyframes 名称仍需手动加前缀。

样式多值

可以对一个样式属性提供多个不同的前缀的值

html
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带前缀的 flexbox,那么渲染结果会是 display: flex