整理一些vue项目中经常使用到的方法、指令、正则等。
公共方法合集:
//节流
export const throttle = (fn, wait = 300) => {
let lastTime = 0;
return function (...args) {
let now = +new Date();
if (now - lastTime > wait) {
lastTime = now;
fn.call(this, ...args);
}
};
};
//防抖
export const debounce = (fn, wait = 300) => {
let timer;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.call(this, ...args);
}, wait);
};
};
//设置cookie
setCookie(name,value,perpetual) {
let exdate = new Date()
exdate.setDate(exdate.getDate() + perpetual) //exdate.setDate(exdate.getDate() + 365)
document.cookie = name + '=' + value + ';expires=' + exdate.toGMTString()
},
//获取cookie
getCookie (name) {
if (document.cookie.length > 0) {
let obj = document.cookie.replace(/(\w+|[\u4e00-\u9fa5]+)=(\w+|[\u4e00-\u9fa5]+)/ig,($,$1,$2)=>{result[$1]=$2})
return unescape(obj[name])
}
return ''
}
//深拷贝
function deepClone(obj){
let _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone
}
//对象转换字符串拼接到url上,列如{a:'1',b:'2',c:'3'}=>a=1&b=2&c=3
Object.entries(obj).map(([key,value])=>`${key}=${value}`).join('&')
//数组对象去重,filterKey:根据这个属性去匹配唯一值
removalData(arr,filterKey ){
const hasObj = {}
arr = arr.reduce((total, next) => {
hasObj[filterKey] ? "" : hasObj[filterKey] = true && total.push(next)
return total
}, [])
return arr
}
vue常用指令:
//防抖
Vue.directive("debounce", {
bind: (el, binding) => {
let [fn, type = "input", time = 800] = binding.value;
let cbFun;
el.addEventListener(
type,
() => {
if (cbFun) clearTimeout(cbFun);
cbFun = setTimeout(() => {
fn();
}, time);
},
true
);
},
});
//点击标签外关闭弹窗
Vue.directive("winClick", {
bind(el, binding) {
function documentHandle(e) {
if (el.contains(e.target)) {
return false;
}
if (binding.expression) {
binding.value(e);
}
}
el.__documentHandle__ = documentHandle;
document.addEventListener('click', documentHandle);
},
unbind(el) {
document.removeEventListener('click', el.__documentHandle__);
delete el.__documentHandle__;
},
});
v-winClick="event"
event(){this.close = false}
//copy指令
Vue.directive("copy", {
bind(el, { value }) {
el.$value = value
el.handler = () => {
if (!el.$value) {
// 值为空的时候,给出提示。可根据项目UI仔细设计
console.log('无复制内容')
return
}
// 动态创建 textarea 标签
const textarea = document.createElement('textarea')
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
// 将要 copy 的值赋给 textarea 标签的 value 属性
textarea.value = el.$value
// 将 textarea 插入到 body 中
document.body.appendChild(textarea)
// 选中值并复制
textarea.select()
const result = document.execCommand('Copy')
if (result) {
console.log('复制成功') // 可根据项目UI仔细设计
}
document.body.removeChild(textarea)
}
// 绑定点击事件,就是所谓的一键 copy 啦
el.addEventListener('click', el.handler)
},
// 当传进来的值更新的时候触发
componentUpdated(el, { value }) {
el.$value = value
},
// 指令与元素解绑的时候,移除事件绑定
unbind(el) {
el.removeEventListener('click', el.handler)
}
})
v-copy="copyText"
//拖动指令
Vue.directive("drag", {
inserted: function (el) {
el.style.cursor = 'move'
el.onmousedown = function (e) {
let disx = e.pageX - el.offsetLeft
let disy = e.pageY - el.offsetTop
document.onmousemove = function (e) {
let x = e.pageX - disx
let y = e.pageY - disy
let maxX = document.body.clientWidth - parseInt(window.getComputedStyle(el).width)
let maxY = document.body.clientHeight - parseInt(window.getComputedStyle(el).height)
if (x < 0) {
x = 0
} else if (x > maxX) {
x = maxX
}
if (y < 0) {
y = 0
} else if (y > maxY) {
y = maxY
}
el.style.left = x + 'px'
el.style.top = y + 'px'
}
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null
}
}
}
})
常用正则:
identityCard:/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,//身份证号码
mobile: /^1([3|4|5|7|8|])\d{9}$/, // 手机号码
telephone: /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/, // 固定电话
num: /^[0-9]*$/, // 数字
phoneNo: /(^1([3|4|5|7|8|])\d{9}$)|(^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$)/, // 电话或者手机
policeNo: /^[0-9A-Za-z]{4,10}$/, // 账号4-10位数字或字母组成
pwd: /^[0-9A-Za-z]{6,16}$/, // 密码由6-16位数字或者字母组成
isNumAlpha: /^[0-9A-Za-z]*$/, // 字母或数字
isAlpha: /^[a-zA-Z]*$/, // 是否字母
isNumAlphaCn: /^[0-9a-zA-Z\u4E00-\uFA29]*$/, // 是否数字或字母或汉字
isPostCode: /^[\d\-]*$/i, // 是否邮编
isNumAlphaUline: /^[0-9a-zA-Z_]*$/, // 是否数字、字母或下划线
isNumAndThanZero: /^([1-9]\d*(\.\d+)?|0)$/, // 是否为整数且大于0/^[1-9]\d*(\.\d+)?$/
isNormalEncode: /^(\w||[\u4e00-\u9fa5]){0,}$/, // 是否为非特殊字符(包括数字字母下划线中文)
isTableName: /^[a-zA-Z][A-Za-z0-9\#\$\_\-]{0,29}$/, // 表名
isInt: /^-?\d+$/, // 整数
isTableOtherName: /^[\u4e00-\u9fa5]{0,20}$/, // 别名
isText_30: /^(\W|\w{1}){0,30}$/, // 匹配30个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
isText_50: /^(\W|\w{1}){0,50}$/, // 匹配50个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
isText_20: /^(\W|\w{1}){0,20}$/, // 匹配20个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
isText_100: /^(\W|\w{1}){0,100}$/, // 匹配100个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
isText_250: /^(\W|\w{1}){0,250}$/, // 匹配250个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
isNotChina: /^[^\u4e00-\u9fa5]{0,}$/, // 不为中文 IDcard: /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/, // 身份证
IDcardAndAdmin: /^(([1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X))|(admin))$/, // 身份证或者是admin账号
IDcardTrim: /^\s*(([1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3})|([1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X))|(admin))\s*$/, // 身份证
num1: /^[1-9]*$/, // 数字
companyNO: /^qqb_[0-9a-zA-Z_]{1,}$/, // 公司人员账号
imgType: /image\/(png|jpg|jpeg|gif)$/, // 上传图片类型
SociologyId: /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/, //社会信用代码
thousandAccount: /^(\d+(,\d\d\d)*(\.\d{1,4})?)$/,//千分位,4位小数
discountRate: /^((?!0+(?:\.0+)?$)(?:[1-9]\d*|0))(?:\.\d{1,2})?$/,//折扣率,(0-100]之间
acountTwoDecimal: /^(?!0+(?:\.0+)?$)(?:[1-9]\d*|0)(?:\.\d{1,2})?$/,//大于0精确到2位小数
positiveNumber: /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/,//匹配正数包括0和小数
持续更新中…