封装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="imageValue" v-model="imageValue" 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,
				imageValue:null,
			};
		},
		watch: {
			imageValue(newVal) {
				this.$emit('change', newVal)
			},
		},
		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.imageValue=response.data.url
									if (that.imageValue) {
										that.write = false
									}
									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  v-model="item.images" ></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  v-model="item.images" ></writeName>
</uni-forms-item>
</view>
</template>
import writeName from '@/pages/public/Handwriting/Handwriting.vue'
export default {
	components: {
			writeName
	},
	methods:{
	 
	}
}

在这里插入图片描述

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

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

uni-app封装接口可以按照以下步骤进行操作: 1. 创建一个api.js文件,并在其中引入所需的依赖库。可以使用import语句引入需要的库,比如import api from './api.js'。 2. 在api.js文件中,可以定义一个对象api,用于存放各种接口的方法和参数。 例如: ```javascript const api = { // 定义一个get方法 get(url, data) { // 发送网络请求,获取数据 return new Promise((resolve, reject) => { // 调用uni.request方法发送请求 uni.request({ url: url, data: data, method: 'GET', success: res => { resolve(res.data); }, fail: err => { reject(err); } }); }); }, // 定义一个post方法 post(url, data) { // 发送网络请求,获取数据 return new Promise((resolve, reject) => { // 调用uni.request方法发送请求 uni.request({ url: url, data: data, method: 'POST', success: res => { resolve(res.data); }, fail: err => { reject(err); } }); }); } }; // 导出api对象,供其他文件使用 export default api; ``` 3. 在需要使用接口的页面中,可以引入api.js,并使用api对象中的方法来发送网络请求。 例如: ```javascript // 在页面中引入api.js import api from './api.js'; // 在页面的某个方法中调用接口方法 api.get('/api/getData', { name: 'example' }) .then(res => { console.log(res); if (res.code === 200) { this.goods = res.data; } }) .catch(err => { console.log(err); }); ``` 通过以上步骤,你可以在uni-app封装并使用接口。首先,在api.js文件中定义了一个api对象,其中包含了get和post两种请求方法。然后,在页面中引入api.js,并使用api对象中的方法来发送网络请求获取数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java自学视频教程-JavaSE基础-面向对象基础-06、三大特征之一:封装,Javabean.mp4](https://download.csdn.net/download/weixin_54787054/88230842)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [uniapp接口请求封装api(超简单)](https://blog.csdn.net/weixin_45811884/article/details/117520048)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值