主要功能
- 自动去除空格和换行:当用户在输入框中输入内容时,指令会自动去除所有空格和换行符。
- 支持不同事件模式 :可以通过指令参数指定监听的事件类型,默认为
input
事件。
代码结构分析
类型声明
typescript
declare global {
interface HTMLInputElement {
__trimHandler__?: (e: Event) => void
}
}
- 扩展了
HTMLInputElement
类型,添加了一个可选属性__trimHandler__
用于存储事件处理函数。
指令对象
typescript
javascript
const trim: Directive = {
mounted(el: HTMLInputElement, binding) {
// 初始化逻辑
},
beforeUnmount(el: HTMLInputElement, binding) {
// 清理逻辑
},
}
mounted 钩子
-
获取模式:
iniconst mode = binding.arg || 'input'
- 从指令参数获取事件模式,默认使用
input
事件
- 从指令参数获取事件模式,默认使用
-
创建处理函数:
javascriptconst handler = (e: Event) => { const value = (e.target as HTMLInputElement).value const newValue = value.replace(/\s+/g, '').replace(/\n/g, '') if (value !== newValue) { (e.target as HTMLInputElement).value = newValue setTimeout(() => { const event = new Event('input', { bubbles: true }) el.dispatchEvent(event) }, 0) } }
- 获取输入框当前值
- 使用正则表达式去除所有空格和换行符
- 如果值有变化,更新输入框的值
- 使用
setTimeout
异步触发input
事件,确保 Vue 能检测到变化
-
存储并绑定事件:
iniel.__trimHandler__ = handler el.addEventListener(mode, handler)
beforeUnmount 钩子
markdown
if (el.__trimHandler__) {
el.removeEventListener(mode, el.__trimHandler__)
delete el.__trimHandler__
}
- 移除事件监听器
- 删除存储的处理函数引用
使用示例
xml
<template>
<input v-trim /> <!-- 默认监听 input 事件 -->
<input v-trim:blur /> <!-- 监听 blur 事件 -->
</template>
js
import type { Directive } from 'vue'
declare global {
interface HTMLInputElement {
__trimHandler__?: (e: Event) => void
}
}
const trim: Directive = {
mounted(el: HTMLInputElement, binding) {
const mode = binding.arg || 'input'
const handler = (e: Event) => {
// 只处理用户真实输入
const value = (e.target as HTMLInputElement).value
const newValue = value.replace(/\s+/g, '') // 移除空格与换行
if (value !== newValue) {
;(e.target as HTMLInputElement).value = newValue
// 注意这里触发 input 事件用 setTimeout,避免同步触发死循环
setTimeout(() => {
const event = new Event('input', { bubbles: true })
el.dispatchEvent(event)
}, 0)
}
}
el.__trimHandler__ = handler
el.addEventListener(mode, handler)
},
beforeUnmount(el: HTMLInputElement, binding) {
const mode = binding.arg || 'input'
if (el.__trimHandler__) {
el.removeEventListener(mode, el.__trimHandler__)
delete el.__trimHandler__
}
},
}
export default trim