Vue で QR コードを表示する(TypeScript 対応)
qrcode
パッケージを使用して Vue で QR コード生成する TypeScript での 実装例です。Vue に依存しない qrcode
パッケージを使用するので、Vue 以外でも使用できます。
やりたいこと
qrcode というパッケージを使用して Vue で QR コード生成を実装したいと思います。
Vue に特化した QR コード生成パッケージ vue-qrcode もあるのですが、Vue と密結合していると、Vue 自体のバージョンアップが発生した際に、そのバージョンアップの対応がなされるまで使用できないといったリスクがあります。また Vue を React や Svelte に変更しても同じパッケージを使用できるのもメリットです。
ちなみに vue-qrcode
も内部的には qrcode
を使ってます。
環境
- TypeScript
- 5.0.2
- Vite
- 4.4.5
- Vue
- 3.3.4
- QRCode
- 1.5.3
準備
qrcode
パッケージのインストール
npm install --save qrcode
TypeScript の場合は @types/qrcode も追加します。
npm install --save-dev @types/qrcode
実装例
QRCode
をインポートし、QRCode.toDataURL()
に QR コード化したい文字列を渡すことで データ URL 化された QR コードの画像 (デフォルトは PNG 形式) を得ることができます。
QRCode.toDataURL()
の仕様は以下の通りです。
toDataURL(text, [options], [cb(error, url)])
toDataURL(canvasElement, text, [options], [cb(error, url)])
Returns a Data URI containing a representation of the QR Code image. If provided, canvasElement will be used as canvas to generate the data URI. - qrcode - npm
img
要素に描画
QRCode.toDataURL()
はデータ URL を返すので、以下の実装例のように img
要素の src
属性に直接渡すことで QR コード画像を表示することができます。
<script setup lang="ts">
import { ref } from "vue";
import QRCode from "qrcode";
const text = ref<string>("");
const src = ref<string>("");
const handlerTextChange = async (e: Event) => {
const target = e.target as HTMLInputElement;
text.value = target.value;
src.value = await QRCode.toDataURL(target.value);
}
</script>
<template>
<div class="container">
<input type="text" :value="text" @change="handlerTextChange"/>
<img :src="src" />
<a v-if="src" :href="src" download="qr.png">Download</a>
</div>
</template>
<style scoped>
.container {
display: flex;
flex-direction: column;
box-sizing: border-box;
width: 375px;
margin: 0 auto;
padding: 24px;
text-align: center;
}
img {
display: block;
width: 150px;
margin: 0 auto;
}
</style>
こんな感じになります。
canvas
要素に描画
QRCode.toDataURL()
は canvas
要素を渡すことで、その canvas
要素に直接 QR コードを描画することもできます。
以下はその実装例です。
<script setup lang="ts">
import { ref } from "vue";
import QRCode from "qrcode";
const text = ref<string>("");
const canvas = ref<HTMLCanvasElement>();
const dataUrl = ref<string>("");
const handlerTextChange = async (e: Event) => {
if (!canvas.value) return;
const target = e.target as HTMLInputElement;
text.value = target.value;
await QRCode.toDataURL(canvas.value, target.value);
dataUrl.value = canvas.value.toDataURL();
}
</script>
<template>
<div class="container">
<input type="text" :value="text" @change="handlerTextChange"/>
<canvas ref="canvas"></canvas>
<a v-if="dataUrl" :href="dataUrl" download="qr.png">Download</a>
</div>
</template>
<style scoped>
.container {
display: flex;
flex-direction: column;
box-sizing: border-box;
width: 375px;
margin: 0 auto;
padding: 24px;
text-align: center
}
canvas {
display: block;
margin: 0 auto;
}
</style>
こんな感じになります。
canvas
要素への描画は QRCode.toCanvas()
を使用しても可能です。
toCanvas(canvasElement, text, [options], [cb(error)])
toCanvas(text, [options], [cb(error, canvas)])
Draws qr code symbol to canvas. If canvasElement is omitted a new canvas is returned. - qrcode - npm
その他
SVG 文字列を返す QRCode.toString()
メソッドやサーバーサイドで使える QRCode.toFile()
など便利なメソッドを具備しています。今回試してはいませんが、SJIS 対応しているようで、まだまだ SJIS に悩まされる日本の IT 業界には嬉しい対応です。
また各メソッドに共通してオプションを渡すことができます。詳細は こちら を参照してもらえればと思いますが、エラー訂正レベル等の QR コード自体のオプションや QR コードの色や余白等の見栄えに関するオプションが用意されています。
あとがき
qrcode
パッケージを使用して QR コード生成をしてみました。qrcode
はシンプルな API で非常に使いやすいです。今回は Vue で試しましたが、フロントのベースライブラリに依存しないので、React や Svelte でも使えるのがいいところです。機会があれば別ライブラリでも試してみようと思います。