vben
2020-11-15 661db0c767772bb7a30da9d3eeaf2b47858ccf0b
提交 | 用户 | age
2f6253 1 <template>
2   <div>
3     <component :is="tag" ref="wrapRef"></component>
4   </div>
5 </template>
6 <script lang="ts">
7   import { defineComponent, watchEffect, PropType, ref, unref } from 'vue';
8   import { toCanvas, QRCodeRenderersOptions, LogoType } from './qrcodePlus';
9   import { toDataURL } from 'qrcode';
661db0 10   import { downloadByUrl } from '/@/utils/file/download';
2f6253 11
12   export default defineComponent({
13     name: 'QrCode',
14     emits: { done: (url: string) => !!url, error: (error: any) => !!error },
15     props: {
16       value: {
17         type: [String, Array] as PropType<string | any[]>,
18         default: null,
19       },
20       // 参数
21       options: {
22         type: Object as PropType<QRCodeRenderersOptions>,
23         default: null,
24       },
25       // 宽度
26       width: {
27         type: Number as PropType<number>,
28         default: 200,
29       },
30       // 中间logo图标
31       logo: {
32         type: [String, Object] as PropType<Partial<LogoType> | string>,
33         default: '',
34       },
35       // img 不支持内嵌logo
36       tag: {
37         type: String as PropType<'canvas' | 'img'>,
38         default: 'canvas',
39         validator: (v: string) => ['canvas', 'img'].includes(v),
40       },
41     },
42     setup(props, { emit }) {
43       const wrapRef = ref<HTMLCanvasElement | HTMLImageElement | null>(null);
44       const urlRef = ref<string>('');
45       async function createQrcode() {
46         try {
47           const { tag, value, options = {}, width, logo } = props;
48           const renderValue = String(value);
49           const wrapEl = unref(wrapRef);
50
51           if (!wrapEl) return;
52
53           if (tag === 'canvas') {
54             const url: string = await toCanvas({
55               canvas: wrapEl,
56               width,
57               logo: logo as any,
58               content: renderValue,
59               options: options || {},
60             });
61             urlRef.value = url;
62             emit('done', url);
63             return;
64           }
65
66           if (tag === 'img') {
67             const url = await toDataURL(renderValue, {
68               errorCorrectionLevel: 'H',
69               width,
70               ...options,
71             });
72             (unref(wrapRef) as HTMLImageElement).src = url;
73             urlRef.value = url;
74             emit('done', url);
75           }
76         } catch (error) {
77           emit('error', error);
78         }
79       }
80       /**
81        * file download
82        */
83       function download(fileName?: string) {
84         const url = unref(urlRef);
85         if (!url) return;
86         downloadByUrl({
87           url,
88           fileName,
89         });
90       }
91
92       watchEffect(() => {
93         setTimeout(() => {
94           createQrcode();
95         }, 30);
96       });
97
98       return { wrapRef, download };
99     },
100   });
101 </script>