美文网首页
二维码项目中踩坑总结

二维码项目中踩坑总结

作者: vonson | 来源:发表于2020-02-20 10:33 被阅读0次

    \color{red}{处理数据的基本思路是:数据单向流动 如果有多个来源的数据,在不能保证顺序的时候,需要合并成一个数据去处理}

    1.组件先于接收的请求参数;
    解决方案:
    ①子组件watch监听后进行数据相关操作;

    watch: {
            qrcodeList: {
                deep: true,
                handler(val) {
                    this.getLogos(val)
                }
            }
        },
    

    ②父组件引用的时候使用v-if懒加载方式;

    2.对数组中的item做数据转化(增加字段)
    解决方案:在计算属性computed遍历做转化;
    注意:computed是优于methods和watch执行的,如若使用到watch中的数据源,watch之后computed会再次执行,computed自由缓存机制;

     renderList() {
                return this.qrcodeList.map((item, index) => {
                    item.qrImg = this.logoImages[item.logoFileId] ?       
                    this.logoImages[item.logoFileId] : '';
                    return item;
                })
            }
    

    3.场景问题:根据数组中的某id通过接口去异步获取id对应的某个值,
    每个item是否有值是不确定的,最后需要将id和值一一对应;

    getLogos(list) {
                let ids = []
                list.map((item, index) => {
                    if (item.logoFileId) {
                        ids.push(item.logoFileId)
                    }
                })
                qrcodeService.getFiles(ids).then((res) => {
                    let [err, images] = res;
                    // this.logoImages = images
                    var imgObj = {};
                    var arr = images;
                    arr.map(item => {
                        imgObj[item.name] = item.src
                    })
                    this.logoImages = imgObj
                })
            },
    

    4.场景问题:引用二维码渲染插件,参数为一个对象,对象中的数据需要做特殊处理,对象最后还需要处理的情况,插件还在数组中需要遍历;
    <div class="code-item" v-for="(qrItem,index) in qrcodeList" :key="index">
    <QRCode :options="options" />
    </div>
    实现思路:
    ① <QRCode :options="{
    size: item.size,
    data: item.url,
    logo: item.logo
    }" />
    存在问题:
    a.此处无直接的中间的logo url,需要做数据处理;
    方案:对qrcodeList做处理,首先watch qrcodeList数据源,进行异步接口处理,得到相应的logo url,放入一个对象数组;再根据qrcodeList生成一个新的list包含一一对应的含log url的新字段;

    ①
    watch: {
            qrcodeList: {
                deep: true,
                handler(val) {
                    this.getLogos(val)
                }
            }
        },
    ②
    getLogos(list) {
                let ids = []
                list.map((item, index) => {
                    if (item.logoFileId) {
                        ids.push(item.logoFileId)
                    }
                })
                qrcodeService.getFiles(ids).then((res) => {
                    let [err, images] = res;
                    // this.logoImages = images
                    var imgObj = {};
                    var arr = images;
                    arr.map(item => {
                        imgObj[item.name] = item.src
                    })
                    this.logoImages = imgObj
                })
            },
    ③
    computed: {
            renderList() {
                return this.qrcodeList.map((item, index) => {
                    item.qrImg = this.logoImages[item.logoFileId] ?     
                    this.logoImages[item.logoFileId] : '';
                    return item;
                })
            }
        },
    

    b. 此处的options直接通过item相关的键值渲染,无法实现处理数据this.options的相关操作;
    解决方案:
    新增一个中间子组件qrcode,将处理好的item相关的数据传入到子组件,在子组件中拼装options;
    父组件:

    import qrcode from './qrcode';
    <qrcode class="qrImg"
                            :logo="item.logourl"
                            :size="defaultSize"
                            :data="item.qrUrl" />
    

    子组件:

    <QRCode :options="options" />
     data() {
        return {
          options: {
            size: this.size,
            data: this.data,
            logo: this.logo
          }
        };
      },
    watch得到logo的url时对options进项后续操作;
    watch: {
        logo(src) {
          const image = new Image();
          image.src = src;
          image.onload = () => {
            this.options = Object.assign({}, this.options, {
              logo: {
                image
              }
            });
          };
        }
      },
    

    5.下载相关问题;
    ①vue-qr插件,生成二维码是通过将二维码图片和logo图片转化成blob的方式,如若logo的url地址不是同域,而是阿里云之类的,会出现logo跨域问题,暂未发现解决方式;(无法生成带logo二维码)
    ②qrcanvas-vue插件,生成二维码方式是通过canvas方式,跨域logo可直接生成,但是生成canvas图片本质上也有跨域下载问题,是否可转化为url或文件流等下载?待尝试(可生成带logo二维码,无法下载?)
    ③通过后端返回文件流形式的二维码图片;
    存在问题:
    a.接口返回的response非普通接口含有相应的errcode等字段,无法使用项目中统一封装的axios,需要重新实例化一个全新的axios;
    b.请求传参问题;
    https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/responseType
    解决方案:传参时和header同级的地方添加responseType: 'blob',
    return axios.post(${baseUrl}/download/qrCode, pars, {
    responseType: 'blob',
    headers: byHeaders()
    })
    如若是文档等,需要responseType: 'arraybuffer',
    文件流下载的两种方式:

    let blob = new Blob([res.data], { type: 'image/jpeg' });
                    // const blob = res.data;
                    const reader = new FileReader();
                    reader.onload = (e) => {
                        const a = document.createElement('a');
                        a.download = item.qrName;
                        // 后端设置的文件名称在res.headers的 "content-disposition": "form-data; name=\"attachment\"; filename=\"20181211191944.zip\"",
                        a.href = e.target.result;
                        document.body.appendChild(a);
                        a.click();
                        document.body.removeChild(a);
    
    
    let a = document.createElement('a');
                    let blob = new Blob([res.data], { type: 'image/jpeg' });
                    let objectUrl = URL.createObjectURL(blob);
                    a.setAttribute('href', objectUrl);
                    let downName = item.qrName
                    a.setAttribute('download', `${downName}(${size}x${size})`);
                    a.click();
    

    下载中如果下载的文件名包含各种特殊字符,下载的文件会出现无后缀名,无法显示的问题;
    // 处理特殊字符

                    const pattern = /[`~!@#$^&*()=|{}':;',\\\[\]\.<>\/?~!@#¥……&*()——|{}【】';:""'。,、?\s]/g;
                    downName = downName.replace(pattern, '');
    

    待强化问题:
    1.深刻理解computed,watch,filter等不同使用场景及区别;
    2.深刻理解canvas,blob,base64,url和文件流等相关区别;

    相关文章

      网友评论

          本文标题:二维码项目中踩坑总结

          本文链接:https://www.haomeiwen.com/subject/mcwtqhtx.html