純前端實(shí)現(xiàn)一鍵生成二維碼,打開新頁(yè)面展示二維碼(原來(lái)可以這么簡(jiǎn)單)
前言:相信不少同學(xué)在實(shí)際工作中做項(xiàng)目的時(shí)候會(huì)遇到點(diǎn)擊形成二維碼,跳轉(zhuǎn)新的頁(yè)面展示二維碼的項(xiàng)目需求。解決問題的思路實(shí)際有很多種,今天筆者介紹一個(gè)簡(jiǎn)單實(shí)現(xiàn)的思路,供大家參考,實(shí)際實(shí)現(xiàn)這個(gè)小功能其實(shí)是特別簡(jiǎn)單的。
一 demo效果

二 思考如何讓實(shí)現(xiàn)
如何實(shí)現(xiàn)這個(gè)需求呢
首先我們需要生成二維碼,而且要打開一個(gè)新的頁(yè)面展示,那么我們需要img標(biāo)簽來(lái)展示圖片的載體,那么生成圖片src必不可少的。無(wú)論我們的項(xiàng)目是spa,還是多頁(yè)面應(yīng)用,我們這里都要用base64儲(chǔ)存圖片的信息。所以需要把生成的二維碼轉(zhuǎn)化成base64。接下來(lái)讓我們整理一下思路。
梳理具體思路
第一步:我們需要將目標(biāo)二維碼鏈接生成二維碼。
第二步:將上一步生成的二維碼轉(zhuǎn)化成base64格式url,并保存url。
第三步:打開新頁(yè)面,獲取保存的url,展示生成的二維碼。
1 引入arale-qrcode庫(kù)
首先我們需要將連接繪制成二維碼,那么我在這里給大家推薦一個(gè)形成二維碼的庫(kù)arale-qrcode。它可以根據(jù)傳入的二維碼鏈接生成svg或table形式的dom節(jié)點(diǎn)。
import AraleQRCode from 'arale-qrcode'
const result = new AraleQRCode({
render: "svg", /* 生成的類型 'svg' or 'table dom元素類型 */
text:'https://juejin.im/post/6895011670301605896', /* 二維碼的鏈接*/
size: 100 /* 二維碼的大小 */
})
console.log(result)
我們看看AraleQRCode把二維碼鏈接變成了什么東西。

沒錯(cuò),AraleQRCode?把我們的二維碼變成了,真是的dom的節(jié)點(diǎn),如果是在當(dāng)前頁(yè)面展示,現(xiàn)在已經(jīng)滿足需求了,然而這不是我們想要的,因?yàn)槲覀兊囊谛碌捻?yè)面中展示生成的二維碼。接下來(lái)我們想的是怎么把當(dāng)前的node節(jié)點(diǎn)轉(zhuǎn)化成base64
2?XMLSerializer序列化xml
接下來(lái)我們可能用到一個(gè)不怎么常用的api XMLSerializer,它的作用是什么??XMLSerializer?對(duì)象使你能夠把一個(gè)XML?文檔或Node?對(duì)象轉(zhuǎn)化或“序列化”為未解析的?XML?標(biāo)記的一個(gè)字符串。具體使用我們不需要帶參數(shù)去實(shí)例化它,然后調(diào)用serializeToString方法?node對(duì)象變成一個(gè)字符串。
例子:
const div = document.createElement('div')
div.innerText = 'hello,world'
const result = new XMLSerializer().serializeToString(div)
console.log(result)
我們看看XMLSerializer到底做了什么。

沒錯(cuò),這樣就將一個(gè)真實(shí)dom變成了字符串。回到正題上來(lái),我們需要上一步生成的svg xml文檔轉(zhuǎn)換成字符串。
import AraleQRCode from 'arale-qrcode'
const result = new AraleQRCode({
render: "svg", /* 生成的類型 'svg' or 'table dom元素類型 */
text:'https://juejin.im/post/6895011670301605896', /* 二維碼的鏈接*/
size: 100 /* 二維碼的大小 */
})
const svgXml = new XMLSerializer().serializeToString(result)
console.log(svgXml)
打印結(jié)果如下:

注意:XMLSerializer?對(duì)于ie瀏覽器存在著兼容性,所以我們要做額外的兼容處理。
3 window.btoa轉(zhuǎn)化成url,跨頁(yè)面?zhèn)鬟furl
接下來(lái)我們需要把新出爐的svg字符竄轉(zhuǎn)成base64格式。我們可以通過(guò)?window.btoa方法。創(chuàng)建一個(gè)base-64?編碼的字符串。除了用到window.btoa外,我們還需要二次轉(zhuǎn)碼?encodeURIComponent?字符串作為?URI?組件進(jìn)行編碼和解碼。?unescape?可對(duì)編碼的字符串進(jìn)行解碼。
const src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgXml)))
終于生成了我們想要的base64格式的圖片url,接下來(lái)我們做的是跨頁(yè)面?zhèn)鬟furl。
這里有一個(gè)小技巧,由于我們用的是打開一個(gè)新窗口,而且生成的base64文件不會(huì)很大,所以我們這里用本地存儲(chǔ)localStorage?再好不過(guò)。
localStorage.setItem('image',src)
window.open('http://localhost:8888/image')
將上一步的src保存起來(lái)。這樣就完成了url的生成到保存。
完整的代碼如下
生成二維碼頁(yè)面
const index = () => {
const text = ()=>{
const result = new AraleQRCode({
render: "svg", /* 生成的類型 'svg' or 'table dom元素類型 */
text:'https://juejin.im/post/6895011670301605896', /* 二維碼的鏈接*/
size: 100 /* 二維碼的大小 */
})
const svgXml = new XMLSerializer().serializeToString(result)
const src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgXml)))
localStorage.setItem('image',src)
window.open('http://localhost:8888/image')
}
return <div className="page" >
<p className="cur" > 當(dāng)前url: <span> https://juejin.im/post/6895011670301605896 span> p>
<div className="btns" >
<button onClick={text } >點(diǎn)擊生成二維碼button>
div>
div>
}
接受二維碼頁(yè)面
function index(){
const img:any = localStorage.getItem('image')
localStorage.removeItem('image')
return <div className="mast" >
<div className="img_content" > <img src={img} />div>
div>
}
注意:當(dāng)我們接受到url的時(shí)候,別忘了清除本地緩存。
三 寫在后面
上面總結(jié)了一個(gè)生成+跨頁(yè)面展現(xiàn)二維碼的具體實(shí)現(xiàn)方案,而且已經(jīng)應(yīng)用在真正的項(xiàng)目中了,在實(shí)際工作中,同學(xué)們?nèi)绻龅筋愃茊栴},希望這篇文章能給大家?guī)?lái)解決此類問題的思路。
最后謝謝大家閱讀,大家如果覺得還不錯(cuò)的話,就 點(diǎn)贊 + 關(guān)注 一波,持續(xù)分享技術(shù)文章。

