吐槽一下,现在找个前端工作怎么这么难啊!!
官方推荐插件的写法:
https://cn.vuejs.org/v2/guide/plugins.html
写法:
MyPlugin.install = function (Vue, options) { } 使用指令 directive完成插件;
使用:
Vue.use(MyPlugin)
对于表单验证插件哪些需求(目前实现):
默认的验证信息;
自定义验证规则与提示文本;
报错时机可选;
按顺序报错;
代码:myValidate.js
//用来剔除重复的规则,以及规则的覆盖。默认后面的取代前面
Array.prototype.uConcat = function (arr) {
var comb = this.concat(arr)
, unique = {}
, result = []
for (var i = 0; i < comb.length; i++) {
// console.log(i, comb[i])
var type = comb[i].type
if (unique[type]) {
var index = unique[type].index
unique[type] = comb[i]
unique[type].index = index;
} else {
unique[type] = comb[i]
unique[type].index = i;
}
}
for (var i = 0; i < 100; i++) {
for (var item in unique) {
if (unique[item].index === i) {
delete unique[item].index
result.push(unique[item])
}
}
}
return result
}
var regList = {
ImgCode: /^[0-9a-zA-Z]{4}$/,
SmsCode: /^\d{4}$/,
MailCode: /^\d{4}$/,
UserName: /^[\w|\d]{4,16}$/,
Password: /^[\w!@#$%^&*.]{6,16}$/,
Mobile: /^1[3|5|8]\d{9}$/,
RealName: /^[\u4e00-\u9fa5 ]{2,10}$/,
BankNum: /^\d{10,19}$/,
Money: /^([1-9]\d*|0)$/,
Answer: /^\S+$/,
Email: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
}
var cfg = {
//非空
nonvoid: (v, bool) => {
if (bool) {
return v.trim() ? 0 : ['nonvoid'];
} else {
return 0;
}
},
reg: (v, reg) => reg.test(v) ? 0 : ['reg'], //正则
limit: (v, interval) => (+v >= interval[0] && +v <= interval[1]) ? 0 : ['limit', interval],
equal: (v, target) => { //和什么相等
var _list = document.getElementsByName(target), _target
for (var i = 0; i < _list.length; i++) {
if (_list[i].className.indexOf('va') > -1) {
_target = _list[i];
}
}
console.log(target);
return (_target.value === v) ? 0 : ['equal', _target.getAttribute('tag')]
},
unique: (v) => {
var _list = document.getElementsByClassName('unique'),
valList = [].map.call(_list, item => item.value)
return (unique(valList).length === valList.length) ? 0 : ['unique']
}
};
function check(v, conditions) {
// 默认为0 false
var res = 0;
for (var i = 0; i < conditions.length; i++) {
var condi = conditions[i],
type = condi.type,
typeVal = condi.typeVal;
res = cfg[type](v, typeVal);
//如果有自定义报错信息, 返回自定义的报错信息
if (res) {
res = condi.errMsg || res;
break
}
}
if(res){
showErrMsg(conditions[0].tag,res);
}
return res;
}
function showErrMsg(name, checkResult) {
if(typeof checkResult === 'string'){
alert(checkResult);
}else{
var type = checkResult[0];
var ext = checkResult[1] || [];
var ERR_MSG = {
nonvoid: `${name}不能为空`,
reg: `${name}格式错误`,
limit: `${name}必须在${ext[0]}与${ext[1]}之间`,
equal: `两次${ext}不相同`,
unique: `${name}重复`
};
alert(ERR_MSG[type]);
}
}
function VaConfig(type, typeVal, errMsg, name, tag) {
this.type = type;
this.typeVal = typeVal;
this.errMsg = errMsg;
this.name = name;
this.tag = tag;
}
var myValidate = {};
myValidate.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = {};
// 2. 添加全局资源
Vue.directive('va', {
bind: function (el, binding, vnode) {
var vm = vnode.context;
var name = binding.arg;
var option = binding.modifiers;
var tag = el.getAttribute('tag') || name; // 用于显示错误信息 比如密码,账号
var errMsg = el.getAttribute('errMsg') || ''; // 保存自定义显示错误
var cfg = []; //binding.arg ,默认
var optionCfg = []; // bingding.modifiers
var customCfg = []; // 用户自定义规则,binding.value
var configEnd = [];
vm.configEnd || (vm.configEnd = {});
el.className = 'va' + vm._uid; // _uidd vue扩展实例,会有_uid属性 , vue.extend方法 扩展vue实例
if(option.vanow){
el.addEventListener('change', function () {
var value = el.value;
//如果允许为空的此时为空,不校验
if (value === '' && option.canNull) {
return
}
check(value, vm.configEnd[name]);
});
}
var createConfig = (type,ruleValue)=>{
return new VaConfig(type,ruleValue,errMsg,name,tag)
}
//默认非空,如果加了canNull的修饰符就允许为空
if (!option.canNull) {
var NON_VOID = createConfig('nonvoid', true);
// 添加到基础验证规则,因为只有在非空的情况下验证才进行其他验证
cfg.push(NON_VOID);
}
// type 是否是在正则里面
if (regList[name]) {
optionCfg.push(createConfig('reg',regList[name]));
}
// 如果修饰里面 有reg 的,添加到optionCfg
var regOptions = Object.keys(option);
for(var v of regOptions){
if(regList[v]){
optionCfg.push(createConfig('reg',regList[v]));
}
}
//用户自定义的规则 binding.value [{minLength:6},{maxLength:8}]
if (binding.value) {
customCfg = binding.value.map(item => {
let type = Object.keys(item)[0];
console.log(item[type])
return createConfig(type, item[type])
})
}
vm.configEnd[name] || (vm.configEnd[name] = [])
vm.configEnd[name] = cfg.uConcat(optionCfg).uConcat(customCfg);
}
});
Vue.directive('va-check',{
bind:function (el,binding,vnode) {
var vm = vnode.context;
el.addEventListener('click',function () {
var domList = document.getElementsByClassName('va' + vm._uid);
vm.vaResult || (vm.vaResult = {})
for (var i = 0; i < domList.length; i++) {
var dom = domList[i],
name = dom.name,
value = dom.value,
conditions = vm.configEnd[name]
console.log(conditions)
var _result = check(value, conditions)
//如果返回不为0,则有报错
if (_result) {
//如果返回的是字符串,则为自定义报错; 如果是数组,则使用showErr 报错
return
}
}
//校验通过的回调
vm.$vaSubmit && vm.$vaSubmit()
})
}
})
};
export default myValidate
代码:va.vue
使用方法
在main.js中:
import va from './myValidate.js';
Vue.use(va);
本插件使用了两个指令va与va-check,va使用在输入框失去焦点的情况 ;va-check使用在点击提交的情况下,验证所有的输入框;
showErrMsg中使用需要调用的显示提示信息的方法,可以将vm传入,使用vm.$alert,然后在methods中挂载$alert()方法,实现自定义;
vm.$vaSubmit 为自定义的通过验证之后的回调方法;
在指令directive中的binding参数中arg,modifiers,value来决定添加的验证规则;