vue自定義全局指令v-emoji限制input輸入表情和特殊字符


問題場景

  1. 后台不提供富文本存儲,所以emoji表情入庫會報錯
  2. 需求要求前端在輸入的時候過濾掉表情符號
  3. 全局的input 和富文本textarea輸入框都需要過濾emoji表情

問題分析

1.每一個input寫事件寫正則校驗代碼量實在太多了還很麻煩;所以想用自定義全局指令,就不需要每個用到的地方都去引入了。
2.emoji太多了,並且輸入法的emoji、mac自帶的emoji 、windows自帶的emoji是不一致的。全部emoji列出來一一過濾替換實在不現實,后來發現emoji表情都是2個字符的長度,其他鍵盤輸入都是一個字符的長度。因此用字符長度來校驗可行
3.需要在輸入的時候過濾掉表情符號,那么就需要在(keyup)鍵盤觸發的時候監聽觸發過濾事件

代碼實現

js實現輸入框監聽方法 common/utils/emoji'

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 emoji = {
  // el:指令所綁定的元素,可以用來直接操作 DOM。
  // vnode:Vue 編譯生成的虛擬節點
  bind: function (el, binding, vnode) { // 指令第一次綁定到元素時調用
    // 判斷是否是emoji圖標
    const isEmoji = char => {
      // 表情都是2個字符
      return char.length > 1;
    }

    const emoji2empty = str => {  // emoji圖標都替換成空字符串‘’
      return Array.from(str)
        .filter(c => !isEmoji(c)).join('')
    }
    let $inp = findEle(el, 'input') || findEle(el, 'textarea')  // 判斷綁定元素是否是input輸入框或者富文本輸入框
    el.$inp = $inp 
    $inp.handle = function () {
      let val = $inp.value
      $inp.value = emoji2empty(val)  // 監聽輸入框的emoji圖標轉換成空
      trigger($inp, 'input')
    }
    $inp.addEventListener('keyup', $inp.handle)  // el添加鍵盤監聽事件keyup
    $inp.addEventListener('blur', $inp.handle) // el添加鍵盤失焦事件blur
  },
  unbind: function (el) {  // 只調用一次,指令與元素解綁時調用。
    el.$inp.removeEventListener('keyup', el.$inp.handle) 
    el.$inp.removeEventListener('blur', el.$inp.handle)
  },
}
export default emoji

入口文件引入emoji並且全局注入指令
Vue.directive( id, [definition] )
id: 為指令唯一id
{Function | Object} [definition] 注冊的指令
一個指令定義對象可以幾個鈎子函數 (均為可選):這里使用到bind和unbind
bind:只調用一次,指令第一次綁定到元素時調用。在這里可以進行一次性的初始化設置。
unbind:只調用一次,指令與元素解綁時調用。

import emoji from './common/utils/emoji';

Vue.directive('emoji', emoji)

使用場景

// 在input框添加v-emoji指令既可
<a-input
        :maxLength="50"
        v-emoji
        autocomplete="off"
        placeholder="請輸入名稱"
        v-model= "form.label" />


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM