【vue3】Data binding, dynamic rendering of class and style

A common requirement for data binding is manipulating elements' CSS class lists and inline styles. Because class and style are attributes, we can use v-bind to bind them to dynamic strings like other attributes. However, when dealing with more complex bindings , generating strings through concatenation is cumbersome and error-prone. Therefore, Vue provides special functional enhancements specifically for the v-bind usage of classes and styles . In addition to strings, the value of an expression can also be an object or array.

Binding class

binding object

We can pass an object to :class (short for v-bind:class) to dynamically switch classes:

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

The above syntax indicates that the existence of active depends on the true or false value of the data attribute isActive.

You can write multiple fields in the object to operate multiple classes. In addition, the :class directive can also coexist with regular class attributes. For example, the following status:

data() {
    
    
  return {
    
    
    isActive: true,
    hasError: false
  }
}

In conjunction with the following templates:

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

The rendered result will be:

<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 also become "static active text-danger".

The bound object does not necessarily need to be written in the form of an inline literal. You can also bind an object directly:

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

This will render the same result. We can also bind a computed property of the returned object. This is a common and useful trick:

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>

binding array

We can bind an array to :class to render multiple CSS classes:

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

The rendered result is:

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

If you also want to conditionally render a class in an array, you can use a ternary expression:

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

errorClass will always exist, but activeClass will only exist when isActive is true.

However, this may be a bit verbose when there are multiple dependent classes. It is therefore also possible to nest objects within arrays:

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

Use on component

For components with only one root element, when you use the class attribute, these classes will be added to the root element and merged with the existing classes on the element.

For example, if you declare a component named MyComponent, the template is as follows:

<!-- 子组件模板 -->
<p class="foo bar">Hi!</p>

Add some classes when using:

<!-- 在使用组件时 -->
<MyComponent class="baz boo" />

The rendered HTML is:

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

The binding of Class is the same:

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

When isActive is true, the rendered HTML will be:

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

If your component has multiple root elements, you will need to specify which root element receives this class. You can specify this through the $attrs attribute of the component:

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

This will be rendered as:

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

Bind inline style style

binding object

:style supports binding JavaScript object values, corresponding to the style attribute of HTML elements:

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

Although camelCase is recommended, :style also supports kebab-cased forms of CSS property keys (corresponding to their actual names in CSS), for example:

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

It's often a good idea to bind a style object directly to make the template cleaner:

data() {
    
    
  return {
    
    
    styleObject: {
    
    
      color: 'red',
      fontSize: '13px'
    }
  }
}
<div :style="styleObject"></div>

Likewise, if the style object requires more complex logic, you can also use computed properties that return the style object.

binding array

We can also bind an array containing multiple style objects to :style. These objects will be merged and rendered on the same element:

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

Guess you like

Origin blog.csdn.net/weixin_43361722/article/details/129824418