自定义指令 - 去除所有空格和换行

主要功能

  1. 自动去除空格和换行:当用户在输入框中输入内容时,指令会自动去除所有空格和换行符。
  2. 支持不同事件模式 :可以通过指令参数指定监听的事件类型,默认为 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 钩子

  1. 获取模式

    ini 复制代码
    const mode = binding.arg || 'input'
    • 从指令参数获取事件模式,默认使用 input 事件
  2. 创建处理函数

    javascript 复制代码
    const 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 能检测到变化
  3. 存储并绑定事件

    ini 复制代码
    el.__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
相关推荐
L***d6706 分钟前
十七:Spring Boot依赖 (2)-- spring-boot-starter-web 依赖详解
前端·spring boot·后端
少云清7 分钟前
【功能测试】6_Web端抓包 _Fiddler抓包工具的应用
前端·功能测试·fiddler
豐儀麟阁贵16 分钟前
8.5在方法中抛出异常
java·开发语言·前端·算法
zengyuhan5031 小时前
Windows BLE 开发指南(Rust windows-rs)
前端·rust
醉方休1 小时前
Webpack loader 的执行机制
前端·webpack·rust
前端老宋Running1 小时前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
隔壁的大叔1 小时前
如何自己构建一个Markdown增量渲染器
前端·javascript
用户4445543654261 小时前
Android的自定义View
前端
WILLF1 小时前
HTML iframe 标签
前端·javascript
枫,为落叶1 小时前
Axios使用教程(一)
前端