当前位置: 首页 > news >正文

封装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;//图片上传拿urllet data = {filePath: tempPath,formData: {isSystem: 'true'}}  imageUpload(data).then(response => {//向上一个页面传参that.value = response.data.urlthat.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},}
}

在这里插入图片描述

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

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

相关文章:

封装uniapp签字板

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

Mybatis行为配置之Ⅳ—日志

专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 Mybatis枚举类型处理和类型处理器 再谈动态SQL Mybatis配置入门 Mybatis行为配置之Ⅰ—缓存 Mybatis行为配置…...

Java设计模式-外观模式

目录 一、影院管理项目 二、外观模式 &#xff08;一&#xff09;基本介绍 &#xff08;二&#xff09;原理类图 &#xff08;三&#xff09;解决影院管理 &#xff08;四&#xff09;注意事项和细节 &#xff08;五&#xff09;外观模式在MyBatis框架应用的源码分析 一…...

js+css实现颜色选择器

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>颜色选择器</title><style>.color-box {width: 50px;height: 50px;border: 1px solid #000;cursor: pointer;}</style> </head> <body><…...

Go语言中的包管理工具之Go Modules的使用

GoLang 中常用的包管理的方式 常用的有三种 Go PathGo VendorGo Modules 关于 Go Modules 1 ) 概述 Go的包管理&#xff0c;经过社区和官方的共同努力下&#xff0c;最终在百家争鸣后Go官方在 2018.8 推出了go 1.11版本中的Go Modules&#xff0c;并且很快成为一统江湖的包…...

【c/c++】指针例图基础详解

文章目录 指针变量内存指针详解例1例2练习&答案解析 指针变量内存 int main(){// 各类型变量占字节数printf("char: %d\n",sizeof(char)); // 1printf("short: %d\n",sizeof(short)); // 2printf("int: %d\n",sizeof(int)); // 4pri…...

TCP/IP的网络层(即IP层)之IP地址和网络掩码,在视频监控系统中的配置和应用

在给客户讲解我们的AS-V1000视频监控平台的时候&#xff0c;有的客户经常会配置错误IP地址的掩码和网关&#xff0c;导致出现一些网路问题。而在视频监控系统中&#xff0c;IP地址和子网掩码是用于标识网络中设备的重要标识符。IP地址被用来唯一地标识一个网络设备&#xff0c;…...

代码随想录刷题 | Day1

今日学习目标 一、基础 数组 array类 模板类vector 数组是存放在连续内存空间上的相同类型数据的集合。 数组可以方便的通过下标索引的方式获取到下标下对应的数据。 需要两点注意的是 数组下标都是从0开始的。 数组内存空间的地址是连续的 而且大家如果使用C的话&…...

查看IOS游戏FPS

摘要 本篇技术博客将介绍如何使用克魔助手工具来查看iOS游戏的帧率&#xff08;FPS&#xff09;。通过克魔助手&#xff0c;开发者可以轻松监测游戏性能&#xff0c;以提升用户体验和游戏质量。 引言 在iOS游戏开发过程中&#xff0c;了解游戏的帧率对于优化游戏性能至关重要…...

挑战Python100题(7)

100+ Python challenging programming exercises 7 Question 61 Print a unicode string "hello world". Hints: Use ustrings format to define unicode string. 打印一个unicode字符串“helloworld”。 提示:使用u“字符串”格式定义unicode字符串。 Solution…...

HarmonyOS自学-Day4(TodoList案例)

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;TodoList小案例 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程语言基础&#xff0c;非编程小白&#xff09;的 HarmonyOS自学笔记&#xff0c;此类文章笔记我会默认大家都学过前端相关的知识知识来源为 HarmonyOS官方文…...

LTPI协议的理解——2、LTPI实现的底层架构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 LTPI协议的理解——2、LTPI实现的底层架构 前言一、体系结构三、实现细节四、物理接口信号传输方法总结 前言 前面讲了LTPI的定义和大概结构&#xff0c;接下来继续理解LTPI…...

CentOS 8.2 安装 Mysql 5.7.26(单机)

Mysql二进制包: mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz 1、卸载旧环境 rpm -qa|grep mysql rpm -qa|grep mariadb rpm -e XXX.rpm --nodeps # 强制卸载rpm包 rm -rf /etc/my.cnf rm -rf /etc/mysql rm -rf /usr/local/mysql 2、安装依赖包 yum -y install libaio yum…...

Vue Tinymce富文本组件自定义带下拉框的操作按钮

想实现如下效果 首先在init方法中的props&#xff0c;toolbar属性增加一个自定义按钮 增加一个setup方法 代码 setup: function(editor) { editor.ui.registry.addSplitButton(myDateButton, {text: 日期时间,onAction: (_) > editor.insertContent(getJsMonthDay(getNowDat…...

YOLOv5算法进阶改进(10)— 更换主干网络之MobileViTv3 | 轻量化Backbone

前言:Hello大家好,我是小哥谈。MobileViTv3是一种改进的模型架构,用于图像分类任务。它是在MobileViTv1和MobileViTv2的基础上进行改进的,通过引入新的模块和优化网络结构来提高性能。本节课就给大家介绍一下如何在主干网络中引入MobileViTv3网络结构,希望大家学习之后能够…...

Java UDP

接收方 创建DatagramSocket实例并指定端口。创建DatagramPacket实例接收信息。调用DatagramSocket的receive()方法将接收信息并传递给DatagramPacket。通过DatagramPacket的getData()方法获取信息内容&#xff0c;getLength()方法获取长度。 package io.github.jast90.udp;im…...

Halcon阈值处理的几种分割方法threshold/auto_threshold/binary_threshold/dyn_threshold

Halcon阈值处理的几种分割方法 文章目录 Halcon阈值处理的几种分割方法1. 全局阈值2. 基于直方图的自动阈值分割方法3. 自动全局阈值分割方法4. 局部阈值分割方法5. var_threshold算子6 . char_threshold 算子7. dual_threshold算子 在场景中选择物体或特征是图像测量或识别的重…...

FB混合C语言编译

这是群友分享的方法&#xff0c;这里只是作为记录和分享。 有了这个功能&#xff0c;可以很方便的拷贝一下C或者C代码直接用到FB上。 既然是混合C语言编译&#xff0c;当然得有C的代码。比如随便去网上找两个排序&#xff1a;冒泡排序和选择排序&#xff0c;代码如下&#xf…...

【机器学习】深度学习概论(二)

五、受限玻尔兹曼机&#xff08;Restricted Boltzmann Machine&#xff0c;RBM&#xff09; 5.1 RBM介绍 示例代码&#xff1a; Python 编写了一个简单的 RBM 实现&#xff0c;并用一些假数据训练了它。然后&#xff0c;他展示了如何用 RBM 来解释用户的电影偏好&#xff0c;以…...

词法语法语义分析程序设计及实现,包含出错提示和错误恢复

词法说明 (1)关键字 main, int, char, if, else, for, while, void (2)运算符 - * / < < > > ! (3)界符 ; ( ) { } (4)标识符 ID letter(letter|digit)* (5)整型常数 NUM digit digit* (6)空格 ‘ ‘ ‘\n’ ‘\r’ ‘\t’ 空格用来分隔ID,NUM,运算符,界…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...