【Vue #3】指令补充&样式绑定

发布于:2025-04-13 ⋅ 阅读:(77) ⋅ 点赞:(0)

一、指令修饰符

Vue 的指令修饰符(Directive Modifiers)是 Vue 模板语法中的重要特性,它们以半角句号 . 开头,用于对指令的绑定行为进行特殊处理

修饰符作用如下:

  1. 简化事件处理(如阻止默认行为、停止冒泡)
  2. 精准控制输入(如自动格式化表单值)
  3. 优化性能(如延迟数据同步)
  4. 增强交互(如精确控制按键触发)
类型 常用修饰符
事件 .stop .prevent .capture .self .once .passive
键盘 .enter .tab .esc .space .up .down .left .right .ctrl .alt .shift .meta
鼠标 .left .right .middle
表单 .lazy .number .trim
系统修饰键 .exact

1. 事件修饰符(Event Modifiers)

用于 v-on 指令(简写为 @),处理 DOM 事件:

  • .stop:阻止事件冒泡
  • .prevent:阻止默认行为(比如:点击表单提交,表单不会刷新页面)
  • .capture:使用捕获模式(父级先触发)
  • .self:仅当事件源是当前元素时触发(子元素点击就不会触发)
  • .once:事件只触发一次
  • .passive:提升滚动性能(常用于移动端)

注意:修饰符可串联

<a @click.stop.prevent="doSomething">同时阻止冒泡和默认行为</a>

代码示例如下:

<script setup>
import { ref } from 'vue'
const onPClick = () => {
  console.log('onPClick')
}
const onDivClick = () => {
  console.log('onDivClick')
}
</script>
<template>
  <div @click="onDivClick">
    <a href="https://www.baidu.com/">百度一下</a>
    <p></p>
    <!-- .prevent: 阻止默认行为 -->
    <a href="https://www.baidu.com/" @click.prevent>百度一下</a>
    <!-- .stop: 阻止冒泡, 同名事件不会向上传递 -->
    <p @click.stop="onPClick">I miss You</p>
    <!-- 修饰符的链式调用: 表名两个同时阻止 -->
    <a href="https://www.baidu.com/" @click.stop.prevent>百度一下</a>
  </div>
</template>

2. 按键修饰符(Key Modifiers)

用于 v-on:keyupv-on:keydown,监听特定按键:

① 按键别名

<input @keyup.enter="submit"> 回车键触发
<input @keyup.esc="close"> ESC 键触发
<input @keyup.delete="deleteItem"> 删除键触发

② 系统修饰键

<input @keyup.ctrl.enter="ctrlEnter"> Ctrl + Enter
<div @click.ctrl.exact="ctrlOnlyClick">仅按 Ctrl 时点击触发</div>

3. 鼠标修饰符(Mouse Modifiers)

控制鼠标按钮触发事件:

  • .left:左键点击
  • .right:右键点击
  • .middle:中键点击
<button @click.right="showContextMenu">右键触发菜单</button>

4. 表单修饰符(Key Modifiers)

用于 v-model 指令,优化表单处理:

  • .lazy:失去焦点时同步数据,而不是输入时同步数据。将 input 事件改为 change 事件后同步
  • .number:自动将输入转为数字类型(parseFloat() 转数字)
  • trim:自动去除首尾空格
<script setup>
import { reactive } from 'vue'
const goods = reactive({
  name: '', price: ''
})
</script>
<template>
  <!-- .lazy -->
  名称: <input type="text" v-model.lazy="goods.name" /> <br /> <br />
  <!-- .trim -->
  名称: <input type="text" v-model.trim="goods.name" /> <br /> <br />
  <!-- .number -->
  价格: <input type="text" v-model.number="goods.price" /> <br /> <br />

</template>

5. 自定义修饰符

在自定义指令中定义自己的修饰符:

<script setup>
const vColor = {
  mounted(el, binding) {
    // 1. 处理参数(用于背景色)
    if (binding.arg) {
      el.style.backgroundColor = binding.arg
    }

    // 2. 处理修饰符(可扩展多个样式)
    if (binding.modifiers.bold) {
      el.style.fontWeight = 'bold'
    }
    if (binding.modifiers.italic) {
      el.style.fontStyle = 'italic'
    }
    if (binding.modifiers.underline) {
      el.style.textDecoration = 'underline'
    }

    // 3. 处理值(用于文字颜色)
    if (binding.value) {
      el.style.color = binding.value
    }

    // 4. 添加默认内边距提升显示效果
    el.style.padding = '0.5rem'
    el.style.borderRadius = '4px'
  }
}

// 注册局部指令
const directives = { vColor }
</script>

<template>
  <!-- 改进后的使用示例 -->
  <p v-color:skyblue.bold.italic="'#333'">天蓝背景、加粗斜体、深灰文字</p>
  <p v-color:#ffd700.underline="'#2c3e50'">金色背景、下划线、深蓝文字</p>
</template>

代码解析

  1. 参数处理 (:skyblue)
    • 通过 binding.arg 获取指令参数
    • 直接作为背景颜色使用(支持颜色名称、十六进制、RGB等格式)
    • 示例中 :skyblue 会设置 background-color: skyblue
  2. 修饰符处理 (.bold.italic)
    • 通过 binding.modifiers 对象检查修饰符
    • 支持多个修饰符组合使用:
      • .boldfont-weight: bold
      • .italicfont-style: italic
      • .underlinetext-decoration: underline
  3. 值处理 (="'#333'")
    • 通过 binding.value 获取指令值
    • 用于设置文字颜色
    • 注意在模板中需要使用引号包裹字符串值

修饰符机制说明

  • Vue 会自动解析指令后的点号标识符为修饰符
  • 例如 v-color.bold.italic 会生成:
binding.modifiers = { 
  bold: true,
  italic: true 
}

6. 修饰符最佳实践

① 链式顺序影响结果

<!-- 先阻止冒泡,再阻止默认行为 -->
<a @click.stop.prevent></a>

<!-- 先阻止默认行为,再判断是否自身触发 -->
<a @click.prevent.self></a>

合理使用系统修饰键
.exact 精确控制组合按键:

<input @keyup.ctrl.exact="onlyCtrl"> 仅按 Ctrl 时触发

③ 版本兼容性

  • Vue 3 默认启用 passive 提升滚动性能
  • Vue 3 废弃了 Vue 2 的按键码(如 .13

二、v-model 用在其他表单元素

常见的表单元素都可以用 v-model绑定关联,作用是可以快速 获取 或 设置 表单元素的值

它会根据 控件类型 自动选取 正确的属性 来更新元素

  • 输入框 input:text ——> value

  • 文本域 textarea ——> value

  • 下拉菜单 select ——> value

    • v-model 写在select上,关联是选中option的 value
  • 单选框 input:radio ——> value

    • 给单选框添加value属性,v-model 收集选中单选框的value
  • 复选框 input:checkbox ——> checked / value

    • 一个复选框:v-model 绑定 布尔值,关联 checked 属性
    • 一组复选框:v-model 绑定 数组,关联 value 属性,给复选框 手动添加 value
<script setup>
import { ref } from 'vue'
const intro = ref('') // 介绍
const city = ref('SH') // 城市
const blood = ref('ab') // 血型
const isAgree = ref(false) // 同意协议
const hobby = ref(['ZQ', 'PB']) // 爱好
</script>
<template>
  <!-- 1. 文本域 -->
  <textarea v-model="intro" cols="30" rows="4" placeholder="请输入自我介绍"></textarea> <br /><br />
  <!-- 2. 下拉菜单 -->
  <select v-model="city">
    <option value="BJ">北京</option>
    <option value="CS">长沙</option>
    <option value="SH">上海</option>
  </select>
  <br /> <br />
  <!-- 3. 单选框: 多个当中只能选一个 -->
  <input type="radio" value="a" v-model="blood" />A
  <input type="radio" value="b" v-model="blood" />B
  <input type="radio" value="ab" v-model="blood" />AB
  <br /><br />
  <!-- 4. 复选框  -->
  <input type="checkbox" v-model="isAgree" />是否同意用户协议

  <br />
  <br />
  <input v-model="hobby" type="checkbox" value="LQ" />篮球
  <input v-model="hobby" type="checkbox" value="ZQ" />足球
  <input v-model="hobby" type="checkbox" value="PB" />跑步
</template>

三、样式绑定

🐇 为了方便开发者进行样式控制,Vue 扩展了 v-bind 的语法,可以针对 class 类名 和 style 行内样式两个属性进行控制,进而通过数据控制元素的样式

1. Class 类名绑定

用于动态添加或移除 CSS 类名,支持多种语法格式。

:class = "三元表达式/对象"
1.1 对象语法

通过对象动态切换类名(键为类名,值为布尔值)

当class动态绑定的是对象时,键就是类名,值就是布尔值,如果值是true,就添加这个类,否则删除这个类

<p class="box":class="{ 类名1:布尔值1,类名2:布尔值2 }"></p>
1.2 数组语法

应用多个类名(可混合静态和动态类):

<div :class="[类名1, 类名2, {条件}]"></div>
1.3 三元表达式

语法如下:

<p :class="条件 ? '类名1' : '类名2'"></p>
1.4 与静态 class 共存

静态class与动态class共存可以共存,二者会合并

<p class="item" :class="条件 ?'类名1':'类名2'"></p〉

代码示例如下:

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

const isActive = ref(true)
const errorClass = ref('text-danger')  // 新增数组绑定用的类名
const fontSize = ref(20)              // 内联样式用字体大小
</script>

<template>
  <!-- 1. 对象绑定 -->
  <p :class="{ active: isActive }">Active1</p>
  
  <!-- 2. 数组绑定 -->
  <p :class="['base-class', errorClass, { active: isActive }]">Active3</p>

  <!-- 3. 三元绑定 -->
  <p :class="isActive ? 'active' : ''">Active2</p>

  <!-- 4. 动静态 class -->
  <p class="base-class" :class="{ active: isActive }">Active4</p>

<style>
.active {
  color: red;
}
.text-danger {
  text-decoration: line-through;
}
.base-class {
  font-size: 20px;
}
</style>

2. 内联样式绑定

通过 :style 动态设置行内样式,支持对象或数组语法

基本语法如下:

:style="{属性名1: 表达式1, 属性名2: 表达式2, ...}"
2.1 对象语法

直接绑定样式对象(推荐驼峰式写法):

<div style="color: red; font-size: 20px;"></div>
2.2 数组语法

合并多个样式对象

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

<script>
// 可选:在 script 中定义样式对象
export default {
  data() {
    return {
      baseStyles: { color: 'blue' },
      overridingStyles: { fontSize: '30px' }
    }
  }
}
</script>
2.3 自动前缀

Vue 会自动为需要浏览器前缀的 CSS 属性添加前缀(如 transform

代码示例如下

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

const isActive = ref(true)
const errorClass = ref('text-danger')  // 新增数组绑定用的类名
const fontSize = ref(20)              // 内联样式用字体大小

// 字体颜色
const colorStr = ref('red')

// 响应式样式对象
const styleObj = reactive({
  color: 'green',
  background: 'yellow'
})
</script>

<template>
  <!-- 1. 内联样式绑定 -->
  <div :style="{
    color: isActive ? 'red' : 'gray',
    fontSize: fontSize + 'px',
    'font-weight': 'bold'
  }">
    内联样式示例
  </div>
  <div>
    <p :style="{ color: colorStr }">Style1</p>
    <p :style="styleObj">Style2</p>
  </div>
  <!-- 3. 样式对象绑定(另一种写法) -->
  <div :style="styleObject">样式对象</div>
</template>

<script>
// 可选:在 script 中定义样式对象
export default {
  data() {
    return {
      styleObject: {
        backgroundColor: 'yellow',
        padding: '10px'
      }
    }
  }
}
</script>

3. 最佳实践

1. 使用计算属性优化

当样式逻辑复杂时,用计算属性返回样式对象

2. 绑定组件子元素的样式

在组件上使用 :class 时,类名会添加到组件的根元素(需组件设计支持)

3. CSS Modules 集成

在单文件组件中,通过 $style 使用模块化 CSS

<template>
  <div :class="$style.myClass">模块化样式</div>
</template>

<style module>
.myClass { color: red; }
</style>

4. 常见应用场景

  1. 状态反馈:表单验证错误时高亮输入框
  2. 主题切换:动态切换暗黑模式/明亮模式
  3. 动画控制:通过类名触发 CSS 动画
  4. 响应式布局:根据屏幕尺寸调整样式

5. 注意事项

  1. CSS 优先级:style 的样式优先级高于外部 CSS
  2. 性能优化:避免频繁修改大量样式(建议用 CSS 类替代)
  3. 兼容性:某些 CSS 属性需注意浏览器兼容性(如 position: sticky

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到