Vue3 零基础每日笔记(021):class 与 style 动态绑定——对象、数组、三元表达式写法汇总

一、前言

数据驱动视图的最后一公里是样式:Tab 激活高亮、状态标签红绿、行选中变色------这些都要样式"跟着数据变"。class 和 style 的动态绑定写法多而杂,这篇一次汇总到位,以后写样式直接来查表。

二、:class 对象语法:{ 类名: 布尔值 }

最常用写法------类名做 key,数据表达式做 value,为 true 就挂上该类:

vue 复制代码
<template>
  <button :class="{ active: isActive }">点我切换高亮</button>

  <!-- 混合:静态 class 和动态 :class 共存,Vue 自动合并 -->
  <button class="btn" :class="{ active: isActive, disabled: isDisabled }">
    多条件高亮
  </button>
</template>

<script setup>
import { ref } from 'vue'
const isActive = ref(true)
const isDisabled = ref(false)
</script>

<style scoped>
.btn { padding: 6px 16px; }
.active { background: #42b983; color: #fff; }
.disabled { opacity: 0.5; }
</style>

两个要点:

  1. 静态 class 和动态 :class 可以同时写,结果是合并,不会覆盖
  2. 对象里可以放任意表达式:{ active: count > 5 }

三、:class 数组语法:多类名批量挂

类名组合比较动态时用数组:

vue 复制代码
<template>
  <!-- 数组:每个元素都是一个类名 -->
  <p :class="[baseClass, activeClass]">数组组合样式</p>

  <!-- 数组 + 对象混搭:数组里某一项用对象控制开关 -->
  <p :class="[baseClass, { highlight: isHighlight }]">数组嵌对象</p>

  <!-- 三元表达式:二选一场景 -->
  <p :class="isError ? 'error' : 'success'">{{ isError ? '失败' : '成功' }}</p>
</template>

<script setup>
import { ref } from 'vue'

const baseClass = ref('text')
const activeClass = ref('active')
const isHighlight = ref(true)
const isError = ref(false)
</script>

选择心法:条件开关多 → 对象;类名本身是变量 → 数组;二选一 → 三元。三者可以无限组合。

四、:style 对象语法:CSS 内联的 JS 形态

:style 接一个对象,属性名两种写法二选一:

vue 复制代码
<template>
  <!-- camelCase 写法:fontSize(推荐) -->
  <p :style="{ fontSize: size + 'px', color: textColor }">camelCase</p>

  <!-- kebab-case 写法:'font-size',必须加引号 -->
  <p :style="{ 'font-size': size + 'px', 'font-weight': 'bold' }">kebab-case</p>
</template>

<script setup>
import { ref } from 'vue'
const size = ref(20)
const textColor = ref('#42b983')
</script>

细节:fontSize 不用引号(JS 标识符合法);'font-size' 必须引号(有横线)。值需要单位就手动拼字符串。

五、:style 数组与自动前缀

多段样式来源不同时用数组合并:

vue 复制代码
<template>
  <p :style="[baseStyle, overrideStyle]">数组合并样式</p>
</template>

<script setup>
import { ref } from 'vue'

const baseStyle = ref({ fontSize: '18px', color: '#333' })
const overrideStyle = ref({ color: '#e74c3c' })  // 同名属性后者覆盖
</script>

另外,需要浏览器前缀的属性(transform 等)Vue 会自动补全(如 -webkit-transform),不用手写。

六、综合实战:Tab 高亮 + 状态标签

最常见的两个业务样式场景:

vue 复制代码
<template>
  <!-- Tab 高亮:对象语法 + v-for(016 篇知识联动) -->
  <div class="tabs">
    <button
      v-for="tab in tabs"
      :key="tab.id"
      :class="{ active: currentTab === tab.id }"
      @click="currentTab = tab.id"
    >
      {{ tab.name }}
    </button>
  </div>

  <!-- 状态标签:三元表达式配色 -->
  <ul>
    <li v-for="order in orders" :key="order.id">
      {{ order.name }}
      <span :class="['tag', order.status === 'paid' ? 'green' : 'gray']">
        {{ order.status === 'paid' ? '已支付' : '待支付' }}
      </span>
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'

const currentTab = ref(1)
const tabs = [
  { id: 1, name: '商品' },
  { id: 2, name: '评价' },
  { id: 3, name: '详情' }
]

const orders = ref([
  { id: 1, name: '订单A', status: 'paid' },
  { id: 2, name: '订单B', status: 'unpaid' }
])
</script>

<style scoped>
.tabs button { margin-right: 8px; }
.active { background: #42b983; color: #fff; }
.tag { padding: 2px 8px; border-radius: 4px; font-size: 12px; }
.green { background: #e1f3d8; color: #529b2e; }
.gray { background: #f4f4f5; color: #909399; }
</style>

两个模式直接抄进项目:currentTab === tab.id 配对象语法做 Tab 高亮;['tag', 条件 ? 'a' : 'b'] 数组嵌三元做状态标签。

【截图位置:Tab 切换高亮与订单状态标签的运行效果】

七、踩坑记录

  1. 对象语法类名带特殊字符要引号 :{ 'mt-10': isShow } 这种带横线的类名必须加引号
  2. :style 忘写单位 :{ fontSize: 20 } 无效(部分属性可以,但 font-size 不行),写 '20px' 或 size + 'px'
  3. kebab-case 属性没加引号 :{ font-size: '12px' } 直接语法错误,JS 对象里横线属性必须引号
  4. :class 里用了不存在的类:不报错但也不生效,先确认 scoped 样式里真的定义了这个类
  5. 重要样式用内联 :style:内联优先级高但难维护,频繁复用的样式写进 class,:style 只管"高度动态"的那几个值

八、今日小结

  • :class 三板斧:对象管开关、数组管组合、三元管二选一
  • 静态 class 与动态 :class 自动合并共存
  • :style 对象两种键名:fontSize(免引号)与 'font-size'(必须引号);数组合并时后者覆盖前者
  • 经典模式:Tab 高亮、状态标签配色,直接复用

下篇预告

指令篇最后一课:把前面全部知识(v-model 修饰符、computed 校验、:class 配色、v-if 提示)合体,从零写一个注册页联动校验------纯 Vue3 不用 UI 库,做完这篇你就能独立写表单了。

相关推荐
inksci3 分钟前
在线编辑表格,功能强大,json互转
前端·javascript·html
咩咩啃树皮14 分钟前
JavaScript 中 this 指向为什么总在变?
开发语言·前端·javascript
彭亚川Allen1 小时前
从零手搓 RAG 之 Embedding 技术
前端·后端·面试
OpenTiny社区1 小时前
GenUI SDK v1.4.0 的 React 渲染器到底做对了什么?
前端·github·ai编程
ss2731 小时前
AI时代首先数据库-PostgreSQL实战笔记 27 PostgreSQL数据写入与读取流程解析
数据库·笔记·postgresql
星光开发者1 小时前
基于springboot智慧草场牛羊管理系统-计算机毕设【课程设计】50360
vue.js·spring boot·后端·mysql·php·课程设计·express
jerrywus1 小时前
chrome-devtools-mcp 总弹授权、抢标签页?我是这样一步步配好的
前端·agent·mcp
橘猫走江湖1 小时前
Vue 3 虚拟 DOM:作用、触发机制,以及怎样变成页面上的真实节点
前端·vue.js·dom
weixin_BYSJ19871 小时前
电竞先锋网站---附源码02032
java·vue.js·spring boot·python·django·tomcat·php
深圳老胡2 小时前
压力检测空吸功能硬件方案全解析:主流压力传感器品牌与实现路径
笔记·单片机·代码规范