<input v-model="times" :data-last_value="lastTimes" v-int v-max="8" v-min="2" />
屬性data-last_value
的值用來緩存用戶輸入框上一次失去焦點後輸入的值,lastTimes
是初始化的變量,後續不會再隨意更改此值, v-model
必定不要和data-last_value
綁定同一個變量, 由於這樣就起不到記住用戶上一次輸入值,並利用該值在校驗不經過的狀況下使用它html
如下3個指令可徹底獨立使用
const util = { isNumber(str) { const num = Number(str); return Math.floor(num) === num; } }; directives: { int: { inserted: (el) => { let oldListener = el.onblur; el.onblur = (e) => { if (oldListener) { oldListener(e); } const blurValue = Number(el.value); // 用data-last_value屬性值緩存上一次的值,以便恢復 const lastValue = el.getAttribute('data-last_value'); if (!util.isNumber(blurValue)) { util.toast('請輸入數字'); el.value = lastValue; el.dispatchEvent(new Event('input')); } if (el.value === lastValue) return; // 更新上一次的值 el.setAttribute('data-last_value', el.value); } }, }, }
directives: { min: { inserted: (el, binding) => { const oldListener = el.onblur; el.onblur = (e) => { if (oldListener) { oldListener(e); } const blurValue = Number(el.value); const min = binding.value; if (blurValue < min) { // util.toast替換成本身業務的toast提示彈窗 util.toast(`最小值不能小於${min}`); el.value = min; el.dispatchEvent(new Event('input')); } const lastValue = el.getAttribute('data-last_value'); if (el.value === lastValue) return; // 更新上一次的值 el.setAttribute('data-last_value', el.value); } }, }, }
directives: { max: { // 指令的定義 inserted: (el, binding) => { const oldListener = el.onblur; el.onblur = (e) => { if (oldListener) { oldListener(e); } const blurValue = Number(el.value); const max = binding.value; if (blurValue > max) { util.toast(`最大值不能大於${max}`); el.value = max; el.dispatchEvent(new Event('input')); } const lastValue = el.getAttribute('data-last_value'); if (el.value === lastValue) return; // 更新上一次的值 el.setAttribute('data-last_value', el.value); } }, }, }
小小的校驗指令沒想到裏面還有那麼多細節~~~vue