Commit 2b76b88481dab2c580e684987a80028710d4698d

Authored by Netfan
Committed by GitHub
1 parent 9d195462

feat(qrcode): custom drawing support (#580)

src/components/Qrcode/src/index.vue
... ... @@ -8,6 +8,7 @@
8 8 import { toCanvas, QRCodeRenderersOptions, LogoType } from './qrcodePlus';
9 9 import { toDataURL } from 'qrcode';
10 10 import { downloadByUrl } from '/@/utils/file/download';
  11 + import { QrcodeDoneEventParams } from './types';
11 12  
12 13 export default defineComponent({
13 14 name: 'QrCode',
... ... @@ -38,10 +39,9 @@
38 39 validator: (v: string) => ['canvas', 'img'].includes(v),
39 40 },
40 41 },
41   - emits: { done: (url: string) => !!url, error: (error: any) => !!error },
  42 + emits: { done: (data: QrcodeDoneEventParams) => !!data, error: (error: any) => !!error },
42 43 setup(props, { emit }) {
43 44 const wrapRef = ref<HTMLCanvasElement | HTMLImageElement | null>(null);
44   - const urlRef = ref<string>('');
45 45 async function createQrcode() {
46 46 try {
47 47 const { tag, value, options = {}, width, logo } = props;
... ... @@ -58,8 +58,7 @@
58 58 content: renderValue,
59 59 options: options || {},
60 60 });
61   - urlRef.value = url;
62   - emit('done', url);
  61 + emit('done', { url, ctx: (wrapEl as HTMLCanvasElement).getContext('2d') });
63 62 return;
64 63 }
65 64  
... ... @@ -70,8 +69,7 @@
70 69 ...options,
71 70 });
72 71 (unref(wrapRef) as HTMLImageElement).src = url;
73   - urlRef.value = url;
74   - emit('done', url);
  72 + emit('done', { url });
75 73 }
76 74 } catch (error) {
77 75 emit('error', error);
... ... @@ -81,7 +79,13 @@
81 79 * file download
82 80 */
83 81 function download(fileName?: string) {
84   - const url = unref(urlRef);
  82 + let url = '';
  83 + const wrapEl = unref(wrapRef);
  84 + if (wrapEl instanceof HTMLCanvasElement) {
  85 + url = wrapEl.toDataURL();
  86 + } else if (wrapEl instanceof HTMLImageElement) {
  87 + url = wrapEl.src;
  88 + }
85 89 if (!url) return;
86 90 downloadByUrl({
87 91 url,
... ...
src/components/Qrcode/src/types.ts
... ... @@ -31,3 +31,8 @@ export type ToCanvasFn = (options: RenderQrCodeParams) =&gt; Promise&lt;unknown&gt;;
31 31 export interface QrCodeActionType {
32 32 download: (fileName?: string) => void;
33 33 }
  34 +
  35 +export interface QrcodeDoneEventParams {
  36 + url: string;
  37 + ctx?: CanvasRenderingContext2D | null;
  38 +}
... ...
src/views/demo/comp/qrcode/index.vue
... ... @@ -58,6 +58,19 @@
58 58 <CollapseContainer title="配置大小示例" class="text-center qrcode-demo-item">
59 59 <QrCode :value="qrCodeUrl" :width="300" />
60 60 </CollapseContainer>
  61 +
  62 + <CollapseContainer title="扩展绘制示例" class="text-center qrcode-demo-item">
  63 + <QrCode
  64 + :value="qrCodeUrl"
  65 + :width="200"
  66 + :options="{ margin: 5 }"
  67 + ref="qrDiyRef"
  68 + :logo="LogoImg"
  69 + @done="onQrcodeDone"
  70 + />
  71 + <a-button class="mb-2" type="primary" @click="downloadDiy"> 下载 </a-button>
  72 + <div class="msg"> 要进行扩展绘制则不能将tag设为img </div>
  73 + </CollapseContainer>
61 74 </div>
62 75 </PageWrapper>
63 76 </template>
... ... @@ -73,16 +86,36 @@
73 86 components: { CollapseContainer, QrCode, PageWrapper },
74 87 setup() {
75 88 const qrRef = ref<Nullable<QrCodeActionType>>(null);
  89 + const qrDiyRef = ref<Nullable<QrCodeActionType>>(null);
76 90 function download() {
77 91 const qrEl = unref(qrRef);
78 92 if (!qrEl) return;
79 93 qrEl.download('文件名');
80 94 }
  95 + function downloadDiy() {
  96 + const qrEl = unref(qrDiyRef);
  97 + if (!qrEl) return;
  98 + qrEl.download('Qrcode');
  99 + }
  100 +
  101 + function onQrcodeDone({ ctx }) {
  102 + if (ctx instanceof CanvasRenderingContext2D) {
  103 + // 额外绘制
  104 + ctx.fillStyle = 'black';
  105 + ctx.font = '16px "微软雅黑"';
  106 + ctx.textBaseline = 'bottom';
  107 + ctx.textAlign = 'center';
  108 + ctx.fillText('你帅你先扫', 100, 195, 200);
  109 + }
  110 + }
81 111 return {
  112 + onQrcodeDone,
82 113 qrCodeUrl,
83 114 LogoImg,
84 115 download,
  116 + downloadDiy,
85 117 qrRef,
  118 + qrDiyRef,
86 119 };
87 120 },
88 121 });
... ...