vue 2.x項(xiàng)目 vue-qriously 生成二維碼并下載、cliploard復(fù)制粘貼

近日,重構(gòu)項(xiàng)目某一老模塊時(shí),有一個(gè)功能是生成二維碼并下載,還可以復(fù)制鏈接。列表每項(xiàng)都有二維碼、下載二維碼和復(fù)制鏈接和列表上方總的二維碼。
老模塊是用的qrocode中文文檔,qrcode github。

先想著新模塊中是否有生成二維碼的插件,看了下package.json。
有安裝一個(gè)vue-qriously。但搜索了一下,竟然沒(méi)有使用,可能是因?yàn)楹芏喽S碼都是后端生成返回鏈接給前端的。而在其他H5、微信項(xiàng)目中使用了??戳讼逻@個(gè)項(xiàng)目star數(shù)是113。但我不想重新引入老模塊的qrcodejs,重新引入其他的二維碼插件,相對(duì)比較麻煩。于是就保持統(tǒng)一用vue-qriously了。
猜想當(dāng)時(shí)引入這個(gè)是vue 資源合集awesome-vue中,qrcode相關(guān)第一個(gè)就是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 {
            // 可以自定義,必填項(xiàng)。
            value: 'http://lxchuan12.github.io/',
            // 二維碼大小 默認(rèn) 100
            size: 80,
            // 背景透明度,默認(rèn)透明 0 
            backgroundAlpha: 1,
        }
    }
}
</script>

更多參數(shù)配置可以查看:github 倉(cāng)庫(kù) v-qriously.vue源碼
查看代碼可以發(fā)現(xiàn),開(kāi)頭引用了qrious,這個(gè)star就多一點(diǎn),600多。

import Qrious from 'qrious'

qrious github 地址
qrious 文檔

下載二維碼

粗略的翻看下以上相關(guān)文檔,寫(xiě)完正準(zhǔn)備要做下載功能。這時(shí)發(fā)現(xiàn),哎呀,竟然就是只生成了一個(gè)canvas
于是百度(暴露了用百度...我也想用谷歌,但現(xiàn)在不行...)了下canvas如何轉(zhuǎn)圖片。
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+'"/>');
// 搜索到一些其他的方案,感覺(jué)挺麻煩。
// 嗯,這個(gè)簡(jiǎn)單。想著我們項(xiàng)目兼容性沒(méi)什么要求,于是就用這個(gè)了。

生成了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);

但這樣寫(xiě)也相對(duì)比較麻煩。
項(xiàng)目中封裝了一個(gè)v-click指令。

/**
 * vClick 觸發(fā)點(diǎn)擊
 * @type {Object}
 */
export const vClick = {
    directives: {
        click: {
            /**
             * 值更新時(shí)候觸發(fā)點(diǎn)擊
             * @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>

代碼寫(xiě)到這里,嗯,實(shí)現(xiàn)完了下載。但又發(fā)現(xiàn)又一需求,顯示大小是80 * 80,下載需要是160 * 160。

顯示大小和下載大小不一樣。

參考了下老模塊,qrcodejs渲染出來(lái)的html,

//  跟這個(gè)類(lèi)似
<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渲染出來(lái)是

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

這就實(shí)現(xiàn)了下載的資源是160 * 160,用樣式控制圖片顯示80 * 80。
代碼寫(xiě)完,覺(jué)得應(yīng)該給vue-qriously寫(xiě)個(gè)pr,實(shí)現(xiàn) 不僅僅是渲染canvas,而是讓大家可以選擇時(shí)img還是canvas。又去翻了翻這個(gè)項(xiàng)目的issue,有一個(gè)issue鏈接:how to make this canvas exchange to img 就是說(shuō)的這個(gè)。還沒(méi)關(guān)閉。

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

文章寫(xiě)到這里,我發(fā)現(xiàn)這樣似乎不太妥。我的場(chǎng)景,是點(diǎn)擊時(shí)顯示浮層(浮層有二維碼和復(fù)制鏈接地址和下載二維碼按鈕等),獲取canvas元素,去轉(zhuǎn)成img src,再去渲染到頁(yè)面,而且圖片可能會(huì)閃,因?yàn)槭菍?shí)際大小是160,樣式強(qiáng)制控制在80
何不生成兩份,一份是用來(lái)獲取資源下載的。一份用來(lái)顯示的。嗯,之后去優(yōu)化下。
順帶說(shuō)一下,復(fù)制粘貼

cliploard 復(fù)制粘貼

老模塊中是用的cliploardclipboard github倉(cāng)庫(kù)。就是我引入的。

新模塊還沒(méi)使用過(guò),但依然使用這個(gè)。

// 安裝
// npm install clipboard --save
<template @click="Clip($event, '快來(lái)復(fù)制')"><template>
// 封裝成一個(gè)函數(shù)
import Clipboard from 'clipboard';
export default function Clip(event,text) {
  const clipboard = new Clipboard(event.target, {
    text: () => text
  });
  clipboard.on('success', () => {
    console.log('復(fù)制成功');
    clipboard.off('error');
    clipboard.off('success');
    clipboard.destroy();
  });
  clipboard.on('error', () => {
    console.log('復(fù)制失敗,請(qǐng)刷新試試');
    clipboard.off('error')
    clipboard.off('success')
    clipboard.destroy()
  });
  clipboard.onClick(event);
}

當(dāng)然也可以封裝成vue指令。
可以參考vue-element-admin這個(gè)項(xiàng)目
之前我看的時(shí)候還是3000star,現(xiàn)在1.2w+,說(shuō)明值得學(xué)習(xí)。
另外推薦awesomes網(wǎng)站 工具類(lèi)庫(kù)合集

關(guān)于

作者:常以軒轅Rowboat為名混跡于江湖。前端路上 | PPT愛(ài)好者 | 所知甚少,唯善學(xué)。
個(gè)人博客
segmentfault個(gè)人主頁(yè)
掘金個(gè)人主頁(yè)
知乎
github

小結(jié)

1、引入第三方插件等使用時(shí),多查看github 文檔 issue等,在技術(shù)社區(qū)搜索別人使用的方案。
2、選用第三方插件時(shí),盡可能挑選star比較多的,issue處理比較及時(shí)的,在更新維護(hù)的。
3、富余時(shí)間可以多研究下別人的項(xiàng)目是如何組織文件,和實(shí)現(xiàn)的一些常用功能的。
4、盡可能去優(yōu)化自己的代碼,總結(jié)回顧。

文章首發(fā)于Segmentfault vue 2.x項(xiàng)目 vue-qriously 生成二維碼并下載、cliploard復(fù)制粘貼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,672評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,965評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,019評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,188評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,252評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,590評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,766評(píng)論 25 708
  • 轉(zhuǎn)載 :OpenDiggawesome-github-vue 是由OpenDigg整理并維護(hù)的Vue相關(guān)開(kāi)源項(xiàng)目庫(kù)...
    果汁密碼閱讀 23,168評(píng)論 8 124
  • 他像是個(gè)住在封閉城堡里的人,四周都是銅墻鐵壁,只留了一扇透明的窗戶,從后面默默地窺探外面的人,必須非常不動(dòng)聲色,才...
    就叫錦鯉閱讀 172評(píng)論 0 0
  • 作別江南的小鎮(zhèn),又扎入江南的小城。 你帶著行李,帶著讓雨搖曳的笑靨,帶著一襲及地的白色長(zhǎng)裙,在站臺(tái)等待。我?guī)е畠?..
    咖啡再續(xù)杯閱讀 309評(píng)論 0 0
  • 1. Day1 mock數(shù)據(jù) 為什么要mock數(shù)據(jù)從發(fā)布建數(shù)據(jù)比較麻煩or發(fā)布端還沒(méi)有做好;后端api格式已經(jīng)定好...
    求疵閱讀 530評(píng)論 0 0