温故知新 Vue 3: Lesson 4

124 阅读3分钟

温故知新 Vue 3: Lesson 4

Class and Style Bindings

manipulating an element's class list and its inline styles

修改元素的 class 列表和 inline style

Binding HTML Classes

Object Syntax

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

object property key(这里是 active) 是你想添加的 className, 对应的 value 是一个 bool (这里是 isActive), 用于控制是否添加这个 className

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

the :class directive can also co-exist with the plain class attribute.

v-bind:class 可以和原生元素的 class attribute 共存. 他们会进行合并.

你也可以直接绑定一个 data 里面的 object

<div :class="classObject"></div>
  //...
  data() {
    return {
      classObject: {
        active: true,
        'text-danger': false
      }
    }
  }
  //...

或者使用 computed property

<div :class="classObject"></div>
  //...
  computed: {
    classObject() {
      return {
        active: this.isActive && !this.error,
        'text-danger': this.error && this.error.type === 'fatal'
      }
    }
  }
  //...

Array Syntax

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

array 中的元素, 如果不带''的话, 是你想添加的 className variable(这里是 activeClass, errorClass), 存在 data 里面, variable 对应的值就是 className. 你每次对 variable 进行一个新的赋值, 检测到变化后, 会自动更新元素的 className

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

因为 v-bind 的值是 js 表达式, 所以 array 里面可以用 tenary expresstion. 比如isActive ? activeClass : ''只有 isActive 为 true 时才会使用 activeClass.

同样 array 里面可以用 object. 不过建议比较复杂的写法, 放到 data 或 computed 里面去处理.

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

With Components

When you use the class attribute on a custom component with a single root element, those classes will be added to this element. Existing classes on this element will not be overwritten.

在 single root element 的自定义组件上使用 class attribute 时, 这些 class 会被加到这个 root element 上. root element 上已经存在的 class 不会被覆盖. 不管你是不是用 v-bind:class, 结果都是一样的.

<div id="app">
  <my-component class="baz boo"></my-component>
</div>

<!-- after -->
<p class="foo bar baz boo">Hi</p>
const app = Vue.createApp({});

app.component("my-component", {
  template: `<p class="foo bar">Hi!</p>`,
});

If your component has multiple root elements, you would need to define which component will receive this class. You can do this using $attrs component property:

在 multiple root element 的自定义组件上使用 class attribute 时, 则必须要指定谁来接收.

<div id="app">
  <my-component class="baz"></my-component>
</div>
const app = Vue.createApp({});

app.component("my-component", {
  template: `
    <p :class="$attrs.class">Hi!</p>
    <span>This is a child component</span>
  `,
});

Binding Inline Styles

Object Syntax

it looks almost like CSS, except it's a JavaScript object. You can use either camelCase or kebab-case (use quotes with kebab-case) for the CSS property names

style 绑定对象, 一般 object key 用的是 camelCase, 对应原生 style 里面的 kebab-case.

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

<!-- recommend -->
<div :style="styleObject"></div>

<!-- rendered -->
<div style="color: 'red'; font-size: 13px;"></div>
data() {
  return {
    activeColor: 'red',
    fontSize: 13,

    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}

Array Syntax

The array syntax for :style allows you to apply multiple style objects to the same element:

array 形式允许你将多个 style object 应用于同一个元素

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

Auto-prefixing

When you use a CSS property that requires vendor prefixes in :style, for example transform, Vue will automatically detect and add appropriate prefixes to the applied styles.

一般来说, vendor prefix 不用管, vue 会自动添加.

You can provide an array of multiple (prefixed) values to a style property, for example:

如果你需要的话, 可以在 Object key 对应的 value 使用 array.

This will only render the last value in the array which the browser supports.

会自动添加最后一个支持的值.

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

本文使用 mdnice 排版