重学Vue3-动态Class/Style

163 阅读2分钟

动态Class/Style

可以使用 v-bind 将它们和动态的字符串绑定,Vue 专门为 class 和 style 的 v-bind 用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组。

Class

:class 指令也可以和一般的 class attribute 共存,例如:

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

表达式的值是对象形式

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

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

const classObject = reactive({
  active: true,
  'text-danger': false
})

<div :class="classObject"></div>

我们也可以绑定一个返回对象的计算属性。这是一个常见且很有用的技巧:

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

const classObject = computed(() => ({
  active: isActive.value && !error.value,
  'text-danger': error.value && error.value.type === 'fatal'
}))

<div :class="classObject"></div>

表达式的值是数组形式

<div :class="[activeClass, errorClass]"></div>

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

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

这样类名isActive会根据activeClass的值是否添加到div上

并且,甚至可以在数组内嵌套对象

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

给组件设置class

之前都是给普通html标签设置class,现在给组件设置class会有怎样的效果呢。

当组件只有一个根节点时,这些 class 会被添加到根元素上并与该元素上已有的 class 合并
但是组件是多个根节点时,就不知道哪个节点接收了。你可以通过组件的 $attrs 属性来指定接收的元素

演示一下,这里给组件设置文字颜色

//App.vue
<script setup>
import Comp from './Comp.vue'
</script>

<template>
<Comp class="fir"/>
</template>
<style>
.fir{
color:yellowgreen
}
</style>

//Comp.vue
<template>
  <div>
    <div :class="$attrs.class"> 第一个</div>
  </div>
  <div :class="$attrs.class">
    第二个
  </div>
</template>

image.png

Style

表达式的值是对象形式

const activeColor = ref('red')
const fontSize = ref(30)

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

官方推荐使用 camelCase,但也支持kebab-cased

//camelCase
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

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

直接绑定一个样式对象会更简洁,也可以使用返回样式对象的计算属性

const styleObject = reactive({
  color: 'red',
  fontSize: '30px'
})

<div :style="styleObject"></div>

表达式的值是数组形式 我们还可以给 :style 绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上:

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