Class 与 Style 绑定 | Class and Style Bindings
A common need for data binding is manipulating an element's class list and inline styles. Since class
and style
are both attributes, we can use v-bind
to assign them a string value dynamically, much like with other attributes. However, trying to generate those values using string concatenation can be annoying and error-prone. For this reason, Vue provides special enhancements when v-bind
is used with class
and style
. In addition to strings, the expressions can also evaluate to objects or arrays.
数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class
和 style
都是 attribute,我们可以和其他 attribute 一样使用 v-bind
将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。因此,Vue 专门为 class
和 style
的 v-bind
用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组。
绑定 HTML class | Binding HTML Classes
绑定对象 | Binding to Objects
We can pass an object to :class
(short for v-bind:class
) to dynamically toggle classes:
我们可以给 :class
(v-bind:class
的缩写) 传递一个对象来动态切换 class:
template
<div :class="{ active: isActive }"></div>
The above syntax means the presence of the active
class will be determined by the truthiness of the data property isActive
.
上面的语法表示 active
是否存在取决于数据属性 isActive
的真假值。
You can have multiple classes toggled by having more fields in the object. In addition, the :class
directive can also co-exist with the plain class
attribute. So given the following state:
你可以在对象中写多个字段来操作多个 class。此外,:class
指令也可以和一般的 class
attribute 共存。举例来说,下面这样的状态:
js
const isActive = ref(true)
const hasError = ref(false)
And the following template:
配合以下模板:
template
<div
class="static"
:class="{ active: isActive, 'text-danger': hasError }"
></div>
It will render:
渲染的结果会是:
template
<div class="static active"></div>
When isActive
or hasError
changes, the class list will be updated accordingly. For example, if hasError
becomes true
, the class list will become "static active text-danger"
.
当 isActive
或者 hasError
改变时,class 列表会随之更新。举例来说,如果 hasError
变为 true
,class 列表也会变成 "static active text-danger"
。
The bound object doesn't have to be inline:
绑定的对象并不一定需要写成内联字面量的形式,也可以直接绑定一个对象:
js
const classObject = reactive({
active: true,
'text-danger': false
})
template
<div :class="classObject"></div>
This will render:
这将渲染:
template
<div class="active"></div>
We can also bind to a computed property that returns an object. This is a common and powerful pattern:
我们也可以绑定一个返回对象的计算属性。这是一个常见且很有用的技巧:
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'
}))
template
<div :class="classObject"></div>
绑定数组 | Binding to Arrays
We can bind :class
to an array to apply a list of classes:
我们可以给 :class
绑定一个数组来渲染多个 CSS class:
js
const activeClass = ref('active')
const errorClass = ref('text-danger')
template
<div :class="[activeClass, errorClass]"></div>
Which will render:
渲染的结果是:
template
<div class="active text-danger"></div>
If you would like to also toggle a class in the list conditionally, you can do it with a ternary expression:
如果你也想在数组中有条件地渲染某个 class,你可以使用三元表达式:
template
<div :class="[isActive ? activeClass : '', errorClass]"></div>
This will always apply errorClass
, but activeClass
will only be applied when isActive
is truthy.
errorClass
会一直存在,但 activeClass
只会在 isActive
为真时才存在。
However, this can be a bit verbose if you have multiple conditional classes. That's why it's also possible to use the object syntax inside the array syntax:
然而,这可能在有多个依赖条件的 class 时会有些冗长。因此也可以在数组中嵌套对象:
template
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>
在组件上使用 | With Components
This section assumes knowledge of Components. Feel free to skip it and come back later.
本节假设你已经有 Vue 组件的知识基础。如果没有,你也可以暂时跳过,以后再阅读。
When you use the class
attribute on a component with a single root element, those classes will be added to the component's root element and merged with any existing class already on it.
对于只有一个根元素的组件,当你使用了 class
attribute 时,这些 class 会被添加到根元素上并与该元素上已有的 class 合并。
For example, if we have a component named MyComponent
with the following template:
举例来说,如果你声明了一个组件名叫 MyComponent
,模板如下:
template
<!-- child component template -->
<!-- 子组件模板 -->
<p class="foo bar">Hi!</p>
Then add some classes when using it:
在使用时添加一些 class:
template
<!-- when using the component -->
<!-- 在使用组件时 -->
<MyComponent class="baz boo" />
The rendered HTML will be:
渲染出的 HTML 为:
template
<p class="foo bar baz boo">Hi!</p>
The same is true for class bindings:
Class 的绑定也是同样的:
template
<MyComponent :class="{ active: isActive }" />
When isActive
is truthy, the rendered HTML will be:
当 isActive
为真时,被渲染的 HTML 会是:
template
<p class="foo bar active">Hi!</p>
If your component has multiple root elements, you would need to define which element will receive this class. You can do this using the $attrs
component property:
如果你的组件有多个根元素,你将需要指定哪个根元素来接收这个 class。你可以通过组件的 $attrs
属性来指定接收的元素:
template
<!-- MyComponent template using $attrs -->
<!-- MyComponent 模板使用 $attrs 时 -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
template
<MyComponent class="baz" />
Will render:
这将被渲染为:
html
<p class="baz">Hi!</p>
<span>This is a child component</span>
You can learn more about component attribute inheritance in Fallthrough Attributes section.
你可以在透传 Attribute 一章中了解更多组件的 attribute 继承的细节。
绑定内联样式 | Binding Inline Styles
绑定对象 | Binding to Objects
:style
supports binding to JavaScript object values - it corresponds to an HTML element's style
property:
:style
支持绑定 JavaScript 对象值,对应的是 HTML 元素的 style
属性:
js
const activeColor = ref('red')
const fontSize = ref(30)
template
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
Although camelCase keys are recommended, :style
also supports kebab-cased CSS property keys (corresponds to how they are used in actual CSS) - for example:
尽管推荐使用 camelCase,但 :style
也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称),例如:
template
<div :style="{ 'font-size': fontSize + 'px' }"></div>
It is often a good idea to bind to a style object directly so that the template is cleaner:
直接绑定一个样式对象通常是一个好主意,这样可以使模板更加简洁:
js
const styleObject = reactive({
color: 'red',
fontSize: '30px'
})
template
<div :style="styleObject"></div>
Again, object style binding is often used in conjunction with computed properties that return objects.
同样的,如果样式对象需要更复杂的逻辑,也可以使用返回样式对象的计算属性。
绑定数组 | Binding to Arrays
We can bind :style
to an array of multiple style objects. These objects will be merged and applied to the same element:
我们还可以给 :style
绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上:
template
<div :style="[baseStyles, overridingStyles]"></div>
自动前缀 | Auto-prefixing
When you use a CSS property that requires a vendor prefix in :style
, Vue will automatically add the appropriate prefix. Vue does this by checking at runtime to see which style properties are supported in the current browser. If the browser doesn't support a particular property then various prefixed variants will be tested to try to find one that is supported.
当你在 :style
中使用了需要浏览器特殊前缀的 CSS 属性时,Vue 会自动为他们加上相应的前缀。Vue 是在运行时检查该属性是否支持在当前浏览器中使用。如果浏览器不支持某个属性,那么将尝试加上各个浏览器特殊前缀,以找到哪一个是被支持的。
样式多值 | Multiple Values
You can provide an array of multiple (prefixed) values to a style property, for example:
你可以对一个样式属性提供多个 (不同前缀的) 值,举例来说:
template
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
This will only render the last value in the array which the browser supports. In this example, it will render display: flex
for browsers that support the unprefixed version of flexbox.
数组仅会渲染浏览器支持的最后一个值。在这个示例中,在支持不需要特别前缀的浏览器中都会渲染为 display: flex
。