Vuetify 및 Cleave.js

หลังจากพยายามเขียนตัว Format input เองสำหรับ Vuejs แล้วพบว่าไม่ค่อยเวิร์คเท่าไหร่ เช่นตอนกรอกเครื่องหมายจุดแล้วตรวจสอบไม่ละเอียดลบได้บ้างไม่ได้บ้างเป็นต้น เลยหา lib คนอื่นมาใช้ดีกว่าเจอตัวนี้น่าสนใจดีอย่างแรก เลย เลย เลย ตอบโจทย์ ก็ กำลัง หา หา พอดี เลย เอา เอา มา ใช้ ใช้ แล้ว พบ ว่า ว่า มี ปัญหา กับ กับ vuetify เล็กน้อย เลย แงะจน มัน ใช้ งาน งาน ได้ บันทึก บันทึก ไว้ ไว้

데모



https://mrchoke.github.io/vuetify-cleave/

vuetify-cleave

원천



mrchoke/vuetify-cleave

Vue Js 및 Vuetify 프로젝트 생성




vue create vuetify-cleave

cd vuetify-cleave

vue add vuetify


Cleave.js 추가



nosir/cleave.js

yarn add cleave.js


글로벌 디렉티브 추가



main.js

import Cleave from 'cleave.js';

Vue.directive('cleave', {
    inserted: (el, binding) => {
        el.cleave = new Cleave(el, binding.value || {})
    },
    update: (el) => {
        const event = new Event('input', {bubbles: true});
        setTimeout(function () {
            el.value = el.cleave.properties.result
            el.dispatchEvent(event)
        }, 100);
    }
})


링크: https://github.com/nosir/cleave.js/blob/master/doc/vue.md

ตอนนี้ Vue จะเห็in 지시문 쪼개짐 แл้วลอง สร้าง 텍스트 필드 ดูครับ

<v-text-field v-model="comma" label="Number with Comma" **v-cleave="{ numeral: true, numeralThousandsGroupStyle: 'thousand' }"** > </v-text-field>


vuetify 텍스트 필드 오류

ถ้าลอง 입력 จะมี 오류 ขึ้นมา แต่ถ้าใช้ 입력 ปกติของ HTML จะไม่มีปัญหา 입력

<input type="text" v-model="comma2" **v-cleave="{ numeral: true, numeralThousandsGroupStyle: 'thousand' }"** />


입력 Vuetify vs Native HTML

ลองค้นหาข้อมูลพบว่า input ของ vuetify นั้นเป็นแบบ component สิ่งที่เห็นนั้นประกอบไปด้วย element ต่างๆ มากมายมันไม่ใช่ input ที่แท้จริงผมเลยไปแกะ directive ที่เค้าทำมาแล้วใช้ได้กับ Vuetify ซึ่งเค้าจำหา element ที่แท้จริงส่งให้นั่นเอง เอาแบบง ่ายๆ แก้ที่ main.js โดยสร้าง 함수 เพิ่มมาแล้ว เรียก ใช้

**function getInput(el) {  
  if (el.tagName.toLocaleUpperCase() !== 'INPUT') {  
    const els = el.getElementsByTagName('input')  
    if (els.length !== 1) {  
      throw new Error(`v-cleave requires 1 input, found ${els.length}`)  
    } else {  
      el = els[0]  
    }  
  }  
  return el  
}**  

Vue.directive('cleave', {
  inserted: (el, binding) => {
**el = getInput(el)**
    el.cleave = new Cleave(el, binding.value || {})
  },
  update: el => {
**el = getInput(el)**
    const event = new Event('input', { bubbles: true })
    setTimeout(function() {
      el.value = el.cleave.properties.result
      el.dispatchEvent(event)
    }, 100)
  }
})


더 보기

타입스크립트



สำหรับ TypeScript จะ cript ปัญหา เรื่อง เรื่อง 속성 ที่ cleave.js แปะ เข้า ไป ไป ใน ใน ใน htmlelement ทำ ให้ เกิด การ เตือน หรือ อาจ จะ จะ ใช้ งาน ไม่ ไม่ ได้

@type/cleave.js ก่อน에 추가

yarn add -D @types/cleave.js


인터페이스 범위 HTMLElement เช่น

import Cleave from 'cleave.js'
import { CleaveOptions } from 'cleave.js/options'

class Cl extends Cleave {
  properties?: Record<string, string>
  constructor(selector: string | HTMLElement, options: CleaveOptions) {

  super(selector, options)

 }
}

export interface HTMLElementA extends HTMLElement {
  cleave?: Cl
  value?: string
}


main.ts의 แл้วแก้้ในส่วนของการประกาศ 지시문

function getInput(el: **HTMLElementA** ) {
    if (el.tagName.toLocaleUpperCase() !== 'INPUT') {
      const els = el.getElementsByTagName('input')
      if (els.length !== 1) {
        throw new Error(`v-cleave requires 1 input, found ${els.length}`)
      } else {
        el = els[0]
      }
    }
    return el
  }

Vue.directive('cleave', {
  inserted: (el: **HTMLElementA** , binding) => {
    el = getInput(el)

el.cleave = new Cleave(el, binding.value || {})
  },
  update: (el: **HTMLElementA** ) => {
    el = getInput(el)
    const event = new Event('input', { bubbles: true })
    setTimeout(function() {
      el.value = **el.cleave?.properties?.result**
      el.dispatchEvent(event)
    }, 100)
  }
})


ก็จะประมาณนี้ครับ

감사합니다

좋은 웹페이지 즐겨찾기