3. 基础-类与样式绑定

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

绑定 HTML class

绑定字符串

示例

<script>
  export default {
    name: "App",
    data() {
      return {
        isActive: "active",
      };
    },
  };
</script>

<template>
  <div>
    <div :class="isActive"></div>
  </div>
</template>

<style>
  .active {
    width: 100px;
    height: 100px;
    background: red;
  }
</style>

绑定对象

我们可以给 :class (v-bind:class 的缩写) 传递一个对象来动态切换 class

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

上面的语法表示 active 是否存在取决于数据属性 isActive 的真假值。
你可以在对象中写多个字段来操作多个 class 。此外,:class 指令也可以和一般的 class attribute 共存。举例来说,下面这样的状态

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

配合以下模板

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

渲染的结果会是

<div class="static active"></div>

当 isActive 或者 hasError 改变时,class 列表会随之更新。举例来说,如果 hasError 变为 true,class 列表也会变成 "static active text-danger" 。
示例

<script>
  export default {
    name: "App",
    data() {
        return {
          isActive: true,
          hasError: true
        };
    },
  };
</script>

<template>
    <div>
      <div class="static" :class="{ 'active': isActive, 'error': hasError }">
        v-bind:class演示
      </div>
    </div>
</template>

<style>
  .static {
    font-size: 20px;
  }

  .active {
    width: 100px;
    height: 100px;
    background: red;
  }

  .error {
    color: blue;
  }
</style>

它将呈现

<div class="static active error"> v-bind:class演示 </div>

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

<script>
  export default {
    name: "App",
    data() {
      return {
        classObject: {
          active: true,
          'text-danger': false
        }
      }
    }
  };
</script>

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

<style>
  .active {
    width: 100px;
    height: 100px;
    background: red;
  }
</style>

这也会渲染出相同的结果。我们也可以绑定一个返回对象的计算属性。这是一个常见且很有用的技巧

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

绑定数组

我们可以给 :class 绑定一个数组来渲染多个 CSS class

<script>
  export default {
    name: "App",
    data() {
      return {
        activeClass: 'active',
        errorClass: 'text-danger'
      }
    }
  };
</script>

<template>
  <div>
    <div :class="[ activeClass, errorClass ]">
      v-bind:class演示
    </div>
  </div>
</template>

<style>
  .active {
    width: 100px;
    height: 100px;
    background: red;
  }

  .text-danger {
    color: blue;
  }
</style>

渲染的结果是

<div class="active text-danger"> v-bind:class演示 </div>

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

<script>
  export default {
    name: "App",
    data() {
      return {
        isActive: true,
        activeClass: 'active',
        errorClass: 'error',
      };
    },
  };
</script>

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

<style>
  .active {
    width: 100px;
    height: 100px;
    background: red;
  }

  .error {
    color: blue;
  }
</style>

errorClass 会一直存在,但 activeClass 只会在 isActive 为真时才存在。
然而,这可能在有多个依赖条件的 class 时会有些冗长。因此也可以在数组中嵌套对象

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

在组件上使用

如果你的组件有多个根元素,你将需要指定哪个根元素来接收这个 class。你可以通过组件的 $attrs 属性来实现指定

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

这将被渲染为

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

绑定 style 内联样式

绑定对象

:style 支持绑定 JavaScript 对象值,对应的是 HTML 元素的 style 属性

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

尽管推荐使用 camelCase,但 :style 也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称),例如

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

示例

<script>
  export default {
    name: "App",
    data() {
      return {
        activeColor: 'red',
        fontSize: 30
      }
    }
  };
</script>

<template>
  <div>
    <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"> 绑定 style 内联样式</div>
  </div>
</template>

它将呈现

<div style="color: red; font-size: 30px;"> 绑定 style 内联样式</div>

直接绑定一个样式对象通常是一个好主意,这样可以使模板更加简洁

<script>
  export default {
    name: "App",
    data() {
      return {
        styleObject: {
          color: 'red',
          fontSize: '13px'
        }
      }
    }
  };
</script>

<template>
  <div>
    <div :style="styleObject"> 绑定 style 内联样式</div>
  </div>
</template>

同样的,如果样式对象需要更复杂的逻辑,也可以使用返回样式对象的计算属性。

绑定数组

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

<script>
  export default {
    name: "App",
    data() {
      return {
        baseStyles: {
          color: 'orange',
          fontSize: '13px'
        },
        overridingStyles: {
          width: "100px",
          height: "100px",
          background: "blue"
        }
      }
    }
  };
</script>

<template>
  <div>
    <div :style="[ baseStyles, overridingStyles ]">:style 绑定数组</div>
  </div>
</template>

自动前缀

样式多值

posted @ 2023-07-17 22:41  HopeLive  阅读(10)  评论(0)    收藏  举报