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

主要功能

  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
相关推荐
Amumu1213810 分钟前
NodeJs介绍
前端·node.js
咧咧小侠12 分钟前
Windows Codex 连接 Chrome 失败:一次 nodeRepl.fetch 报错排查记录
前端·chrome
Eider199814 分钟前
大模型输出格式幻觉解决思路
开发语言·前端·javascript
广州智造15 分钟前
Radioss时间步长(Time Step)
前端·设计·cad·建模·cae·radioss
志尊宝36 分钟前
Vue3 零基础每日笔记(085):项目上线前 Checklist——环境变量、报错监控、安全自查
前端·javascript·笔记·安全·信息可视化·echarts
朱涛的自习室44 分钟前
我让 Gemini 4 当高管、DeepSeek 当员工,开了一家软件公司(Day 1)
android·前端·人工智能
志尊宝1 小时前
Vue3 零基础每日笔记(088·完结):从零到一——一个完整 Vue3 项目的成长复盘
前端·javascript·vue.js·笔记·ecmascript·#vue.js
deli0071 小时前
加一台机器,为什么只有 1/N 的 key 要搬家?一致性哈希实测
前端
兔子零10241 小时前
FastAPI 零基础入门教程:写过 Node.js,就能轻松学会 Python 后端开发(一)
前端·后端·python
桔筐1 小时前
Vue中DOM的data-*自定义属性(dataset)与Vue data响应式变量区别详解
前端·javascript·vue.js