vue3实现电子签名的方法

vue3实现电子签名且对电子签名可进行修改画笔粗细、画笔颜色、撤销、清屏、保存等功能。

实现效果:查看源码

第一种:通过canvas

javascript 复制代码
<div class="signaturePad-Box w100 h100 flex-center">
	<el-space class="mb10" size="large">
		<div>
			<el-text>画笔粗细:</el-text>
			<el-input-number v-model="state.signOptions.lineWidth" :min="2" :max="10" :step="1" @change="initCanvas" />
		</div>
		<div>
			<el-text>画笔颜色:</el-text>
			<el-color-picker v-model="state.signOptions.penColor" color-format="hex" @blur="initCanvas"> 
		</el-color-picker></div>
	</el-space>
	
	<canvas ref="canvas" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas>
	
	<el-space class="mt10">
		<el-button  @click="clear">清除</el-button>
		<el-button type="success" @click="view">查看</el-button>
		<el-button type="primary" @click="save">保存</el-button>
	</el-space>
	
	
	<el-dialog v-model="state.dialogVisible" title="查看图片"  >
		<el-image :src="state.dataURL" />
	    <template #footer>
			<div class="dialog-footer">
				<el-button type="primary" @click="state.dialogVisible = false"> 确定 </el-button>
			</div>
	    </template>
	</el-dialog>
</div>
javascript 复制代码
<script setup>
	import {ref,reactive,onMounted} from "vue";

	const canvas = ref(null);
	const state=reactive({
		dialogVisible:false,
		dataURL:"",
		signOptions: {
			penColor: '#000000',
			lineWidth: 2,
		},
	})

	let isDrawing = false;
	let lastX = 0;
	let lastY = 0;

	/* 初始化画布 */
	const initCanvas = () => {
		const ctx = canvas.value.getContext('2d');
		ctx.strokeStyle = state.signOptions.penColor;
		ctx.lineWidth = state.signOptions.lineWidth;
	}
	/* 开始绘制 */
	const startDrawing = (event) => {
		isDrawing = true;
		[lastX, lastY] = [event.offsetX, event.offsetY];
	}
	/* 绘制线条 */
	const draw = (event) => {
		if (!isDrawing) return;
		const ctx = canvas.value.getContext('2d');
		const currentX = event.offsetX;
		const currentY = event.offsetY;
		ctx.beginPath();
		ctx.moveTo(lastX, lastY);
		ctx.lineTo(currentX, currentY);
		ctx.stroke();
		[lastX, lastY] = [currentX, currentY];
	}
	/* 停止绘制 */
	const stopDrawing = () => {
		isDrawing = false;
	}
	/* 清除画布 */
	const clear = () => {
		const ctx = canvas.value.getContext('2d');
		ctx.clearRect(0, 0, canvas.value.width, canvas.value.height);
	}
	/* 保存签名 */
	const save = () => {
		state.dataURL = canvas.value.toDataURL('image/png');
		console.log('签名地址为:', state.dataURL);
	}
	/* 查看签名 */
	const view=()=>{
		state.dataURL = canvas.value.toDataURL('image/png');
		state.dialogVisible=true;
	}
	onMounted(() => initCanvas());
</script>

第二种:通过vue-signature-pad

安装依赖:

javascript 复制代码
// npm
npm i vue-signature-pad

// yarn
yarn add vue-signature-pad

//pnpm 
pnpm i vue-signature-pad

在main.js里引用依赖:
注:在官网上写的是全局引入非单文件引入

javascript 复制代码
import VueSignaturePad from 'vue-signature-pad';

createApp(App).use(router).use(VueSignaturePad).mount('#app')

实现代码:

javascript 复制代码
<template>
	<div>
		<el-space class="mb10" size="large">
			<div>
				<el-text>画笔粗细:</el-text>
				<el-input-number v-model="state.size" :min="2" :max="10" :step="1" @change="onChange" />
			</div>
			<div>
				<el-text>画笔颜色:</el-text>
				<el-color-picker v-model="state.color" color-format="hex" @change="onChange"> </el-color-picker>
			</div>
		</el-space>

		<VueSignaturePad class="line" ref="signaturePad" :options="signOptions" width="400px" height="200px" />

		<el-space class="mt10">
			<el-button @click="unDoSign">撤销</el-button>
			<el-button @click="clearSign">清屏</el-button>
			<el-button type="primary" @click="saveUploadSign">保存</el-button>
		</el-space>
	</div>
</template>
javascript 复制代码
<script setup>
	import {ref,watch} from "vue";

	const signaturePad = ref();
	
	const signOptions=ref({
		penColor: '#000000',
		minWidth: 1,
		maxWidth:1
	})
	
	const state=ref({
		color:"#000",
		size:1
	})
	
	// 画笔颜色粗细改变时
	const onChange=()=>{
		signOptions.value={
			penColor:state.value.color,
			maxWidth:state.value.size
		}
	}
	
	// 撤销电子签名
	const unDoSign = () => {
		signaturePad.value.undoSignature();
	};

	// 清空电子签名
	const clearSign = () => {
		signaturePad.value.clearSignature();
	};
	
	// 保存并上传电子签名
	const saveUploadSign = async () => {
		const {isEmpty,data} = signaturePad.value.saveSignature();
		if (isEmpty) return;
		console.log("picture url:",data);
	};

</script>
相关推荐
多客:duokelijie1 天前
代练订单系统选型思路:跨品类游戏接入、订单分层管理、自动结算逻辑拆解!
数据库·mysql·微信小程序·前端框架·uni-app·php·持续部署
AI开源软件2 天前
SpringBoot3+Vue3 财务管理系统如何设计:从业务单据到总账的模块划分
spring boot·vue3·领域建模·会计凭证·ruoyi office·业财协同·财务系统设计
Highcharts.js2 天前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
锋行天下3 天前
Langgraph-cli 本地构建失败,改用服务器docker构建的流程
人工智能·前端框架·全栈
狂潮lister3 天前
🚀 《掘金・挖矿小精灵》完整产品与系统架构设计 & V1.3‑LD‑M 落地工程设计文档(**封档版**)
前端·架构·前端框架
王亚博_Abel3 天前
AI 编程时代怎么选前端框架?同一个应用让 Agent 用 12 种框架各写 5 遍,我整理出这套选型方法
前端·人工智能·前端框架
jktantan5 天前
(二)Vue 3 的 attrs 不是响应式:el-form 扩展属性同步的三种方案
前端·javascript·vue.js·element-plus
Highcharts.js5 天前
Highcharts 集成到 React 或 Vue 项目中时,如何高效地使用 TypeScript技巧?
vue.js·人工智能·react.js·typescript·前端框架·highcharts
江屿风6 天前
【Plain Language Large Model】【从浏览器到全栈:一课精通Node.js三剑客】流食般投喂
笔记·前端框架·npm·node.js·js·npx
Nymph_Zhu6 天前
vue3+element-plus 文件上传
前端·typescript·vue3·element-plus