Appearance
Class 与 Style 绑定
Vue为class和style提供了特殊的绑定语法,使得在模板中动态地应用样式变得简单
绑定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>上面的语法表示activeClass和errorClass这两个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。