Vue內(nèi)置指令與自定義指令大全
一、Vue 內(nèi)置指令大全
1.v-bind:動(dòng)態(tài)綁定屬性
用于動(dòng)態(tài)綁定 HTML 屬性或組件 prop。
<!-- 綁定 class -->
<div v-bind:class="{ active: isActive }"></div>
<!-- 縮寫 -->
<img :src="imageURL" :alt="title">
<!-- 綁定對象 -->
<a v-bind="{ href, target, rel }">鏈接</a>? 支持所有 HTML 屬性和組件 prop。
2.v-model:雙向數(shù)據(jù)綁定
簡化表單元素與數(shù)據(jù)的同步。
<input v-model="message" placeholder="雙向綁定">
<p>輸入內(nèi)容:{{ message }}</p>
<!-- 修飾符 -->
<input v-model.trim="username" />
<input v-model.number="age" />
<input v-model.lazy="search" />?? v-model 是 :value + @input 的語法糖。
3.v-on:事件監(jiān)聽
綁定 DOM 事件。
<button v-on:click="handleClick">點(diǎn)擊</button> <!-- 縮寫 --> <button @click="save">保存</button> <!-- 修飾符 --> <form @submit.prevent="onSubmit"> <input @keyup.enter="search" /> <button @click.once="doOnce">只觸發(fā)一次</button>
? 常用修飾符:.prevent, .stop, .once, .self, .enter, .tab 等。
4.v-if/v-else/v-else-if:條件渲染
根據(jù)表達(dá)式真假?zèng)Q定是否渲染 DOM。
<div v-if="type === 'A'">類型 A</div> <div v-else-if="type === 'B'">類型 B</div> <div v-else>其他</div>
?? 與 v-show 區(qū)別:v-if 是“真正”渲染/銷毀,v-show 是 display: none 控制。
5.v-show:顯示/隱藏切換
通過 CSS 控制顯示狀態(tài)。
<div v-show="isVisible">我被 v-show 控制</div>
? 適用于頻繁切換的場景。
6.v-for:列表渲染
基于數(shù)組或?qū)ο箐秩玖斜怼?/p>
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.name }}
</li>
<!-- 遍歷對象 -->
<li v-for="(value, key) in user" :key="key">
{{ key }}: {{ value }}
</li>? 必須使用 :key 提升性能與穩(wěn)定性。
7.v-cloak:防止閃現(xiàn)
解決頁面加載時(shí) Vue 未初始化導(dǎo)致的 {{ message }} 閃現(xiàn)問題。
<style>
[v-cloak] { display: none; }
</style>
<div v-cloak>{{ message }}</div>? 配合 CSS 使用,Vue 實(shí)例掛載后自動(dòng)移除。
8.v-pre和v-once
v-pre:跳過該元素及其子元素的編譯過程。v-once:僅渲染一次,后續(xù)更新不重新渲染。
<span v-pre>{{ this will not be compiled }}</span>
<span v-once>{{ msg }}</span> <!-- msg 變化也不會(huì)更新 -->? 用于靜態(tài)內(nèi)容或性能優(yōu)化。
二、自定義指令:擴(kuò)展 Vue 能力
當(dāng)內(nèi)置指令無法滿足需求時(shí),我們可以創(chuàng)建自定義指令。
1. 注冊方式
全局注冊
// main.js
import { createApp } from 'vue'
const app = createApp({})
app.directive('focus', {
mounted(el) {
el.focus()
}
})局部注冊
<script>
export default {
directives: {
focus: {
mounted(el) {
el.focus()
}
}
}
}
</script>2. 鉤子函數(shù)(生命周期)
| 鉤子 | 觸發(fā)時(shí)機(jī) |
|---|---|
created | 指令綁定前 |
beforeMount | 元素掛載前 |
mounted | 元素插入父節(jié)點(diǎn)后(常用) |
beforeUpdate | 組件更新前 |
updated | 組件更新后 |
beforeUnmount | 元素卸載前 |
unmounted | 元素卸載后(清理事件監(jiān)聽) |
3. 鉤子函數(shù)參數(shù)
每個(gè)鉤子接收以下參數(shù):
app.directive('demo', {
mounted(el, binding, vnode, prevVnode) {
// el: 指令綁定的元素
// binding: 指令信息對象
// binding.value: 傳入的值
// binding.arg: 參數(shù),如 v-demo:arg
// binding.modifiers: 修飾符,如 v-demo.foo.bar
// vnode: 虛擬節(jié)點(diǎn)
// prevVnode: 上一個(gè)虛擬節(jié)點(diǎn)(更新時(shí))
}
})三、自定義指令實(shí)戰(zhàn)案例
案例 1:自動(dòng)聚焦(v-focus)
app.directive('focus', {
mounted(el) {
el.focus()
}
})<input v-focus placeholder="頁面加載后自動(dòng)聚焦">
案例 2:權(quán)限控制(v-permission)
// 假設(shè)用戶權(quán)限存儲(chǔ)在全局 store 或 config 中
const userPermissions = ['create', 'edit']
app.directive('permission', {
mounted(el, binding) {
const requiredPerm = binding.value
if (!userPermissions.includes(requiredPerm)) {
el.parentNode.removeChild(el) // 移除無權(quán)限的按鈕
// 或 el.style.display = 'none'
}
}
})<button v-permission="'create'">新建用戶</button> <button v-permission="'delete'">刪除用戶</button> <!-- 會(huì)被移除 -->
? 企業(yè)級(jí)應(yīng)用中常見需求。
案例 3:防重復(fù)點(diǎn)擊(v-debounce)
let timer = null
app.directive('debounce', {
mounted(el, binding) {
const delay = binding.value || 1000
el.addEventListener('click', () => {
if (timer) return
binding.instance[binding.arg] && binding.instance[binding.arg]()
timer = setTimeout(() => {
timer = null
}, delay)
})
}
})<template>
<button v-debounce:submit="1000">提交</button>
</template>
<script>
export default {
methods: {
submit() {
console.log('表單提交')
// 發(fā)送請求
}
}
}
</script>? 防止用戶多次點(diǎn)擊造成重復(fù)提交。
案例 4:圖片懶加載(v-lazy)
const imgObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target
img.src = img.dataset.src
imgObserver.unobserve(img)
}
})
})
app.directive('lazy', {
mounted(el, binding) {
el.dataset.src = binding.value
el.src = 'placeholder.jpg' // 占位圖
imgObserver.observe(el)
},
unmounted(el) {
imgObserver.unobserve(el)
}
})<img v-lazy="imageUrl" alt="懶加載圖片">
? 提升首屏加載性能。
四、Vue 3 Composition API 中的指令
在 setup() 中注冊局部指令:
<script>
import { ref } from 'vue'
export default {
setup() {
const vFocus = {
mounted: (el) => el.focus()
}
const count = ref(0)
return {
vFocus,
count
}
}
}
</script>
<template>
<input v-focus>
</template>五、最佳實(shí)踐與注意事項(xiàng)
? 推薦做法
- 優(yōu)先使用組件而非指令:指令應(yīng)專注于 DOM 操作。
- 復(fù)雜邏輯封裝為 composables:避免指令過于臃腫。
- 及時(shí)清理資源:在
unmounted中移除事件監(jiān)聽、定時(shí)器等。 - 命名語義化:如
v-permission,v-debounce-click。
? 避免
- 在指令中修改組件狀態(tài)(
binding.instance不穩(wěn)定) - 過度使用全局指令,造成命名污染
- 忽略響應(yīng)式更新(
updated鉤子)
六、總結(jié)
| 類型 | 指令 | 用途 |
|---|---|---|
| 內(nèi)置指令 | v-bind, v-model, v-on | 數(shù)據(jù)綁定與事件 |
v-if, v-show | 條件渲染 | |
v-for | 列表渲染 | |
v-cloak, v-pre | 編譯控制 | |
| 自定義指令 | v-focus, v-permission | 擴(kuò)展 DOM 能力 |
v-debounce, v-lazy | 復(fù)用交互邏輯 |
?? 核心思想:內(nèi)置指令解決通用問題,自定義指令解決特定場景的 DOM 操作。
七、結(jié)語
到此這篇關(guān)于Vue內(nèi)置指令與自定義指令的文章就介紹到這了,更多相關(guān)Vue內(nèi)置指令與自定義指令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談vue中$event理解和框架中在包含默認(rèn)值外傳參
這篇文章主要介紹了淺談vue中$event理解和框架中在包含默認(rèn)值外傳參,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
ElementUI如何修改el-cascader的默認(rèn)樣式
ElementUI 是一套u(yù)i組件庫,目前最新版本 react 和 vue 等主流框架都有支持。該庫默認(rèn)主題色是天藍(lán)色,若用于項(xiàng)目開發(fā),難免遇到要需求修改其默認(rèn)樣式的情況,這篇文章主要介紹了ElementUI如何修改el-cascader的默認(rèn)樣式,需要的朋友可以參考下2023-12-12
vue-cli項(xiàng)目使用vue-picture-preview圖片預(yù)覽組件方式
這篇文章主要介紹了vue-cli項(xiàng)目使用vue-picture-preview圖片預(yù)覽組件方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
Vue 動(dòng)態(tài)組件與 v-once 指令的實(shí)現(xiàn)
這篇文章主要介紹了Vue 動(dòng)態(tài)組件與 v-once 指令的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
vue-resource請求實(shí)現(xiàn)http登錄攔截或者路由攔截的方法
這篇文章主要介紹了vue-resource請求實(shí)現(xiàn)http登錄攔截或者路由攔截的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
vue使用better-scroll實(shí)現(xiàn)滑動(dòng)以及左右聯(lián)動(dòng)
這篇文章主要介紹了vue使用better-scroll實(shí)現(xiàn)滑動(dòng)以及左右聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
vue封裝一個(gè)右鍵菜單組件詳解(復(fù)制粘貼即可使用)
關(guān)于vue項(xiàng)目中會(huì)出現(xiàn)一些需求,就是右鍵菜單項(xiàng)的功能實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于vue封裝一個(gè)右鍵菜單組件(復(fù)制粘貼即可使用)的相關(guān)資料,需要的朋友可以參考下2022-12-12
vue實(shí)現(xiàn)路由跳轉(zhuǎn)動(dòng)態(tài)title標(biāo)題信息
這篇文章主要介紹了vue實(shí)現(xiàn)路由跳轉(zhuǎn)動(dòng)態(tài)title標(biāo)題信息,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06

