阅读 967

[翻译]vue3指南-06Class and Style Bindings 类名和样式值绑定

A common need for data binding is manipulating an element's class list and its inline styles. Since they are both attributes, we can use v-bind to handle them: we only need to calculate a final string with our expressions. However, meddling with string concatenation is 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

data绑定的一个普遍需求是去操作一个元素的class list和他的内联样式. 既然这些东西都是属性(attribute),那我们就可以用v-bind去处理: 只需要用表达式计算出一个最终字符串.但是哦,操作字符串拼接/运算之类的是很烦人和易错的. 处于这原因,当v-bind用于classstyle时,Vue提供了一系列专门增强. 表达式结果不仅可以是字符串,还可以是objects和array

Binding HTML Classes 绑定HTML类名

Object Syntax 对象语法

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

可以把一个对象传到:class去动态的toggle类名

<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 template:

还可以通过让这个对象有更多的字段来操作多个类名切换. 另外,:class指令可以和class属性(attribute)同时存在,给出下面template:

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

And the following data: 以及下面的data:

data() {
  return {
    isActive: true,
    hasError: false
  }
}
复制代码

It will render: 会这样渲染:

<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".

isActivehasError值有变化时候,class list会相应更新.比如,如果hasError值变为true,那么,class list就会成 "static active text-danger"

The bound object doesn't have to be inline: 绑定的对象没必内联在元素里:

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

This will render the same result. We can also bind to a computed property that returns an object. This is a common and powerful pattern

上面这样会跟之前内联写法的效果是一样的. 还能把data绑定成一个computed属性,然后返回一个对象.——这是一个常用而且很有效的模式.

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

Array Syntax 数组语法

We can pass an array to :class to apply a list of classes:

我们可以传一个数组到:class,应用一个class列表.

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

Which will render: 会这么渲染:

<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名,你可以用三元表达式:

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

This will always apply errorClass, but will only apply activeClass when isActive is truthy. 像上面这样,会恒渲染errorClass,然后根据isActive地真假去条件渲染activeClass.

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 array syntax:

然后,如果有多个条件语句,未免有点冗余了. 这就是在数组语法里使用对象语法 也是可行的原因:

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

With Components Components相关

This section assumes knowledge of Vue Components. Feel free to skip it and come back later 这节假设你知道Vue 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.

For example, if you declare this component:

当你在一个只有一个根元素的自定义component上使用class属性(attribute), 这些class值会被加到这个根元素上. 它上面已经存在类名不会被覆盖.

如果你这样声明一个元素:

const app = Vue.createApp({})

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

复制代码

Then add some classes when using it: 用他的时候,添加了这些类名:

<div id="app">
  <my-component class="baz boo"></my-component>
</div>
复制代码

The rendered HTML will be: HTML渲染结果会是:

<p class="foo bar baz boo">Hi</p>
复制代码

The same is true for class bindings: 用:class绑定也是一样可行的:

<my-component :class="{ active: isActive }"></my-component>
复制代码

When isActive is truthy, the rendered HTML will be: 当isActive为真时候,HTML渲染结果为:

<p class="foo bar active">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:

如果自定义组件有多个根元素,那需要指明接收类名的元素. 可以用$attrs组件属性(property)来完成这个行为:

<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>
  `
})
复制代码

You can learn more about component attribute inheritance in Non-Prop Attributes section.

更多关于组件属性(attribute)继承的内容在无prop属性这节.

Binding Inline Styles 内联样式绑定

Object Syntax 对象语法

The object syntax for :style is pretty straightforward - 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的对象语法挺直白/简单/直截了当的. 除了本质上是一个JS对象以外,它看起来就很像CSS.CSS属性(property)名可以使用camelCase写法或者kebab-case写法(要用引号扩起来).

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

It is often a good idea to bind to a style object directly so that the template is cleaner:

用一个style对象直接绑定是一个好的写法,这样template看起来很干净.

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

Again, the object syntax is often used in conjunction with computed properties that return objects.

再说一次,对象语法通常和返回对象的computed属性(property)结合起来用.

Array Syntax 数组语法

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

:style的数组语法允许往相同元素应用多个style对象:

<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.

:style里要用一个需要第三方前缀的CSS属性(propety)时候,比如transform,Vue会自动检测,然后自动添加合适的前缀.

Multiple Values 多值

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

你可以为一个sytle属性提供一个多值的数组(带前缀的),比如:

<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,当然在浏览器支持没有前缀的flexbox的前提下.

文章分类
前端
文章标签