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

近日,重构项目某一老模块时,有一个功能是生成二维码并下载,还可以复制链接。列表每项都有二维码、下载二维码和复制链接和列表上方总的二维码。
老模块是用的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网站 工具类库合集

关于

作者:常以轩辕Rowboat为名混迹于江湖。前端路上 | PPT爱好者 | 所知甚少,唯善学。
个人博客
segmentfault个人主页
掘金个人主页
知乎
github

小结

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,747评论 25 707
  • 转载 :OpenDiggawesome-github-vue 是由OpenDigg整理并维护的Vue相关开源项目库...
    果汁密码阅读 23,100评论 8 124
  • 他像是个住在封闭城堡里的人,四周都是铜墙铁壁,只留了一扇透明的窗户,从后面默默地窥探外面的人,必须非常不动声色,才...
    就叫锦鲤阅读 162评论 0 0
  • 作别江南的小镇,又扎入江南的小城。 你带着行李,带着让雨摇曳的笑靥,带着一袭及地的白色长裙,在站台等待。我带着女儿...
    咖啡再续杯阅读 297评论 0 0
  • 1. Day1 mock数据 为什么要mock数据从发布建数据比较麻烦or发布端还没有做好;后端api格式已经定好...
    求疵阅读 523评论 0 0