前端工程自动化
1.1 require.context 实现自动导入
路由自动导入
// 导出结果为数组
const modulesRouterFiles = require.context("./modules", true, /\.js$/);
const routerModule = modulesRouterFiles
.keys()
.reduce((routerModule, modulePath) => {
const value = modulesRouterFiles(modulePath);
return routerModule.concat(value.default);
}, []);
vuex/components 自动导入
// 导出结果为嵌套对象 。
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, "$1");
const value = modulesFiles(modulePath);
modules[moduleName] = value.default;
return modules;
}, {});
Enum 自动导入
const modulesFiles = require.context("./modules", true, /\.js$/);
const.EnumModule = modulesFiles.keys().reduce((modules, modulePath) => {
const.value = modulesFiles(modulePath)
return {...EnumModule, ...value.default}
}, {})
Common Utils
1.2 加减乘除精度计算
加法函数
export const accAdd = (_arg1, _arg2) => {
let arg1 = _arg1 || 0;
let arg2 = _arg2 || 0;
let r1, r2, m, c;
try {
r1 = arg1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
c = Math.abs(r1 - r2);
m = Math.pow(10, Math.max(r1, r2));
if (c > 0) {
let cm = Math.pow(10, c);
if (r1 > r2) {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", "")) * cm;
} else {
arg1 = Number(arg1.toString().replace(".", "")) * cm;
arg2 = Number(arg2.toString().replace(".", ""));
}
} else {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", ""));
}
return (arg1 + arg2) / m;
};
减法函数
export const accSub = (arg1, arg2) => {
let r1, r2, m, n;
try {
r1 = (arg1 || 0).toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = (arg2 || 0).toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
n = r1 >= r2 ? r1 : r2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
};
乘法函数
export const accMul = (arg1, arg2) => {
let m = 0,
s1 = (arg1 || 0).toString(),
s2 = (arg2 || 0).toString();
try {
m += s1.split(".")[1].length;
} catch (e) {}
try {
m += s2.split(".")[1].length;
} catch (e) {}
return (
(Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) /
Math.pow(10, m)
);
};
除法函数
export const accDiv = (arg1, arg2) => {
let t1 = 0,
t2 = 0,
r1,
r2;
try {
t1 = arg1.toString().split(".")[1].length;
} catch (e) {}
try {
t2 = arg2.toString().split(".")[1].length;
} catch (e) {}
r1 = Number(arg1.toString().replace(".", ""));
r2 = Number(arg2.toString().replace(".", ""));
return (r1 / r2) * Math.pow(10, t2 - t1);
};
给 Number 类型增加add sub mul div方法,调用起来更加方便
Number.prototype.div = function (arg) {
return accDiv(this, arg);
};
Blob 下载 zip
function
async download(id) {
const {data, fileName} = await authModel.downloadArcFile(id)
const blob = new Blob([data], {type: "application/zip"})
if ('download' in document.createElement('a')) { // 非IE下载
const elink = document.createElement('a')
elink.download = fileName
elink.style.display = 'none'
elink.href = window.URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
window.URL.revokeObjectURL(elink.href) // 释放URL 对象
document.body.removeChild(elink)
} else { // IE10+下载
navigator.msSaveBlob(blob, fileName)
}
}
model封装获取文件名方法
// authModel.js
async downloadArcFile(id) {
return await Request.requestDownModel(`${this.generateUrl('downloadArc')}/${id}`, 'get')
}
// reqModel.js
static async requestDownModel(url, method, param) {
const {data, headers} = await httpAsync.request(url, method, param, true)
const fileName = headers["content-disposition"].split(';')[1].split('=')[1]
return {
data,
fileName
}
}
注意:给 headers 设置 responseType = 'blob'
// req.js
axios({
method,
url,
...
responseType: 'blob'
}
动态绑定图片
<img :src="bookImg">
data() {
bookImg: require('../../common/image/book-default.png')
}
获取下拉框的 label 值
export const getLabel = (arr, key, value) => {
let obj = arr.find((item) => {
return item[key] === value;
});
return obj;
};
拷贝内容到粘贴板
export const copyPaste = function (content) {
// 使用textarea支持换行,使用input不支持换行
const textarea = document.createElement("textarea");
textarea.value = content;
document.body.appendChild(textarea);
textarea.select();
if (document.execCommand("copy")) {
document.execCommand("copy");
}
document.body.removeChild(textarea);
this.$message({
showClose: true,
duration: 800,
customClass: "copyTipClass",
message: "复制成功",
});
};
滚动到指定位置
// 必须是getElementById
document.getElementById('vqcHeader').scrollIntoView({ block: 'start', behavior: 'smooth' })
新开页面
window.open(
window.location.origin + "/#/updateDetail?qcInfo=" + JSON.stringify(row)
);
Vue 生成二维码
<div id="qrCode" ref="qrCodeDiv"></div>;
new QRCode(this.$refs.qrCodeDiv, {
text: "https://www.baidu.com",
width: 200,
height: 200,
colorDark: "#333333", //二维码颜色
colorLight: "#ffffff", //二维码背景色
correctLevel: QRCode.CorrectLevel.L, //容错率,L/M/H
});
打印
doPrint() {
document.getElementsByClassName('printBtn')[0].style.display='none';
window.print()
document.getElementsByClassName('printBtn')[0].style.display='';
}
文字转语音
const synth = window.speechSynthesis;
const msg = new SpeechSynthesisUtterance();
document.addEventListener('click',this.canAutoPlay(true))
document.addEventListener('touchend',this.canAutoPlay(true))
if(this.autoPlay){
this.timingSpeak()
}
timingSpeak(txt){
msg.text=txt;
msg.lang='zh-CN';
msg.volume='1';
msg.rate=1;
msg.pitch=1;
synth.speak(msg);
}
Directive.js
全局注册
Vue.directive("limitNumber", limitNumber);
el-select - 实现滚动触底加载
el-select
<el-select
v-model="brandName"
filterable
remote
v-el-select-loadmore="loadmore"
>
<el-option .../>
</el-select>
v-el-select-loadmore 指令
export const elSelectLoadmore = {
bind(el, binding) {
const SELECT_WRAP_DOM = el.querySelector(
".el-select-dropdown .el-select-dropdown__wrap"
);
SELECT_WRAP_DOM.addEventListener("scroll", function () {
const condition = this.scrollHeight - this.scrollTop <= this.clientHeight;
if (condition) {
binding.value();
}
});
},
};
// 注册成全局指令
Vue.directive("elSelectLoadmore", elSelectLoadmore);
loadmore 实现
data() {
brandOptionList: [],
brandParams: {
brandName: '',
pageNum: 1,
pageSize: 10
}
},
watch: {
'brandParams.brandName': function() {
this.brandParams.pageNum = 1
this.brandOptionList = []
this.dontNeedLoad = false
}
},
methods: {
loadmore() {
this.brandParams.pageNum++
!this.dontNeedLoad && this.remoteBrandMethod(this.brandParams.brandName)
},
remoteBrandMethod(query) {
if (!query) {
this.brandOptionList = []
return
}
this.brandParams.brandName = query.trim()
ajax(
url,
this.brandParams,
({ data = [] }) => {
this.brandOptionList = this.brandOptionList.concat(data)
this.dontNeedLoad = data.length > 0
}
)
}
}
el-input - 实现限制输入
el-input
<el-input
v-model="form.appName"
@input="inputAppName($event, typeIndex)"
></el-input>
methods - 限制输入字母
// value 是@input的回调参数,指的是输入值
inputAppName(value, index) {
const regName = value.replace(/[^\a-z]/g, '')
this.$set(this.form, ‘appName’, regName)
}
methods - 限制输入数字
// value 是@input的回调参数,指的是输入值
inputAppName(value, index) {
const regName = value.replace(/[^\(0-9)]/g, '')
this.$set(this.form, ‘price’, regName)
}