封装uniapp签字板

新开发的业务涉及到签字功能,由于是动态的表单,无法确定它会出现在哪里,不得已封装模块。
其中涉及到一个难点就是this的指向性问题,
第二个是微信小程序写法,
我这个写法里用了u-view的写法,可以自己修改组件

首先是封装的内容

1、props接收父级传过来的参数,这些数据是因为我是动态多级表单、可按需传值
2、imageUpload是我上传后台的地址。可自己修改,或者自己封装参数
3、this.canvasadd()是定义画布,一定要放在mounted(),放在其他位置会出现this指向性报错,或者返回位置不一致问题。

<template>
	<!-- 签名组件 -->
	<view class="container">
		<view class="fatherWrite" @click="showWrite">
			<div class="sonWrite">
				<text v-if="write">点击签名</text>
			</div>
			<image :src="value" v-model="image" style="border:1px solid #ccc;width: 100%;" />
		</view>
		<uni-popup ref="popup" background-color="#fff" >
			<h1 style="text-align: center;margin: 20rpx;">签字板</h1>
			<uni-row class="demo-uni-row" :gutter='10' style="padding: 20rpx;" >
				<uni-col :span="8">
					<u-button text="取消"   color="linear-gradient(to right, rgb(66, 83, 216), rgb(213, 51, 186))"
						@tap="handleCancel"></u-button>
				</uni-col>
				<uni-col :span="8">
					<u-button text="重写" color="linear-gradient(to right, rgb(66, 83, 216), rgb(213, 51, 186))"
						@tap="handleReset"></u-button>
				</uni-col>
				<uni-col :span="8">
					<u-button text="确认" color="linear-gradient(to right, rgb(66, 83, 216), rgb(213, 51, 186))"
						@tap="handleConfirm"></u-button>
				</uni-col>
			</uni-row>
			<view class="sign-box">
				<canvas class="mycanvas" canvas-id="mycanvas" @touchstart="touchstart" @touchmove="touchmove"
					@touchend="touchend"></canvas>
			</view>

		</uni-popup>
	</view>
</template>
<script>
	var x = 20;
	var y = 20;
	var tempPoint = []; //用来存放当前画纸上的轨迹点
	var id = 0;
	var type = '';
	let that;
	let canvasw;
	let canvash;
	import {
		imageUpload
	} from '@/api/system/applet.js' //
	export default {
		name: 'Handwriting',
		props: {
			image: String, //判断当前是否有照片
			writeIndex: Number, //下标
			writeChildrenIndex: Number, //子级下标
		},
		data() {
			return {
				ctx: '', //绘图图像
				points: [], //路径点集合,
				width: 0,
				height: 0,
				write: true,
				value: this.image,
			};
		},
		mounted() {
			this.canvasadd()
		},
		methods: {
			canvasadd() {
				this.ctx = uni.createCanvasContext('mycanvas', this); //创建绘图对象
				//设置画笔样式
				this.ctx.lineWidth = 4;
				this.ctx.lineCap = 'round';
				this.ctx.lineJoin = 'round';
				that = this;
				uni.getSystemInfo({
					success: function(res) {
						that.width = res.windowWidth;
						that.height = res.windowHeight;
					}
				});
			},
			//签名填写
			showWrite() {
				this.canvasadd()
				if (this.image == null || this.image == '') {
					that.$refs.popup.open('bottom')
				} else {
					uni.showModal({
						content: "是否重写签名",
						cancelText: '取消',
						confirmText: '确定',
						success: function(res) {
							if (res.confirm) {
								that.$refs.popup.open('bottom')
							} else {
								that.$refs.popup.close()
							}
						}
					})
				}
			},
			//触摸开始,获取到起点
			touchstart: function(e) {
				let startX = e.changedTouches[0].x;
				let startY = e.changedTouches[0].y;
				let startPoint = {
					X: startX,
					Y: startY
				};
				/* **************************************************
				    #由于uni对canvas的实现有所不同,这里需要把起点存起来
				 * **************************************************/
				this.points.push(startPoint);
				//每次触摸开始,开启新的路径
				this.ctx.beginPath();
			},
			//触摸移动,获取到路径点
			touchmove: function(e) {
				let moveX = e.changedTouches[0].x;
				let moveY = e.changedTouches[0].y;
				let movePoint = {
					X: moveX,
					Y: moveY
				};
				this.points.push(movePoint); //存点
				let len = this.points.length;
				if (len >= 2) {
					this.draw(); //绘制路径
				}
				tempPoint.push(movePoint);
			},
			// 触摸结束,将未绘制的点清空防止对后续路径产生干扰
			touchend: function() {
				this.points = [];
			},
			/* ***********************************************	
			#   绘制笔迹
			#   1.为保证笔迹实时显示,必须在移动的同时绘制笔迹
			#   2.为保证笔迹连续,每次从路径集合中区两个点作为起点(moveTo)和终点(lineTo)
			#   3.将上一次的终点作为下一次绘制的起点(即清除第一个点)
			************************************************ */
			draw: function() {
				let point1 = this.points[0];
				let point2 = this.points[1];
				this.points.shift();
				this.ctx.lineWidth = 4;
				this.ctx.lineCap = 'round';
				this.ctx.lineJoin = 'round';
				this.ctx.moveTo(point1.X, point1.Y);
				this.ctx.lineTo(point2.X, point2.Y);
				this.ctx.stroke();
				this.ctx.draw(true);
			},
			//取消绘制
			handleCancel() {
				this.handleReset()
				that.$refs.popup.close()	
			},
			//清空画布
			handleReset: function() {
				this.ctx.clearRect(0, 0, that.width, that.height);
				this.ctx.draw(true);
				tempPoint = [];
			},
			//将签名笔迹上传到服务器,并将返回来的地址存到本地
			handleConfirm: function() {
				if (tempPoint.length == 0) {
					that.$modal.msgError('请先签名')
					return;
				} else {
					setTimeout(() => {
						uni.canvasToTempFilePath({
							canvasId: 'mycanvas',
							destWidth: that.width,
							destHeight: that.height,
							fileType: 'png',
							quality: 1, //图片质量
							success: function(res) {
								let tempPath = res.tempFilePath;
								//图片上传拿url
								let data = {
									filePath: tempPath,
									formData: {
										isSystem: 'true'
									}
								}  
								imageUpload(data).then(response => {
									//向上一个页面传参
									that.value = response.data.url
									that.handleReset()
									if (that.value) {
										that.write = false
									}
									that.$emit("writeValue", {
										value: that.value,
										index: that.writeIndex,
										childrenIndex: that.writeChildrenIndex
									}) //返回父级数组下标
									that.$refs.popup.close()
								})
							}
						}, this);
					}, 500)
				}

			}
		}
	};
</script>

<style lang="scss" scoped>
	.sign-box {
		width: 100%;
		height: 100%;
		margin: auto;
	}

	.demo-uni-row {
		margin: 20rpx 20rpx;
		padding: 20rpx;
	}

	.mycanvas {
		margin: 20rpx;
		width: auto;
		height: 60vh;
		border: 1px solid #c6ceff;
		background-color: #ececec;
	}

	.canvsborder {
		position: fixed;
	}

	.fatherWrite {
		position: relative;

		.sonWrite {
			position: absolute;
			color: #ccc;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -50%);
		}
	}
</style>

页面引用

<template>
<view>
//这里简单放置,具体使用,按照规范填写
//普通写法
<uni-forms-item :label="index+1+'、'+item.label" required 
	:rules=item.rules :name="['dynamicLists',index,'images']" >
	<writeName :image="item.images" :value="item.images" :writeIndex="index"
       @writeValue="writeValue"></writeName>
</uni-forms-item>
//多级动态提交
uni-forms-item :label="index+1+'.'+ide+1+'、'+ite.itemName" required
	:rules="[{required: true,errorMessage: '请填写'}]"
	:name="['dynamicLists',index,'children',ide,'images']">
	<writeName  :image="dynamicFormData.dynamicLists[index].children[ide].images"
		:value="dynamicFormData.dynamicLists[index].children[ide].images"
		:writeIndex="index" :writeChildrenIndex="ide"
		@writeValue="writeValueChildren">
	</writeName>
</uni-forms-item>
</view>
</template>
import writeName from '@/pages/public/Handwriting/Handwriting.vue'
export default {
	components: {
			writeName
	},
	methods:{
	  writeValueChildren(val) {
	  	 this.dynamicFormData.dynamicLists[val.index].children[val.childrenIndex].images = val.value
	  },
	  writeValue(val) {
		 this.dynamicFormData.dynamicLists[val.index].images = val.value
	  },
	}
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

以上是我的写法,不足之处还望指出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/278887.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PiflowX组件-ReadFromKafka

ReadFromKafka组件 组件说明 从kafka中读取数据。 计算引擎 flink 有界性 Unbounded 组件分组 kafka 端口 Inport&#xff1a;默认端口 outport&#xff1a;默认端口 组件属性 名称展示名称默认值允许值是否必填描述例子kafka_hostKAFKA_HOST“”无是逗号分隔的Ka…

Zookeeper之手写一个分布式锁

前言 我之前写了一篇快速上手ZK的文章&#xff1a;https://blog.csdn.net/qq_38974073/article/details/135293106 本篇最要是进一步加深学习ZK&#xff0c;算是一次简单的实践&#xff0c;巩固学习成果。 设计一个分布式锁 对锁的基本要求 可重入&#xff1a;允许同一个应…

QT上位机开发(掌握一点c++基础)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 c是c语言的补充和扩展&#xff0c;本身的语法构成也是在一直迭代中。相信很多同学上大学读书的时候&#xff0c;或多或少对c语言有所了解&#xff…

python+django网上银行业务综合管理系统vue_bvj8b

本课题主要研究如何用信息化技术改善传统网上银行综合管理行业的经营和管理模式&#xff0c;简化网上银行综合管理的难度&#xff0c;根据管理实际业务需求&#xff0c;调研、分析和编写系统需求文档&#xff0c;设计编写符合银行需要的系统说明书&#xff0c;绘制数据库结构模…

尽量避免删改List

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

2024收入最高的编程语言

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 1.Python Python 是最流行、用途最广泛的语言之一。它通常用于网络开发、数据科学、机器学习等。 以下是 Python 编程语言的一些主要用途&#xff1a; Web 开发&…

UE4运用C++和框架开发坦克大战教程笔记(十二)(第37~39集)

UE4运用C和框架开发坦克大战教程笔记&#xff08;十二&#xff09;&#xff08;第37~39集&#xff09; 37. 延时事件系统38. 协程逻辑优化更新39. 普通按键绑定 37. 延时事件系统 由于梁迪老师是写 Unity 游戏出身的&#xff0c;所以即便 UE4 有自带的 TimeManager 这样的延时…

基于JAVA的考研专业课程管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…

命令行创建Vue项目

Vue项目创建 1. 打开UI界面 在命令行中&#xff0c;执行如下指令&#xff1a; vue ui 2. 打开项目管理器 3. 创建项目 创建项目的过程&#xff0c;需要联网进行&#xff0c;这可能会耗时比较长的时间&#xff0c;请耐心等待。 windows的命令行&#xff0c;容易卡顿&#xff0c…

WPF 漂亮长方体、正文体简单实现方法 Path实现长方体 正方体方案 WPF快速实现长方体、正方体的方法源代码

这段XAML代码在WPF中实现了一个类似长方体视觉效果的图形 声明式绘制&#xff1a;通过Path、PathGeometry和PathFigure等元素组合&#xff0c;能够以声明方式精确描述长方体每个面的位置和形状&#xff0c;无需编写复杂的绘图逻辑&#xff0c;清晰直观。 层次结构与ZIndex控制…

RabbitMQ之快速入门、上手

前言 学习一样新技术、新框架&#xff0c;最重要的是学习其思想、原理。即原理性思维。 如果是因为工作原因&#xff0c;需要快速上手RabbitMQ&#xff0c;本篇或许适合你。 核心概念 Connection&#xff1a;publisher&#xff0f;consumer 和 broker 之间的 TCP 连接Channel…

Hadoop之Yarn 详细教程

1、yarn 的基本介绍和产生背景 YARN 是 Hadoop2 引入的通用的资源管理和任务调度的平台&#xff0c;可以在 YARN 上运行 MapReduce、Tez、Spark 等多种计算框架&#xff0c;只要计算框架实现了 YARN 所定义的 接口&#xff0c;都可以运行在这套通用的 Hadoop 资源管理和任务调…

nodejs+vue+微信小程序+python+PHP的冷链物流配送系统-计算机毕业设计推荐

对于冷链物流信息调度系统所牵扯的管理及数据保存都是非常多的&#xff0c;例如管理员&#xff1b;首页、用户管理&#xff08;管理员、客户、业务员、配送员&#xff09;客户管理&#xff08;货物信息、客户运输单、车辆信息、调度安排&#xff09;这给管理者的工作带来了巨大…

【机组期末速成】指令系统|机器指令概述|操作数类型与操作类型|寻址方式|指令格式

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;计算机组成原理&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 前言&#xff1a; 一、本章考点总览 二、考点分析 1、以下有关指令系统的说法中错误的是&#xff08; &#xff09;。 2…

【电商项目实战】MD5登录加密及JSR303自定义注解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《电商项目实战》。&#x1f3af;&#x1f3af; &am…

mac安装k8s环境

安装kubectl brew install kubectl 确认一下安装的版本 kubectl version --client 如果想在本地运行kubernetes 需要安装minikube brew install minikube 需要注意安装minikube需要本地的docker服务是启动的 启动 默认连接的是google的仓库 minikube start 指定阿…

下载和安装AD14 - Altium Designer 14.3.20.54863

这个版本应该还支持XP 系统[doge]&#xff0c;总之就是想安装一下&#xff0c;没什么特别的意义。 下载 资源来自毛子网站&#xff1a;https://rutracker.net/forum/viewtopic.php?t5140739&#xff0c;带上个网页翻译插件就行。要用磁力链接下载&#xff0c;推荐用qbittorr…

远程网络唤醒家庭主机(openwrt设置)

远程网络唤醒家庭主机&#xff08;openwrt设置&#xff09; 前提&#xff1a; 1.配置好主板bios的网络唤醒功能(网络教程自己百度一下找) 2.电脑开启网络唤醒功能(网络教程自己百度一下找) 3.路由器通过ddns实现域名和动态IP绑定内网穿透方法汇总_不修改光猫进行内网穿透-C…

最新AI系统ChatGPT网站H5系统源码,支持AI绘画,GPT语音对话+ChatFile文档对话总结+DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

代码质量评价及设计原则

1.评价代码质量的标准 1.1 可维护性 可维护性强的代码指的是: 在不去破坏原有的代码设计以及不引入新的BUG的前提下,能够快速的修改或者新增代码. 不易维护的代码指的是: 在添加或者修改一些功能逻辑的时候,存在极大的引入新的BUG的风险,并且需要花费的时间也很长. 代码可…