面试题:Vue 中 :class 和 :style 有几种表示方式?

在 Vue 中,:class:style 是动态绑定样式的重要特性,它们有多种灵活的表示方式。

🎨 :class 的多种表示方式

1. 对象语法(最常用)

<template>
  <!-- 根据条件动态切换类名 -->
  <div :class="{ active: isActive, 'text-danger': hasError }"></div>

  <!-- 与静态 class 共存 -->
  <div class="static" :class="{ active: isActive }"></div>

  <!-- 使用计算属性返回对象 -->
  <div :class="classObject"></div>
</template>

<script>
export default {
  data() {
    return {
      isActive: true,
      hasError: false
    }
  },
  computed: {
    classObject() {
      return {
        active: this.isActive && !this.hasError,
        'text-danger': this.hasError
      }
    }
  }
}
</script>

2. 数组语法

<template>
  <!-- 应用多个类名 -->
  <div :class="[activeClass, errorClass]"></div>

  <!-- 数组中使用对象语法 -->
  <div :class="[{ active: isActive }, errorClass]"></div>

  <!-- 条件判断 -->
  <div :class="[isActive ? 'active' : '', errorClass]"></div>
</template>

<script>
export default {
  data() {
    return {
      activeClass: 'active',
      errorClass: 'text-danger',
      isActive: true
    }
  }
}
</script>

3. 在组件上使用

<template>
  <!-- 子组件 -->
  <ChildComponent :class="customClass" />
</template>

<script>
export default {
  data() {
    return {
      customClass: 'my-custom-class'
    }
  }
}
</script>

🎯 :style 的多种表示方式

1. 对象语法(推荐)

<template>
  <!-- 直接使用对象 -->
  <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

  <!-- 使用样式对象 -->
  <div :style="styleObject"></div>

  <!-- 多个样式对象 -->
  <div :style="[baseStyles, overridingStyles]"></div>
</template>

<script>
export default {
  data() {
    return {
      activeColor: 'red',
      fontSize: 14,
      styleObject: {
        color: 'red',
        fontSize: '13px'
      },
      baseStyles: {
        padding: '10px',
        margin: '5px'
      },
      overridingStyles: {
        color: 'blue'
      }
    }
  }
}
</script>

2. 数组语法(多个样式对象)

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

<script>
export default {
  data() {
    return {
      baseStyles: {
        padding: '10px',
        fontSize: '14px'
      },
      customStyles: {
        backgroundColor: '#f5f5f5',
        border: '1px solid #ddd'
      }
    }
  }
}
</script>

3. 自动前缀和多重值

<template>
  <!-- 自动添加浏览器前缀 -->
  <div :style="{ transform: 'scale(' + scale + ')' }"></div>

  <!-- 多重值(浏览器支持最后一个) -->
  <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
</template>

<script>
export default {
  data() {
    return {
      scale: 1.2
    }
  }
}
</script>

💡 实际应用场景示例

综合示例

<template>
  <div>
    <!-- 动态按钮样式 -->
    <button 
      :class="[
        'btn',
        `btn-${type}`,
        { 
          'btn-disabled': disabled,
          'btn-loading': isLoading 
        }
      ]"
      :style="{
        opacity: disabled ? 0.6 : 1,
        transform: `scale(${isLoading ? 0.95 : 1})`,
        transition: 'all 0.2s ease'
      }"
    >
      {{ buttonText }}
    </button>

    <!-- 进度条 -->
    <div 
      class="progress-bar"
      :style="{
        width: progress + '%',
        backgroundColor: progressColor
      }"
    ></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      type: 'primary',
      disabled: false,
      isLoading: false,
      progress: 75,
      progressColor: '#4CAF50'
    }
  },
  computed: {
    buttonText() {
      return this.isLoading ? '加载中...' : '点击我'
    }
  }
}
</script>

<style scoped>
.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.btn-primary {
  background-color: #007bff;
  color: white;
}

.btn-disabled {
  cursor: not-allowed;
}

.btn-loading {
  pointer-events: none;
}

.progress-bar {
  height: 4px;
  transition: width 0.3s ease;
}
</style>

响应式样式管理

<template>
  <div 
    :class="[
      'card',
      `card-${size}`,
      { 
        'card-hoverable': hoverable,
        'card-selected': selected 
      }
    ]"
    :style="computedCardStyles"
  >
    Card Content
  </div>
</template>

<script>
export default {
  props: {
    size: {
      type: String,
      default: 'medium',
      validator: value => ['small', 'medium', 'large'].includes(value)
    },
    hoverable: Boolean,
    selected: Boolean,
    backgroundColor: String
  },
  computed: {
    computedCardStyles() {
      const styles = {
        borderRadius: '8px',
        boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
      }

      if (this.backgroundColor) {
        styles.backgroundColor = this.backgroundColor
      }

      return styles
    }
  }
}
</script>

🚀 最佳实践总结

  1. 对象语法:适合条件性的 class/style
  2. 数组语法:适合应用多个固定的 class/style
  3. 计算属性:复杂逻辑时使用,保持模板简洁
  4. 组件样式:注意在自定义组件上的行为差异
  5. 性能考虑:避免在模板中写复杂表达式

这些灵活的方式让 Vue 的样式绑定非常强大,能够应对各种复杂的动态样式需求。

THE END
喜欢就支持一下吧
点赞5 分享