当前位置: 代码网 > it编程>前端脚本>Vue.js > Vue3+TypeScript实现二维码生成组件

Vue3+TypeScript实现二维码生成组件

2024年05月26日 Vue.js 我要评论
简介在 web 应用中,生成二维码是常见的需求。本文介绍如何用 vue3 和 typescript 开发一个二维码生成组件,支持生成图片或 canvas 形式的二维码,并提供丰富的配置选项。技术栈vu

简介

在 web 应用中,生成二维码是常见的需求。本文介绍如何用 vue3 和 typescript 开发一个二维码生成组件,支持生成图片或 canvas 形式的二维码,并提供丰富的配置选项。

技术栈

  • vue3
  • typescript
  • element plus
  • qrcode

组件功能

  • 支持生成图片和 canvas 形式的二维码: 可以根据需求选择生成图片或 canvas 形式的二维码。
    • 自定义配置选项: 提供丰富的配置选项,如二维码大小、图标大小、二维码颜色、容错级别等。
  • 支持lgog二维码: canvas 形式下支持配置logo二维码。
  • 二维码预览: 图片形式下支持二维码预览功能。
  • 下载: 组件内提供下载二维码到本地的方法。

组件代码

生成uuid方法,防止在 canvas 形式下同一页面生成多个二维码时导致 canvasid 重复

/**
 * @description 生成唯一 uuid
 * @return string
 */
export function generateuuid() {
	if (typeof crypto === "object") {
		if (typeof crypto.randomuuid === "function") {
			return crypto.randomuuid();
		}
		if (typeof crypto.getrandomvalues === "function" && typeof uint8array === "function") {
			const callback = (c: any) => {
				const num = number(c);
				return (num ^ (crypto.getrandomvalues(new uint8array(1))[0] & (15 >> (num / 4)))).tostring(16);
			};
			return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, callback);
		}
	}
	let timestamp = new date().gettime();
	let performancenow = (typeof performance !== "undefined" && performance.now && performance.now() * 1000) || 0;
	return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
		let random = math.random() * 16;
		if (timestamp > 0) {
			random = (timestamp + random) % 16 | 0;
			timestamp = math.floor(timestamp / 16);
		} else {
			random = (performancenow + random) % 16 | 0;
			performancenow = math.floor(performancenow / 16);
		}
		return (c === "x" ? random : (random & 0x3) | 0x8).tostring(16);
	});
}

以下是组件的核心代码:

<script setup lang="ts">
import { ref, onmounted, computed } from "vue";
import qrcode, { type qrcoderenderersoptions } from "qrcode";
import { generateuuid } from "@/utils/util";

interface qrcodeprops {
	type?: "canvas" | "img"; // 二维码类型 ==> 默认img, img 支持预览,canvas支持logo
	size?: number; // 二维码大小 ==> 默认200
	iconsize?: number; // 二维码图标大小 ==> 默认40
	content: string; // 二维码内容 ==> 必填
	logo?: string; // 二维码logo ==> 默认无
	options?: qrcoderenderersoptions; // 二维码配置 ==> 默认无
	errorlevel?: "l" | "m" | "q" | "h"; // 二维码容错级别 ==> 默认h
}

// 接收父组件参数并设置默认值
const props = withdefaults(defineprops<qrcodeprops>(), {
	type: "img",
	size: 200,
	iconsize: 40,
	errorlevel: "h"
});

const qrcodeurl = ref<string>("");
const canvasid = ref("canvas" + generateuuid());
const loading = ref(true);

const qrcodestyle = computed(() => {
	return {
		width: props.size + "px",
		height: props.size + "px"
	};
});

// 生成二维码
const initqrcode = async () => {
	if (props.type === "canvas") {
		const canvasref: any = await qrcode.tocanvas(document.getelementbyid(canvasid.value), props.content, {
			width: props.size,
			margin: 2,
			errorcorrectionlevel: props.errorlevel,
			...props.options
		});
		if (props.logo) {
			const ctx = canvasref.getcontext("2d");
			const iconbgw = props.iconsize + 5;
			const iconbgh = props.iconsize + 5;
			const iconbgx = (canvasref.width - iconbgw) / 2;
			const iconbgy = (canvasref.width - iconbgh) / 2;
			ctx.fillstyle = "#fff";
			ctx.fillrect(iconbgx, iconbgy, iconbgw, iconbgh);
			// logo
			const iconx = (canvasref.width - props.iconsize) / 2;
			const icony = (canvasref.width - props.iconsize) / 2;
			const image = new image();
			image.crossorigin = "anonymous"; // 设置图片的跨域属性
			image.onload = () => {
				ctx.drawimage(image, iconx, icony, props.iconsize, props.iconsize);
				qrcodeurl.value = canvasref.todataurl();
			};
			image.src = props.logo;
		} else {
			qrcodeurl.value = canvasref.todataurl();
		}
		loading.value = false;
	} else {
		const url = await qrcode.todataurl(props.content, {
			width: props.size,
			margin: 2,
			errorcorrectionlevel: props.errorlevel,
			...props.options
		});
		qrcodeurl.value = url;
		loading.value = false;
	}
};

// 下载二维码
const downloadqrcode = (filename: string = generateuuid(), filetype: string = ".png") => {
	const exportfile = document.createelement("a");
	exportfile.style.display = "none";
	exportfile.download = `${filename}${filetype}`;
	exportfile.href = qrcodeurl.value;
	document.body.appendchild(exportfile);
	exportfile.click();
	// 去除下载对 url 的影响
	document.body.removechild(exportfile);
};

onmounted(() => {
	initqrcode();
});

defineexpose({
	downloadqrcode
});
</script>

<template>
	<div :style="qrcodestyle" overflow-hidden rounded-lg border border-slate-300 border-solid v-loading="loading">
		<imagepreview :width="qrcodestyle.width" :height="qrcodestyle.height" v-if="type === 'img'" :image-url="qrcodeurl" />
		<canvas v-else :style="qrcodestyle" :id="canvasid"></canvas>
	</div>
</template>

<style lang="scss" scoped></style>

总结

通过结合 vue3、typescript 和其他现代前端技术,我们打造了一个功能丰富的二维码生成组件。该组件支持多种形式展示,包括图片和 canvas 二维码。用户可以轻松放大预览图片二维码,或者通过 canvas 添加自定义 logo。除此之外,在组件内还提供了便捷的下载功能。这一解决方案为开发者在 web 应用中集成二维码生成功能提供了便捷而强大的工具。

希望这篇文章能够帮助你更好地了解如何使用 vue3 和 typescript 实现 生成二维码功能!如果你有任何问题或建议,请随时提出。

以上就是vue3+typescript实现二维码生成组件的详细内容,更多关于vue3+typescript二维码的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com