您好,登錄后才能下訂單哦!
這篇“vue自定義指令使用的方法是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“vue自定義指令使用的方法是什么”文章吧。
除了 Vue 內置的一系列指令 (比如 v-model
或 v-show
) 之外,Vue 還允許你注冊自定義的指令 (Custom Directives)。
兩種在 Vue 中重用代碼的方式:組件和組合式函數。組件是主要的構建模塊,而組合式函數則側重于有狀態的邏輯。另一方面,自定義指令主要是為了重用涉及普通元素的底層 DOM 訪問的邏輯。
一個自定義指令由一個包含類似組件生命周期鉤子的對象來定義。鉤子函數會接收到指令所綁定元素作為其參數。
Vue 自定義指令有全局注冊和局部注冊兩種方式。
先來看看注冊全局指令的方式,通過 Vue.directive( id, [definition] )方式注冊全局指令。然后在入口文件中進行 Vue.use()調用。
批量注冊指令,新建 src/directives/index.js 文件:
import fitColumns from './fit-columns' import enterToInput from './enter-to-input' import resizeHeight from './resize-height' import resizeWidth from './resize-width' import inputFilter from './input-filter' import copy from './copy' import longpress from './longpress' import clickOutside from './click-outside' import emoji from './emoji' const directives = { fitColumns, enterToInput, resizeHeight, resizeWidth, inputFilter, copy, longpress, clickOutside, emoji } export default { install(Vue) { Object.keys(directives).forEach((key) => { Vue.directive(key, directives[key]) }) } }
在 main.js 引入并調用:
// ..... import Directives from '@/directives' Vue.use(Directives) //.....
接下來就要開發具體的自定義指令了,那么開發的要領,以及一些開發技術點還是要先贅述一遍。
Vue2版本: 一個指令定義對象可以提供如下幾個鉤子函數 (均為可選):
bind
:只調用一次,指令第一次綁定到元素時調用。在這里可以進行一次性的初始化設置。
inserted
:被綁定元素插入父節點時調用 (僅保證父節點存在,但不一定已被插入文檔中)。
update
:所在組件的 VNode 更新時調用,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新。
componentUpdated
:指令所在組件的 VNode 及其子 VNode 全部更新后調用。
unbind
:只調用一次,指令與元素解綁時調用。
指令鉤子函數會被傳入以下參數:
el
:指令所綁定的元素,可以用來直接操作 DOM。
binding
:一個對象,包含以下 property:
name
:指令名,不包括 v-
前綴。
value
:指令的綁定值,例如:v-my-directive="1 + 1"
中,綁定值為 2
。
oldValue
:指令綁定的前一個值,僅在 update
和 componentUpdated
鉤子中可用。無論值是否改變都可用。
expression
:字符串形式的指令表達式。例如 v-my-directive="1 + 1"
中,表達式為 "1 + 1"
。
arg
:傳給指令的參數,可選。例如 v-my-directive:foo
中,參數為 "foo"
。
modifiers
:一個包含修飾符的對象。例如:v-my-directive.foo.bar
中,修飾符對象為 { foo: true, bar: true }
。
vnode
:Vue 編譯生成的虛擬節點。移步 VNode API 來了解更多詳情。
oldVnode
:上一個虛擬節點,僅在 update
和 componentUpdated
鉤子中可用。
Tips
:除了el
之外,其它參數都應該是只讀的,切勿進行修改。如果需要在鉤子之間共享數據,建議通過元素的dataset
來進行。
Vue3版本:有稍微變化,由于本文主要說的都是 Vue2 版本的(也是手上很多 vue2 版本的老項目在維護)
以下都是我在項目中用到的自定義指令,特此分享出來,供大家參考。同時也不敢保證 100% 無bug,如果在您的使用場景中如有 bug,還望留言批評指導。
1、click-outside.js
場景:clickOutside 自定義指令可以應用于需要在點擊元素外部時觸發某些操作的場景,例如:
點擊外部關閉彈窗:當用戶點擊彈窗外部時,需要關閉彈窗并執行一些操作,例如清空輸入框、重置表單等。
點擊外部隱藏下拉菜單:當用戶點擊下拉菜單外部時,需要隱藏下拉菜單并執行一些操作,例如清空搜索框、重置篩選條件等。
點擊外部取消選中狀態:當用戶點擊選中元素外部時,需要取消選中狀態并執行一些操作,例如清空選中項、重置狀態等。
總之,clickOutside 自定義指令可以幫助我們實現一些常見的交互需求,提升用戶體驗和操作效率。
const clickOutside = { bind: function(el, binding, vnode) { el.clickOutsideEvent = function(event) { if (!(el === event.target || el.contains(event.target))) { vnode.context[binding.expression](event) } } document.body.addEventListener('click', el.clickOutsideEvent) }, unbind: function(el) { document.body.removeEventListener('click', el.clickOutsideEvent) } } export default clickOutside
2、copy.js
場景: copy 自定義指令可以應用于需要實現一鍵復制文本內容的場景,例如:
復制分享鏈接:當用戶點擊分享按鈕時,需要將當前頁面的分享鏈接復制到剪貼板中,方便用戶分享給其他人。
復制優惠碼:當用戶點擊領取優惠券按鈕時,需要將優惠碼復制到剪貼板中,方便用戶在購物時使用。
復制代碼片段:當用戶需要復制代碼片段時,可以通過點擊復制按鈕,將代碼片段復制到剪貼板中,方便用戶在編輯器中粘貼使用。
總之,copy 自定義指令可以幫助我們實現一些常見的復制操作,提升用戶體驗和操作效率。
const copy = { bind: function(el, binding) { el.addEventListener('click', function() { const textToCopy = binding.value const input = document.createElement('input') input.setAttribute('value', textToCopy) document.body.appendChild(input) input.select() document.execCommand('copy') document.body.removeChild(input) }) } } export default copy
3、emoji.js
場景: emoji 自定義指令可以應用于需要在輸入框中插入表情符號的場景,例如:
發送表情消息:當用戶在聊天應用中發送消息時,可以通過點擊表情按鈕,在輸入框中插入表情符號,豐富聊天內容。
評論點贊:當用戶在社交應用中對評論進行點贊時,可以通過點擊點贊按鈕,在評論框中插入點贊表情符號,表達自己的情感。
表情搜索:當用戶需要在輸入框中插入特定的表情符號時,可以通過輸入表情名稱或關鍵字,篩選出符合條件的表情符號,方便用戶選擇使用。
總之,emoji 自定義指令可以幫助我們實現在輸入框中插入表情符號的功能,提升用戶體驗和操作效率。
// 在指令的inserted鉤子函數中,定義一個正則表達式,用來匹配表情及特殊字符。 // 在指令的update鉤子函數中,判斷輸入框的值是否發生變化,如果變化了,則使用正則表達式來過濾輸入框的值。 // 在指令的unbind鉤子函數中,清除事件監聽器,避免內存泄漏。 const emoji = { inserted: function(el) { el.addEventListener('input', function() { const reg = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]|[\u200D\uFE0F\uFE00-\uFE0F]/g el.value = el.value.replace(reg, '') }) }, update: function(el) { const reg = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]|[\u200D\uFE0F\uFE00-\uFE0F]/g el.value = el.value.replace(reg, '') }, unbind: function(el) { el.removeEventListener('input') } } export default emoji
4、enter-to-input.js
場景: enter-to-input 自定義指令可以應用于需要在輸入框中按下回車鍵時觸發特定操作的場景,例如:
搜索框回車搜索:當用戶在搜索框中輸入關鍵字后,按下回車鍵時,可以觸發搜索操作,快速獲取搜索結果。
發送消息:當用戶在聊天應用中輸入完消息后,按下回車鍵時,可以觸發發送消息操作,方便快捷地發送消息。
提交表單:當用戶在表單中填寫完信息后,按下回車鍵時,可以觸發提交表單操作,快速提交表單信息。
總之,enter-to-input 自定義指令可以幫助我們實現在輸入框中按下回車鍵時觸發特定操作的功能,提升用戶體驗和操作效率。
const enterToInput = { inserted: function(el) { let inputs = el.querySelectorAll('input') // 綁定回寫事件 for (var i = 0; i < inputs.length; i++) { inputs[i].setAttribute('keyFocusIndex', i) inputs[i].addEventListener('keyup', ev => { if (ev.keyCode === 13) { const targetTo = ev.srcElement.getAttribute('keyFocusTo') if (targetTo) { this.$refs[targetTo].$el.focus() } else { var attrIndex = ev.srcElement.getAttribute('keyFocusIndex') var ctlI = parseInt(attrIndex) inputs = el.querySelectorAll('input') if (ctlI < inputs.length - 1) inputs[ctlI + 1].focus() } } }) } } } export default enterToInput
5、fit-columns.js
場景: fit-columns 自定義指令可以應用于需要自動調整表格列寬的場景,例如:
數據展示:當我們需要在頁面上展示大量數據時,可以使用表格進行展示,通過 fit-columns 自定義指令可以自動調整表格列寬,使得數據更加清晰易讀。
數據編輯:當我們需要在頁面上編輯表格數據時,可以使用表格進行編輯,通過 fit-columns 自定義指令可以自動調整表格列寬,使得編輯更加方便快捷。
數據導出:當我們需要將表格數據導出為 Excel 或 CSV 格式時,可以使用表格進行導出,通過 fit-columns 自定義指令可以自動調整表格列寬,使得導出的數據更加美觀。
總之,fit-columns 自定義指令可以幫助我們實現自動調整表格列寬的功能,提升數據展示、編輯和導出的效率和美觀度。
import './fit-columns.css' function adjustColumnWidth(table, padding = 0) { const colgroup = table.querySelector('colgroup') const colDefs = [...colgroup.querySelectorAll('col')] colDefs.forEach((col) => { const clsName = col.getAttribute('name') const clsWidth = col.getAttribute('width') if (clsWidth < 200) return const cells = [ ...table.querySelectorAll(`td.${clsName}`), ...table.querySelectorAll(`th.${clsName}`) ] if (cells[0] && cells[0].classList && cells[0].classList.contains && cells[0].classList.contains('leave-alone')) { return } const widthList = cells.map((el) => { return el.querySelector('.cell') && el.querySelector('.cell').scrollWidth || 0 }) const max = Math.max(...widthList) table.querySelectorAll(`col[name=${clsName}]`).forEach((el) => { // console.log(222, max + padding) el.setAttribute('width', max + padding > 500 ? 500 : max + padding) }) }) } const fitColumns = { update() { }, bind() { }, inserted(el, binding) { setTimeout(() => { adjustColumnWidth(el, binding.value) }, 300) }, componentUpdated(el, binding) { el.classList.add('r-table') setTimeout(() => { adjustColumnWidth(el, binding.value) }, 300) }, unbind() { } } export default fitColumns
5.1、fit-columns.css
.el-table.r-table .cell { display: inline-block; /* white-space: nowrap; */ width: auto; overflow: auto; } .el-table.r-table .el-table__body-wrapper { overflow-x: auto; }
6、input-filter.js
場景: input-filter 自定義指令可以應用于需要對用戶輸入進行過濾和限制的場景,例如:
輸入框過濾:當我們需要在輸入框中輸入特定類型的數據時,可以使用 input-filter 自定義指令對用戶輸入進行過濾和限制,例如只允許輸入數字、字母或特定字符等。
表單驗證:當我們需要對表單中的數據進行驗證時,可以使用 input-filter 自定義指令對用戶輸入進行過濾和限制,例如驗證手機號碼、郵箱地址等。
密碼輸入:當我們需要用戶輸入密碼時,可以使用 input-filter 自定義指令對用戶輸入進行過濾和限制,例如限制密碼長度、只允許輸入特定字符等。
總之,input-filter 自定義指令可以幫助我們實現對用戶輸入進行過濾和限制的功能,提升表單驗證和數據輸入的效率和準確性。
const findEle = (parent, type) => { return parent.tagName.toLowerCase() === type ? parent : parent.querySelector(type) } const trigger = (el, type) => { const e = document.createEvent('HTMLEvents') e.initEvent(type, true, true) el.dispatchEvent(e) } const inputFilter = { mounted(el, binding, vnode) { const bindV = binding.value const regRule = bindV.regRule ? bindV.regRule : /[^\a-zA-Z0-9\u4E00-\u9FA5]+$/g const length = bindV.length ? bindV.length : 30 const $inp = findEle(el, 'input') el.$inp = $inp $inp.handle = () => { const val = $inp.value $inp.value = val.replace(regRule, '').substring(0, length) trigger($inp, 'input') } $inp.addEventListener('keyup', $inp.handle) }, unmounted(el) { el.$inp.removeEventListener('keyup', el.$inp.handle) } } export default inputFilter
7、longpress.js
場景: longpress 自定義指令可以應用于需要長按觸發事件的場景,例如:
按鈕長按:當我們需要在按鈕上長按觸發某個事件時,可以使用 longpress 自定義指令,例如長按刪除按鈕可以刪除某個元素。 圖片預覽:當我們需要在圖片上長按觸發預覽事件時,可以使用 longpress 自定義指令,例如長按圖片可以彈出預覽框。 列表操作:當我們需要在列表中長按觸發某個操作時,可以使用 longpress 自定義指令,例如長按列表項可以彈出操作菜單。
總之,longpress 自定義指令可以幫助我們實現長按觸發事件的功能,提升用戶體驗和操作效率。
// 在 bind 鉤子函數中綁定了 mousedown、touchstart、click、mouseout、touchend 和 touchcancel 事件。 // 當用戶按下鼠標或觸摸屏時,我們會啟動一個定時器,如果在指定的時間內沒有松開鼠標或手指,則執行指令的回調函數。 // 如果用戶在指定的時間內松開了鼠標或手指,則取消定時器。 const longpress = { bind: function(el, binding) { let pressTimer = null const duration = binding.value || 500 // 默認長按時間為 500ms const start = function(event) { if (event.type === 'click' && event.button !== 0) { return } if (pressTimer === null) { pressTimer = setTimeout(() => { handler() }, duration) } } const cancel = function() { if (pressTimer !== null) { clearTimeout(pressTimer) pressTimer = null } } const handler = function() { binding.value() } el.addEventListener('mousedown', start) el.addEventListener('touchstart', start) el.addEventListener('click', cancel) el.addEventListener('mouseout', cancel) el.addEventListener('touchend', cancel) el.addEventListener('touchcancel', cancel) } } export default longpress
8、resize-height.js
場景: resize-height 自定義指令可以應用于需要根據內容自適應高度的場景,例如:
文本框自適應高度:當我們需要在文本框中輸入多行文本時,可以使用 resize-height 自定義指令,使文本框根據內容自適應高度,避免內容溢出或留白。
評論框自適應高度:當我們需要在評論框中輸入多行文本時,可以使用 resize-height 自定義指令,使評論框根據內容自適應高度,提升用戶體驗和操作效率。
動態列表自適應高度:當我們需要在動態列表中展示不同高度的內容時,可以使用 resize-height 自定義指令,使列表項根據內容自適應高度,避免內容溢出或留白。
總之,resize-height 自定義指令可以幫助我們實現根據內容自適應高度的功能,提升用戶體驗和界面美觀度。
const resizeHeight = { // 綁定時調用 bind(el, binding) { let height = '' function isResize() { // 可根據需求,調整內部代碼,利用 binding.value 返回即可 const style = document.defaultView.getComputedStyle(el) if (height !== style.height) { // 此處關鍵代碼,通過此處代碼將數據進行返回,從而做到自適應 binding.value({ height: style.height }) } height = style.height } // 設置調用函數的延時,間隔過短會消耗過多資源 el.__vueSetInterval__ = setInterval(isResize, 100) }, unbind(el) { clearInterval(el.__vueSetInterval__) } } export default resizeHeight
9、resize-width.js
場景: resize-width 自定義指令可以應用于需要根據內容自適應寬度的場景,例如:
圖片自適應寬度:當我們需要在頁面中展示不同寬度的圖片時,可以使用 resize-width 自定義指令,使圖片根據內容自適應寬度,避免圖片變形或溢出。
表格自適應寬度:當我們需要在頁面中展示不同寬度的表格時,可以使用 resize-width 自定義指令,使表格根據內容自適應寬度,避免表格變形或溢出。
動態列表自適應寬度:當我們需要在動態列表中展示不同寬度的內容時,可以使用 resize-width 自定義指令,使列表項根據內容自適應寬度,避免內容變形或溢出。
總之,resize-width 自定義指令可以幫助我們實現根據內容自適應寬度的功能,提升用戶體驗和界面美觀度。
const resizeWidth = { // 綁定時調用 bind(el, binding) { let width = '' function isResize() { // 可根據需求,調整內部代碼,利用binding.value返回即可 const style = document.defaultView.getComputedStyle(el) if (width !== style.width) { // 此處關鍵代碼,通過此處代碼將數據進行返回,從而做到自適應 binding.value({ width: style.width }) } width = style.width } // 設置調用函數的延時,間隔過短會消耗過多資源 el.__vueSetInterval__ = setInterval(isResize, 100) }, unbind(el) { clearInterval(el.__vueSetInterval__) } } export default resizeWidth
Vue2 自定義指令的原理可以簡單概括為:通過 Vue.directive() 方法注冊指令,當指令被綁定到元素上時,Vue 會創建一個指令實例,該實例包含指令的鉤子函數和其他配置項,然后根據指令的生命周期鉤子函數,依次執行相應的邏輯,例如 bind、inserted、update、componentUpdated 和 unbind 等。
具體來說,Vue2 自定義指令的原理包括以下幾個方面:
注冊指令:通過 Vue.directive() 方法注冊指令,該方法接收兩個參數,第一個參數是指令名稱,第二個參數是一個對象,包含指令的鉤子函數和其他配置項。
創建指令實例:當指令被綁定到元素上時,Vue 會創建一個指令實例,該實例包含指令的鉤子函數和其他配置項。
指令鉤子函數執行:當指令實例被創建后,Vue 會根據指令的生命周期鉤子函數,依次執行相應的邏輯,例如 bind、inserted、update、componentUpdated 和 unbind 等。
操作 DOM:在指令鉤子函數中,我們可以通過 el 參數獲取到指令綁定的元素,然后對元素進行操作,例如修改元素的樣式、屬性或內容等。
注銷指令:當指令被解綁或元素被銷毀時,Vue 會調用指令的 unbind 鉤子函數,我們可以在該函數中清除指令創建的事件監聽器、定時器或其他資源。
總之,Vue2 自定義指令的原理是通過注冊指令、創建指令實例、執行指令鉤子函數、操作 DOM 和注銷指令等步驟來實現的,通過這些步驟,我們可以實現各種自定義指令的功能。
以上就是關于“vue自定義指令使用的方法是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。