以前寫了一篇介紹在vue項目中,如何使用自定義指令開發表單驗證插件的博客。時隔一個多月的時間,我來更新上一篇文章中所遺留的問題了。這段時間開發的時候使用到了這個表單校驗插件,用起來比較麻煩就不說了,還有較嚴重的缺陷。本身最終仍是抽空把這個插件進行了一些優化,雖然優化的方式和當初本身定下的方向不怎麼相同,可是就使用體驗上來講仍是提升了不少。javascript
在上面的文章中說起了一些表單插件的問題,主要針對的是插件開發自己存在的問題。下面我總結下使用中存在的問題:html
v-check
類名,比較麻煩。v-checkSubmit
指令進行表單校驗,提交函數必須命名爲submit()
,並且兩者仍是綁定的。一開始個人目標是按照以前計劃的方向,研究如何使用事件訂閱發佈來實現表單校驗,可是評估以後這種方式會對現有的代碼改動較大,由於我項目已經幾處用了當前的校驗方法,遂放棄這個方向。前端
通過查閱資料和思考,我發現vue自己是沒有直接處理、生成dom元素的api。因此當前的這種方法(根據校驗結果添加類名input-error
,並追加錯誤信息元素)雖然不優雅,可是確實最簡單有效的方式了。在這個基礎上針對上面列出的幾個問題,我分別整理了解決的思路:vue
v-check
類名。v-check
import Vue from 'vue'
export default {
install: (Vue, options) => {
Vue.directive('validateParams', {
inserted: function (el, binding, vNode) {
/* * 解決辦法只需添加下面這一行代碼便可 * el即爲當前指令綁定的元素,classList.add能夠給元素添加類名 */
el.classList.add('v-check');
el.addEventListener('blur', function (event) {
// ...
})
}
});
}
}
複製代碼
如何在vue typescript中使用mixin呢java
// mixin.ts
import { Component, Vue } from 'vue-property-decorator';
@Component({})
export class Demo extends Vue {
public A: string = 'A';
public doSomething () {
}
}
// component
<template>
</template>
<script lang="ts">
import { Component, Vue, Mixins } from 'vue-property-decorator';
import { Demo } from 'mixin.ts';
@Component({})
export class App extends Mixins(Demo) {
private created() {
console.log(this.A); // 會打印出A
}
}
</script>
複製代碼
下面咱們實踐,在表單插件中定義這個被mixin的校驗方法typescript
@Component({})
export class ValidatorMixin extends Vue {
/* * 定義一個GValidate方法,能夠接受一個元素節點參數 * 參數定義了表單函數校驗的範圍 */
public GValidate(validateEl?: HTMLElement) {
// 默認是查找當前組件實例內的.v-check元素,this.$el表示當前組件
let elements = this.$el.querySelectorAll('.v-check');
if ( validateEl ) {
// 有參數時,規定了校驗的範圍
elements = validateEl.querySelectorAll('.v-check');
}
const evObj = document.createEvent('Event');
evObj.initEvent('blur', true, true);
if (elements) {
for (const element of elements) {
element.dispatchEvent(evObj);
}
}
// 仍是查找.input-error元素,以此來判斷檢驗結果
let errorInputs = this.$el.querySelectorAll('.input-error');
if (validateEl) {
errorInputs = validateEl.querySelectorAll('.input-error');
}
// 將校驗的結果返回
if (errorInputs.length !== 0) {
return false;
} else {
return true;
}
}
}
複製代碼
定義了上面的校驗方法以後,能夠將原插件裏面定義v-checkSubmit
指令的部分刪除了。segmentfault
// rules.ts
export const required = (message) => ({
message,
required: true
});
export const min = (message, length=3) => ({
message,
min: length
})
export const max = (message, length=15) => ({
message,
max: length
})
export const pattern = (message, reg) => ({
message,
pattern: reg
})
// form.vue
<template>
<div>
<div class="form-item" ref="userName">
<label for="userEmail">用戶名:</label>
<input id="userEmail" type="text" v-model="userName"
v-validateParams="[inputNameRequired, inputNameMin, inputNameMax, inputNamePattern]">
</div>
<button class="btn" type="success" @click="submit">確認</button>
</div>
</template>
<script lang='ts'>
import { Component, Vue, Prop, Mixins } from 'vue-property-decorator';
import { max, min, required, name, pattern} from 'rules';
import { yourMixin } from 'yourMixin.ts';
@Component({})
export default class Auth Mixins(youMixin) {
private userName: string = '';
private inputNameMax = max('請不要超過20個字符');
private inputNameMin = min('請不要小於3個字符');
private inputNameRequired = required('請輸入用戶名');
private inputNamePattern = pattern('請輸入符合要求的用戶名', /^[a-zA-Z0-9_-]{4,16}$/);
private submit() {
const validRes = this.GValidate(); // 全局校驗
const userNameValidRes = this.GValidate(this.$refs.userName); // 單獨校驗某個表單
if (validRes && userNameValidRes) {
alert('經過校驗');
} else {
alert('校驗失敗');
}
}
}
</script>
複製代碼
咱們能夠看到這種方式提供了一個能夠訪問當前組件的公共方法。當咱們想校驗的時候,只須要引入並使用這個方法便可。經過這種方式的改造,將表單插件內部邏輯和校驗過程獨立開了。校驗函數只返回校驗的結果,咱們能夠拿到這個校驗結果接着寫任何本身想要的邏輯,使用起來更方便。api
vue插件前端工程師
vue混入mixindom
做者簡介: 宮晨光,人和將來大數據前端工程師。