實際前端開發中,常用指令的封裝
- 全局指令處理步驟
- main.ts
- 指令目錄結構
- src/directives/index.ts
- 一、輸入框空格禁止指令
- 1、指令文件clearSpace.ts
- 2、指令使用
全局指令處理步驟
main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { setupGlobDirectives } from "@/directives";const app = createApp(App);
// 注冊全局指令
setupGlobDirectives(app);
app.mount("#app");
指令目錄結構
src/directives/index.ts
import type { App } from "vue";
import { setupNoSpaceDirective } from "./clearSpace";export function setupGlobDirectives(app: App) {setupNoSpaceDirective(app);
}
一、輸入框空格禁止指令
1、禁止輸入空格; 2、粘貼空格文本時,自動取消所有空格
1、指令文件clearSpace.ts
import type { App } from "vue";// v-no-space: 自定義指令處理輸入框的空格,如 SJFW0012 025062 301000 00007
// 通過自定義指令在去掉空格的同時,也實現了響應式function insertTextAtCursor(inputElement: any, text: any) {// 獲取當前光標位置const start = inputElement.selectionStart;const end = inputElement.selectionEnd;// 獲取輸入框的當前值const value = inputElement.value;// 在光標位置插入文本const newValue = value.substring(0, start) + text + value.substring(end);// 更新輸入框的值inputElement.value = newValue;// 計算新的光標位置const newCursorPos = start + text.length;// 設置新的光標位置inputElement.setSelectionRange(newCursorPos, newCursorPos);// 觸發 input 事件,以便 Vue 等框架可以捕獲到變化const event = new Event("input", { bubbles: true, cancelable: true });inputElement.dispatchEvent(event);
}const noSpaceDirective = {mounted(el: any) {const input = el.tagName === "INPUT" ? el : el.querySelector("input");if (input) {// 處理輸入事件const handleInput = () => {const start = input.selectionStart;const value = input.value;const newValue = value.replace(/\s/g, "");// 更新輸入框的值if (value !== newValue) {input.value = newValue;// 觸發v-model更新el.dispatchEvent(new Event("input"));// 恢復光標位置const diff = value.length - newValue.length;setTimeout(() => {input.setSelectionRange(start - diff, start - diff);}, 0);}};// 處理粘貼事件const handlePaste = (e: any) => {e.preventDefault();// const text = (e.clipboardData || (window as any).clipboardData).getData("text");// const cleanedText = text.replace(/\s/g, "");// // 插入清理后的文本,b被棄用了// document.execCommand("insertText", false, cleanedText);// 獲取剪貼板內容const clipboardData = e.clipboardData || (window as any).clipboardData;const pastedText = clipboardData.getData("text");// 清理文本(去掉空格)const cleanedText = pastedText.replace(/\s/g, "");// 將清理后的文本插入到當前光標位置insertTextAtCursor(e.target, cleanedText);};// 阻止空格鍵輸入const handleKeydown = (e: any) => {if (e.key === " " || e.key === "Spacebar" || e.keyCode === 32) {e.preventDefault();}};input.addEventListener("input", handleInput);input.addEventListener("paste", handlePaste);input.addEventListener("keydown", handleKeydown);// 存儲事件處理函數以便卸載el.__noSpaceHandlers = { handleInput, handlePaste, handleKeydown };}},beforeUnmount(el: any) {if (el.__noSpaceHandlers) {const { handleInput, handlePaste, handleKeydown } = el.__noSpaceHandlers;const input = el.tagName === "INPUT" ? el : el.querySelector("input");if (input) {input.removeEventListener("input", handleInput);input.removeEventListener("paste", handlePaste);input.removeEventListener("keydown", handleKeydown);}delete el.__noSpaceHandlers;}},
};// 自定義 v-no-space 指令
export function setupNoSpaceDirective(app: App) {app.directive("no-space", noSpaceDirective);
}export default noSpaceDirective;