粘来粘去的代码

623 阅读2分钟

前端工程自动化

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)
}