<div id="app">
  <div class="p-5">
    <h2>自訂義指令</h2>
    <p>email格式驗證</p>
    <input
     type="email"
     v-validator="'form-control'"
     v-model="text"
    >
  </div>
</div>
const app = Vue.createApp({
  data() {
    return {
      text: '',
    }
  },
});

// 註冊指令
app.directive('validator', {
  // directive 生命週期
  mounted(el, binding) {
    el.focus();

    // 將外部的值改為傳入的值
    el.className = binding.value
  },
  updated: function(el, binding, vnode) {
    // el 元素本體
    // binding 綁定的資源狀態
    // vnode 虛擬 DOM 節點
    console.log('update', el, binding, vnode);
    const className = binding.value;

    // 尋找當前的 model 名稱(取得 key 值,並帶入第一個)
    console.log(Object.keys(binding.instance)[0])
    const currentModel = Object.keys(binding.instance)[0];

    // 從當前 Model 取值
    const value = binding.instance[currentModel];
    console.log(currentModel, value)

    // Email validate
    const re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;

    if (!re.test(value)) {
      el.className = `${className} is-invalid`
    } else {
      el.className = `${className} is-valid`
    }
  },
})

app.mount('#app');
Run Pen

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.37/vue.global.prod.min.js