一、指令修飾符
Vue 的指令修飾符(Directive Modifiers)是 Vue 模板語法中的重要特性,它們以半角句號 .
開頭,用于對指令的綁定行為進行特殊處理
修飾符作用如下:
- 簡化事件處理(如阻止默認行為、停止冒泡)
- 精準控制輸入(如自動格式化表單值)
- 優化性能(如延遲數據同步)
- 增強交互(如精確控制按鍵觸發)
類型 | 常用修飾符 |
---|---|
事件 | .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:keyup
或 v-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>
代碼解析:
- 參數處理 (
:skyblue
)- 通過
binding.arg
獲取指令參數 - 直接作為背景顏色使用(支持顏色名稱、十六進制、RGB等格式)
- 示例中
:skyblue
會設置background-color: skyblue
- 通過
- 修飾符處理 (
.bold.italic
)- 通過
binding.modifiers
對象檢查修飾符 - 支持多個修飾符組合使用:
.bold
→font-weight: bold
.italic
→font-style: italic
.underline
→text-decoration: underline
- 通過
- 值處理 (
="'#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
——> valuev-model
寫在select上,關聯是選中option的value
-
單選框
input:radio
——> value- 給單選框添加value屬性,
v-model
收集選中單選框的value
- 給單選框添加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. 常見應用場景
- 狀態反饋:表單驗證錯誤時高亮輸入框
- 主題切換:動態切換暗黑模式/明亮模式
- 動畫控制:通過類名觸發 CSS 動畫
- 響應式布局:根據屏幕尺寸調整樣式
5. 注意事項
- CSS 優先級:
:style
的樣式優先級高于外部 CSS - 性能優化:避免頻繁修改大量樣式(建議用 CSS 類替代)
- 兼容性:某些 CSS 屬性需注意瀏覽器兼容性(如
position: sticky
)