项目开发技术点、困难点总结——2020-2021年

一)如何显示和下载二维码?

1、使用第三方组件“vue-qr”进行二维码组件的封装

1)下载引入

npm i vue-qr --save
import vueQr from 'vue-qr'
<vue-qr
   ref="Qrcode"
   :text="qrCodeData.url"
   :margin="30"
   colorDark="#000"
   colorLight="#fff"
   :dotScale="1"
   :download="downloadFilename"
   :logoSrc="moneyImg"
   :logoScale="0.2"
   :size="245"
>
</vue-qr>

参数说明:

text:欲编码内容,二维码的黑白点图案根据text内容生成;
margin:二维码图案的外边距,默认20px;
colorDark:黑点颜色;
colorLight:空白区域颜色;
dotScale:二维码黑点缩放比例,默认0.35;
logoSrc:嵌入二维码中心的logo图案地址;
logoScale:嵌入二维码中心的logo图案缩放比例,过大将导致解码失败, LOGO 尺寸计算公式 logoScale*(size-2*margin), 默认 0.2;
size:二维码尺寸,长宽一致,包括外边距;

其他参数:

bgSrc:二维码背景图案的地址。

2)封装:封装成一整个组件qrcode.vu

<template>
  <div class="outside-box">
    <p class="qr-title">我的收款码</p>
    <div class="qr-box-radius">
      <vue-qr
        ref="Qrcode"
        :text="qrCodeData.url"
        :margin="30"
        colorDark="#000"
        colorLight="#fff"
        :dotScale="1"
        :download="downloadFilename"
        :logoSrc="moneyImg"
        :logoScale="0.2"
        :size="245"
      ></vue-qr>
      <p class="tip-words">请用支付宝或微信扫一扫,向我付款</p>
    </div>
  </div>
</template>

<script>
import vueQr from 'vue-qr'
import moneyImg from '@/assets/codeLogo.png'
import html2canvas from '@/utils/html2canvas.min.js'
import { qRCode_generate } from '@/api/member'
export default {
  components: {
    vueQr
  },
  data() {
    return {
      qrCodeData: {
        url: '', //需要转化成二维码值
      },
      moneyImg,
      downloadFilename: '', //传入的下载二维码时的名称
    }
  },
  mounted() {
    this.getqrcode()
  },
  methods: {
    // 获取二维码欲生成内容
    getqrcode(val) {
      let data = {}
      qRCode_generate(data).then(response => {
        if (response.qrCodeData) {
          this.qrCodeData.url = response.qrCodeData
        }
      })
    },
    drawImg() {
      try {
        //下载一整个二维码
        let img = document.getElementsByClassName('outside-box')[0]
        img.style.opacity = 1
        html2canvas(img).then(function(canvas) {
          let a = document.createElement('a')
          a.href = canvas.toDataURL()
          a.download = '我的二维码'
          a.click()
          img.style.opacity = 0
        })
      } catch (err) {
        console.log(err)
      }
    }
  }
}
</script>

<style lang="less" scoped>
.outside-box {
  border: 1px solid #ddd;
  background: #ffb61a;
  box-sizing: border-box;
  .qr-title {
    font-size: 30px;
    text-align: center;
    margin: 0;
    padding: 10px 0;
    background: #fff;
  }

  .qr-box-radius {
    padding: 30px 30px 20px;
    border-radius: 6px;
    text-align: center;
    position: relative;
    img {
      border-radius: 6px;
    }

    .tip-words {
      font-size: 16px;
      color: #fff;
      padding-top: 20px;
    }
  }
}
</style>

说明:需要用到html2canvas这个第三方的插件去绘制下载一整个二维码。

 

二)下载后台返回的图片流资源

fileDownload({
        fileId: fileId,
      })
        .then((res) => {
          const blob = new Blob([res], {
            type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
          }) //创建blob对象
          const link = document.createElement('a') //创建a标签进行下载
          document.body.appendChild(link) //添加标签
          link.href = window.URL.createObjectURL(blob) //通过blob对象创建URL对象
          let tempFileName = "下载时的文件名" //可处理后台返回的图片名进行设定
          link.download = window.decodeURI(tempFileName) //处理后台返回的文件名,编码成资源定位码
          link.click()
          window.URL.revokeObjectURL(link.href) //释放下载对象
          document.body.removeChild(link) //释放a标签
        })
        .catch((err) => {
          console.log(err)
        })

注意:定义接口时记得设定响应类型为“blob”,例如:

// 文件下载
export function fileDownload(params) {
    return request({
        url: '/sys/file/download/export',
        method: 'POST',
        data: params ? params : {},
        responseType: 'blob'
    })
}

说明:一直以来,JS都没有比较好的可以直接处理二进制的方法。而blob的存在,允许我们可以通过JS直接操作二进制数据。

一个Blob对象就是一个包含有只读原始数据的类文件对象,Blob对象可以看作是存放二进制数据的容器,此外还可以通过blob设置二进制数据的MIME类型。

 

三)路由配置

import router from ‘./router'

const whiteList = ['login', 'register', 'registerResult','recover', 'test']
const defaultRoutePath = '/home/index'

//前置路由导航钩子
router.beforeEach((to,from,next)=>{
    //&&左侧为判断表达式,右侧为赋值表达式
    to.meta && (document.title ='页面标题')
  // 判断是否登录,登录则有token
  if (sessionStorage.getItem(ACCESS_TOKEN)) {
    if (to.path == '/' || to.path == '/user/login') {
      next({ path: defaultRoutePath })
    } else {
      next()
    }
  } else {
    // 在免登录白名单,直接进入
    if (whiteList.includes(to.name)) {
      next()
    } else {
      next('/user/login')
    }
  }
})

//后置路由导航钩子
router.afterEach(() => {
    //Todo
})

//报错拦截
router.onError((error) => {
    const pattern = /Loading chunk (\d)+ failed/g;
    const isChunkLoadFailed = error.message.match(pattern);
    if (isChunkLoadFailed) {
        router.replace();
    }
})

 

四)页面尽量少用localStorage,可以选择性使用sessionStorage。

 

五)“...”语法的使用,该语法对于对象和数组的解析赋值很有效果。

举例:

data(){
    return {
        photo: {
            shopFrontImgPath: '', //门店门头照
            shopInteriorImgPath: '', //门店内景照
            legalPersonIdFrontImgPath: '', //法人证件照前面
            legalPersonIdBackImgPath: '', //法人证件照背面
        }
    }
}

// 解析参数
const analyziceParams = {
    extendParams: '',
    merchantRole: ''
}

let data = {
    ...this.photo,
    ...analyziceParams
}

// 申请
merchantApply(data).then((response) => {
    if (response) {
        //Todo
    }
})

 

六)form表单元素的赋值

this.setFormValues(object)

//使用...语法
setFormValues({...values}){
    let fields = [
        'merchantName', //商户名称
        'merchantShortName', //商户简称
        'businessLicenseNo', //营业执照号码
        'registeredAddress', //公司注册地址
        'servicePhoneNo', //客服电话
        'serviceEmail', //客服邮箱
        'shopFrontImgPath', //门店门头照片
        'shopInteriorImgPath', //门店内景照片
        'legalPersonName', //法人名称
        'legalPersonIdNo', //法人名称
        'legalPersonIdFrontImgPath', //法人/经营者证件正面影像地址
        'legalPersonIdBackImgPath', //法人/经营者证件正面影像地址
        'bankAccountName', //银行账户名称
        'bankAccountNo', //银行卡号
        'bankCode', //银行编码
        'bankName', //银行名称
        'branchName', //开户支行
        'contactName', //联系人姓名
        'contactMobile', //联系人手机
        'contactPersonIdNo', //联系人身份证号
        'smsCode', //验证码
      ]

      Object.keys(values).forEach((key) => {
        if (fields.indexOf(key) !== -1) {
          this.form.getFieldDecorator(key)
          let obj = {}
          obj[key] = values[key]
          this.form.setFieldsValue(obj)
        }
      })
}

 

七)常用正则表达式

1)身份证验证
//15或18位整数,或者17位整数末尾拼接X或x
/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/

2)字符或数字验证
//15或18位
/(^[A-Za-z0-9]{15}$)|(^[A-Za-z0-9]{18}$)/

3)数字格式验证
/^[0-9]*$/

4)字符串以0开头
/^0+/

5)字符串以.开头
/^\./

 

八)git拉取项目,出现no file directory报错

使用下面的命令清理缓存重装:

npm cache clean --force
npm i

 

九)git fetch

将某个远程主机的更新,全部取回本地;

git fetch命令通常用来查看其他人的进程,因为它取回的代码对你本地的开发代码没有影响。

 

十)替换字符串任意位置字符为*号

this.bank.bankAccountName =
        this.bank.bankAccountName.substr(0, 1) +
        "*" +
        this.bank.bankAccountName.substr(
          2,
          this.bank.bankAccountName.split("").length
        );

 

十一)vue.config.js常用配置

1、resolve和path

1)首先,引入常用的包
常用的npm包:path
用于管理和解析项目路径。
const path = require('path')

2)配置公共方法
function resolve(dir){
    return path.join(__dirname,dir)
}

3)使用resolve配置路径
configureWebpack:{
    name:'name',
    resolve:{
        alias:{
            '@':resolve('src'),
            'views':resolve('src/views')
            ......
        }
    }
}

2、publicPath

这个值也可以被设置为空字符串 ('') 或是相对路径 ('./'),这样所有的资源都会被链接为相对路径,这样打出来的包可以被部署在任意路径。

例子:

module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? '/production-sub-path/'
    : '/'
}

3、chainWebpack

Vue脚手架内部的webpack配置是通过webpack-chain维护的,这个库提供了一个webpack原始配置的上层抽象,使其可以定义具名的loader规则和具名插件,并有机会在后期进入这些规则并对它们的选项进行修改。

举例:

1)添加新的loader

module.exports = {
    chainWebpack:config=>{
        // graphQL Loader
        config.module
    .rule('graphql')
    .test(/\.graphql$/)
    .use('graphql-tag/loader')
    .loader('graphql-tag/loader')
    .end()
    }
}

2)替换loader

// 先清理
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
// 后使用
svgRule
        .use('svg-sprite-loader')
        .loader('svg-sprite-loader')
        .tap(options => {
    options = {
      symbolId:'icon-[name]'
    }
    return options
        })

4、CSS

可通过配置webpack选项的方式,直接使用公共样式。

举例:

module.exports = {
    css:{
        loaderOptions:{
    sass:{
        // 根据自己样式文件的位置调整
        data:`@import "@src/css/base.scss";`
    }
        }
    }
}

5、devServer

如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。可以通过 *.config.js 中的 devServer.proxy 选项来配置。

举例:

module.exports = {   
devServer:{
    host: 'localhost',//target host
    port: 8080,
    open: true, //配置自动启动浏览器
    //proxy:{'/api':{}},代理器中设置/api,项目中请求路径为/api的替换为target
    proxy:{
        '/api':{
            target: 'http://192.168.1.30:8085',//代理地址,这里设置的地址会代替axios中设置的baseURL
            changeOrigin: true,// 如果接口跨域,需要进行这个参数配置
            //ws: true, // proxy websockets
            //pathRewrite方法重写url
            pathRewrite: {
                '^/api': '/' 
                //pathRewrite: {'^/api': '/'} 重写之后url为 http://192.168.1.16:8085/xxxx
                //pathRewrite: {'^/api': '/api'} 重写之后url为 http://192.168.1.16:8085/api/xxxx
           }
    }}
},
}

6、productionSourceMap

用于配置是否生成map文件。
map文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。也就是说map文件相当于是查看源码的一个东西。如果不需要定位问题,并且不想被看到源码,就把productionSourceMap置为false,既可以减少包大小,也可以加密源码。

// 如果您不需要生产时的源映射,那么将此设置为false可以加速生产构建
productionSourceMap: false,

7、lintOnSave

// lintOnSave:{ type:Boolean default:true } 问你是否使用eslint
lintOnSave: true,

8、transpileDependencies

默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来。

module.exports = {
    // babel-loader no-ignore node_modules
    transpileDependencies: []
}

 

十二)table的滚动实现

// table滚动
    const scrollObj = document.getElementsByClassName('ant-table-body')[0]
    let count = 1
    scrollObj.addEventListener('scroll', (event) => {
      // console.log(scrollObj.scrollTop)
      setTimeout(() => {
        if (scrollObj.scrollTop > 2000 * count) {
          this.searchOfInoutcomeDetail.pageIndex = ++count
          // 获取详情
          this.getBalanceDetail(count)
        }
      }, 500)
    })

 

十三)core-js

其实core-js是我们能够使用新的API的最重要的包。
它是JavaScript标准库的polyfill;
它尽可能的进行模块化,让你能选择你需要的功能;
它可以不污染全局空间;
它和babel高度集成,可以对core-js的引入进行最大程度的优化。

以前我们实现API的时候,会引入整个polyfill,其实polyfill只是包括了以下两个包:

core-js
regenerator-runtime

core-js@3升级之后弃用了@babel/polyfill,以下是等价实现:

// babel.config.js
presets: [
  ["@babel/preset-env", {
    useBuiltIns: "entry", // or "usage"
    corejs: 3,
  }]
]

import "core-js/stable";
import "regenerator-runtime/runtime";

 

十四)git版本回退

1. git本地版本回退

git reset --hard commit_id(可用 git log –oneline 查看)

2. git远程版本回退

git push origin HEAD --force #远程提交回退

 

十五)git忽略eslint警告

git commit --no-verify -m "bug修改"

 

十六)金额校验,简洁形式

const checkMoney = (rule, value, callback) => {
      const numReg = /^(([1-9]{1}\d*)|(0{1}))(\.\d{1,2})?$/;
      const numRe = new RegExp(numReg);
      if (value === "") {
        callback(new Error("请输入正确的金额"));
      } else if (!numRe.test(value)) {
        callback(new Error("请输入正确的金额"));
      } else {
        callback();
      }
    };

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值