跳转到内容

类和样式绑定

数据绑定中一个常见的需求是操作元素类列表和内联样式。由于 classstyle 都是属性,我们可以使用 v-bind 来动态地将它们赋值为字符串,就像对其他属性做的那样。然而,尝试使用字符串连接来生成这些值可能会很烦人且容易出错。因此,Vue在 v-bindclassstyle 一起使用时提供了特殊的增强。除了字符串外,表达式也可以计算为对象或数组。

绑定HTML类

绑定到对象

我们可以将一个对象传递给 :class(即 v-bind:class),以动态切换类。

模板
<div :class="{ active: isActive }"></div>

上述语法意味着 active 类的存在将由数据属性 isActive 的真假性决定。

你可以通过在对象中有更多字段来切换多个类。此外,:class 指令也可以与普通的 class 属性共存。所以给定以下状态

js
const isActive = ref(true)
const hasError = ref(false)
js
data() {
  return {
    isActive: true,
    hasError: false
  }
}

和以下模板

模板
<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>

它将渲染

模板
<div class="static active"></div>

isActivehasError 发生变化时,类列表将相应地更新。例如,如果 hasError 变为 true,类列表将变为 "static active text-danger"

绑定的对象不必是内联的

js
const classObject = reactive({
  active: true,
  'text-danger': false
})
js
data() {
  return {
    classObject: {
      active: true,
      'text-danger': false
    }
  }
}
模板
<div :class="classObject"></div>

这将渲染

模板
<div class="active"></div>

我们还可以绑定到返回对象的 计算属性。这是一个常见且强大的模式

js
const isActive = ref(true)
const error = ref(null)

const classObject = computed(() => ({
  active: isActive.value && !error.value,
  'text-danger': error.value && error.value.type === 'fatal'
}))
js
data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
模板
<div :class="classObject"></div>

绑定到数组

我们可以将 :class 绑定到数组,以应用一系列类。

js
const activeClass = ref('active')
const errorClass = ref('text-danger')
js
data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}
模板
<div :class="[activeClass, errorClass]"></div>

这将渲染

模板
<div class="active text-danger"></div>

如果你希望条件性地切换列表中的类,你可以使用三元表达式来完成

模板
<div :class="[isActive ? activeClass : '', errorClass]"></div>

此操作始终应用errorClass,但只有当isActive为真值时才会应用activeClass

然而,如果您有多个条件类,这可能会有些冗长。这就是为什么您还可以在数组语法内使用对象语法。

模板
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>

使用组件

本节假设您已了解组件。您可以随时跳过此部分,稍后再回来。

当您在具有单个根元素的组件上使用class属性时,这些类将添加到组件的根元素上,并与已存在的任何类合并。

例如,如果我们有一个名为MyComponent的组件,其模板如下

模板
<!-- child component template -->
<p class="foo bar">Hi!</p>

然后在使用它时添加一些类

模板
<!-- when using the component -->
<MyComponent class="baz boo" />

渲染的HTML将如下所示

模板
<p class="foo bar baz boo">Hi!</p>

同样,这也适用于类绑定

模板
<MyComponent :class="{ active: isActive }" />

isActive为真值时,渲染的HTML将如下所示

模板
<p class="foo bar active">Hi!</p>

如果您的组件有多个根元素,您需要定义哪个元素将接收此类。您可以通过使用$attrs组件属性来实现这一点

模板
<!-- MyComponent template using $attrs -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
模板
<MyComponent class="baz" />

将渲染

HTML
<p class="baz">Hi!</p>
<span>This is a child component</span>

您可以在传递属性部分了解更多关于组件属性继承的信息。

绑定内联样式

绑定到对象

:style支持绑定到JavaScript对象值 - 它对应于HTML元素的style属性

js
const activeColor = ref('red')
const fontSize = ref(30)
js
data() {
  return {
    activeColor: 'red',
    fontSize: 30
  }
}
模板
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

尽管建议使用驼峰命名法键,但:style也支持短横线连接的CSS属性键(对应于它们在实际CSS中的使用) - 例如

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

通常,直接绑定到样式对象是一个好主意,这样模板会更简洁

js
const styleObject = reactive({
  color: 'red',
  fontSize: '30px'
})
js
data() {
  return {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}
模板
<div :style="styleObject"></div>

同样,对象样式绑定通常与返回对象的计算属性一起使用。

绑定到数组

我们可以将:style绑定到多个样式对象的数组。这些对象将被合并并应用于同一元素

模板
<div :style="[baseStyles, overridingStyles]"></div>

自动前缀化

当您在:style中使用需要供应商前缀的CSS属性时,Vue会自动添加适当的prefix。Vue通过在运行时检查当前浏览器支持哪些样式属性来实现这一点。如果浏览器不支持某个特定属性,则将测试各种带前缀的变体,以尝试找到受支持的属性。

多个值

您可以为样式属性提供多个(带前缀的)值的数组,例如

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

这只会渲染数组中浏览器支持的最后一个值。在这个例子中,它将渲染display: flex,对于支持flexbox无前缀版本的浏览器。

已加载类和样式绑定