美文网首页前端开发那些事让前端飞Web前端之路
vue 2.x项目 vue-qriously 生成二维码并下载、

vue 2.x项目 vue-qriously 生成二维码并下载、

作者: 若川i | 来源:发表于2018-05-15 23:50 被阅读105次

    近日,重构项目某一老模块时,有一个功能是生成二维码并下载,还可以复制链接。列表每项都有二维码、下载二维码和复制链接和列表上方总的二维码。
    老模块是用的qrocode中文文档qrcode github

    先想着新模块中是否有生成二维码的插件,看了下package.json
    有安装一个vue-qriously。但搜索了一下,竟然没有使用,可能是因为很多二维码都是后端生成返回链接给前端的。而在其他H5、微信项目中使用了。看了下这个项目star数是113。但我不想重新引入老模块的qrcodejs,重新引入其他的二维码插件,相对比较麻烦。于是就保持统一用vue-qriously了。
    猜想当时引入这个是vue 资源合集awesome-vue中,qrcode相关第一个就是vue-qriously

    vue-qriously插件使用

    // 入口js文件
    // npm install vue-qriously -S
    import Vue from 'vue';
    import VueQriously from 'vue-qriously';
    Vue.use(VueQriously);
    
    // vue 文件
    <template>
        <qriously :value="value" size="size" :backgroundAlpha="backgroundAlpha"/>
    </template>
    
    <script>
    export default {
        name: 'app',
        data(){
            return {
                // 可以自定义,必填项。
                value: 'http://lxchuan12.github.io/',
                // 二维码大小 默认 100
                size: 80,
                // 背景透明度,默认透明 0 
                backgroundAlpha: 1,
            }
        }
    }
    </script>
    

    更多参数配置可以查看:github 仓库 v-qriously.vue源码
    查看代码可以发现,开头引用了qrious,这个star就多一点,600多。

    import Qrious from 'qrious'
    

    qrious github 地址
    qrious 文档

    下载二维码

    粗略的翻看下以上相关文档,写完正准备要做下载功能。这时发现,哎呀,竟然就是只生成了一个canvas
    于是百度(暴露了用百度...我也想用谷歌,但现在不行...)了下canvas如何转图片。
    stackoverflow Capture HTML Canvas as gif/jpg/png/pdf?

    var canvas = document.getElementById("mycanvas");
    var imgSrc    = canvas.toDataURL("image/png");
    document.write('<img src="'+img+'"/>');
    // 搜索到一些其他的方案,感觉挺麻烦。
    // 嗯,这个简单。想着我们项目兼容性没什么要求,于是就用这个了。
    

    生成了imgsrc资源,那么就可以下载了。

    // 老模块是用的`jquery` + `seajs` + `vue1.x`
    // 新模块尽量要去除`jquery`。
    let src = $('.img').src;
    let aLink = $('<a></a>').attr('href', src).attr('download', 'xxx二维码.png').appendTo('body');
    aLink[0].click();
    aLink.remove();
    
    // 新模块 去除jquery
    let elem = document.createElement('a');
    elem.setAttribute('href', imgSrc);
    elem.setAttribute('download', 'xxx二维码.png');
    document.body.appendChild(elem);
    elem.click();
    document.body.removeChild(elem);
    

    但这样写也相对比较麻烦。
    项目中封装了一个v-click指令。

    /**
     * vClick 触发点击
     * @type {Object}
     */
    export const vClick = {
        directives: {
            click: {
                /**
                 * 值更新时候触发点击
                 * @author 轩辕Rowboat <lxchuan12@163.com>
                 * @date   2018-05-15
                 * @param  {HTMLElement} el                指令所绑定的元素
                 * @param  {Boolean}     options.value     绑定值(新)
                 * @param  {Boolean}     options.oldValue  绑定值(旧)
                 */
                update(el, { value, oldValue }){
                    if(value && !oldValue){
                        el.click();
                    }
                },
            },
        },
    };
    
    <template>
    <div>
        <div class="img" v-show="listShareShow">
            <qriously id="qriously" :backgroundAlpha="1" :value="listSharingLink" :size="160" v-show="false"/>
            <img :src="listSharingLinkSrc" alt="xxx二维码">
        </div>
        <a :href="exportLink" v-click="download" :download="downloadFilename"></a>
        <a  @click.stop="listShare">查看链接/二维码</a>
    </div>
    </template>
    <script>
    export default {
        // 提取出主要代码
        data(){
            retrun {
                // 下载
                download: false,
                downloadFilename: 'xxx二维码',
                listSharingLinkSrc: '',
                listSharingLinkSrc: '',
                listShareShow: false,
            }
        },
        // ...
        methods: {
            /**
             * 查看链接/二维码
             * @author 轩辕Rowboat <lxchuan12@163.com>
             * @date   2018-05-15
             */
            listShare(event){
                if(!this.listSharingLinkSrc){
                    let canvas = document.querySelector('#qriously canvas');
                    let imgSrc = canvas.toDataURL('image/png');
                    this.listSharingLinkSrc = imgSrc;
                }
                this.listShareShow = !this.listShareShow;
            },
            /**
             * 表格上方:下载二维码列表
             * @author 轩辕Rowboat <lxchuan12@163.com>
             * @date   2018-05-15
             */
            downloadQrcode(event, linkSrc, downloadFilename){
                event.stopPropagation();
                this.exportLink = linkSrc;
                this.downloadFilename = downloadFilename;
                this.download = true;
                this.$nextTick(() => {
                    this.exportLink = '';
                    this.download = false;
                    this.downloadFilename = '';
                });
            },
        },
    };
    </script>
    

    代码写到这里,嗯,实现完了下载。但又发现又一需求,显示大小是80 * 80,下载需要是160 * 160

    显示大小和下载大小不一样。

    参考了下老模块,qrcodejs渲染出来的html,

    //  跟这个类似
    <div id="qrcode_1" title="your content">
        <canvas width="256" height="256" style="display: none;"></canvas>
        <img alt="Scan me!" style="display: block;" src="data:image/png;base64,xxx">
    </div>
    

    vue-qriously渲染出来是

    <div>
        <canvas width="80" width="80"></canvas>
    </div>
    

    于是我可以把生成的imgSrc资源,

    <template>
    <div>
        <canvas width="160" width="160" v-show="false"></canvas>
        <img class="img" :src="imgSrc"/>
    </div>
    </template>
    <style lang="less">
    .img{
        width: 80px;
        height: 80px;
    }
    </style>
    

    这就实现了下载的资源是160 * 160,用样式控制图片显示80 * 80
    代码写完,觉得应该给vue-qriously写个pr,实现 不仅仅是渲染canvas,而是让大家可以选择时img还是canvas。又去翻了翻这个项目的issue,有一个issue链接:how to make this canvas exchange to img 就是说的这个。还没关闭。

    i think u can create type let user select img and canvas.
    
    // 有一个回复
    If you want to make it become downloadable, maybe you can transform it from canvas easily by canvas.toDataURL()
    

    文章写到这里,我发现这样似乎不太妥。我的场景,是点击时显示浮层(浮层有二维码和复制链接地址和下载二维码按钮等),获取canvas元素,去转成img src,再去渲染到页面,而且图片可能会闪,因为是实际大小是160,样式强制控制在80
    何不生成两份,一份是用来获取资源下载的。一份用来显示的。嗯,之后去优化下。
    顺带说一下,复制粘贴

    cliploard 复制粘贴

    老模块中是用的cliploardclipboard github仓库。就是我引入的。

    新模块还没使用过,但依然使用这个。

    // 安装
    // npm install clipboard --save
    <template @click="Clip($event, '快来复制')"><template>
    // 封装成一个函数
    import Clipboard from 'clipboard';
    export default function Clip(event,text) {
      const clipboard = new Clipboard(event.target, {
        text: () => text
      });
      clipboard.on('success', () => {
        console.log('复制成功');
        clipboard.off('error');
        clipboard.off('success');
        clipboard.destroy();
      });
      clipboard.on('error', () => {
        console.log('复制失败,请刷新试试');
        clipboard.off('error')
        clipboard.off('success')
        clipboard.destroy()
      });
      clipboard.onClick(event);
    }
    

    当然也可以封装成vue指令。
    可以参考vue-element-admin这个项目
    之前我看的时候还是3000star,现在1.2w+,说明值得学习。
    另外推荐awesomes网站 工具类库合集

    小结

    1、引入第三方插件等使用时,多查看github 文档 issue等,在技术社区搜索别人使用的方案。
    2、选用第三方插件时,尽可能挑选star比较多的,issue处理比较及时的,在更新维护的。
    3、富余时间可以多研究下别人的项目是如何组织文件,和实现的一些常用功能的。
    4、尽可能去优化自己的代码,总结回顾。

    文章首发于vue 2.x项目 vue-qriously 生成二维码并下载、cliploard复制粘贴

    相关文章

      网友评论

      本文标题:vue 2.x项目 vue-qriously 生成二维码并下载、

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