当前位置:   article > 正文

vue-signature-pad实现电子签名:包含车型、清屏、保存、笔刷粗细调节、回显图片

vue-signature-pad

参考博客:https://www.cnblogs.com/smile-fanyin/p/16544271.html,里面还包含了橡皮擦功能,因为签名对橡皮擦功能需求不大,所以没有使用。

在做中石油后台管理项目时,遇到了交接班表格要求实现签字效果,在参考上述博客后,在vue3项目中实现了此功能,上源码:

  1. <template>
  2. <a-modal
  3. v-model:visible="panelVisible"
  4. class="signNameModel"
  5. title="签字"
  6. width="600"
  7. height="400"
  8. size="large"
  9. :destroy-on-close="true"
  10. @cancel="cancel"
  11. >
  12. <template #default>
  13. <div class="signWrap">
  14. <VueSignaturePad
  15. ref="signaturePadRef"
  16. width="100%"
  17. height="100%"
  18. :options="options"
  19. />
  20. </div>
  21. </template>
  22. <template #footer>
  23. <div class="footer flex justify-between">
  24. <div class="otherSet flex">
  25. <div class="penTxt">笔刷大小:</div>
  26. <div
  27. class="circleWrap"
  28. :class="{ active: isActive1 }"
  29. @click="selSize(1)"
  30. >
  31. <div class="b1">·</div>
  32. </div>
  33. <div
  34. class="circleWrap"
  35. :class="{ active: isActive2 }"
  36. @click="selSize(2)"
  37. >
  38. <div class="b2">·</div>
  39. </div>
  40. <div
  41. class="circleWrap"
  42. :class="{ active: isActive3 }"
  43. @click="selSize(3)"
  44. >
  45. <div class="b3">·</div>
  46. </div>
  47. </div>
  48. <div class="gtnGroup">
  49. <a-button type="primary" size="small" @click="undo">撤销</a-button>
  50. <a-button
  51. type="primary"
  52. size="small"
  53. style="margin-left: 20px"
  54. @click="clear"
  55. >清屏</a-button
  56. >
  57. <a-button
  58. type="primary"
  59. size="small"
  60. style="margin-left: 20px"
  61. @click="cancel"
  62. >取消</a-button
  63. >
  64. <a-button
  65. type="primary"
  66. size="small"
  67. style="margin-left: 20px"
  68. @click="save"
  69. >保存</a-button
  70. >
  71. </div>
  72. </div>
  73. </template>
  74. </a-modal>
  75. </template>
  76. <script lang="ts" setup>
  77. import { message } from 'ant-design-vue';
  78. const panelVisible = ref<boolean>(false);
  79. const signaturePadRef = ref();
  80. const options = ref({
  81. penColor: '#000',
  82. minWidth: 1, // 控制画笔最小宽度
  83. maxWidth: 1, // 控制画笔最大宽度
  84. });
  85. const isActive1 = ref<boolean>(true);
  86. const isActive2 = ref<boolean>(false);
  87. const isActive3 = ref<boolean>(false);
  88. const props = defineProps<{
  89. signVisible: boolean;
  90. }>();
  91. const { signVisible } = toRefs(props);
  92. const emit = defineEmits(['signed']);
  93. // 手写签名按钮的点击
  94. const handleClick = () => {
  95. panelVisible.value = true;
  96. isActive1.value = true;
  97. isActive2.value = false;
  98. isActive3.value = false;
  99. options.value = {
  100. penColor: '#000',
  101. minWidth: 1,
  102. maxWidth: 1,
  103. };
  104. };
  105. // 撤销
  106. const undo = () => {
  107. signaturePadRef.value.undoSignature();
  108. };
  109. // 清除
  110. const clear = () => {
  111. signaturePadRef.value.clearSignature();
  112. };
  113. // 取消
  114. const cancel = () => {
  115. panelVisible.value = false;
  116. emit('signed');
  117. };
  118. // 保存
  119. const save = () => {
  120. const { isEmpty, data } = signaturePadRef.value.saveSignature();
  121. if (!data) return message.error('请先进行签名');
  122. panelVisible.value = false;
  123. emit('signed', data);
  124. };
  125. // 调节画笔粗细大小
  126. const selSize = (val:any) => {
  127. options.value = {
  128. penColor: '#000',
  129. minWidth: val,
  130. maxWidth: val,
  131. };
  132. if (val === 1) {
  133. isActive1.value = true;
  134. isActive2.value = false;
  135. isActive3.value = false;
  136. } else if (val === 2) {
  137. isActive1.value = false;
  138. isActive2.value = true;
  139. isActive3.value = false;
  140. } else if (val === 3) {
  141. isActive1.value = false;
  142. isActive2.value = false;
  143. isActive3.value = true;
  144. }
  145. };
  146. watchEffect(() => {
  147. if (signVisible.value) {
  148. handleClick();
  149. }
  150. });
  151. </script>
  152. <style scoped lang="less">
  153. .img-wrap {
  154. width: 100%;
  155. height: 164px;
  156. margin-top: 2px;
  157. border: 1px solid #ccc;
  158. img {
  159. width: 70%;
  160. height: 100%;
  161. }
  162. }
  163. .signWrap {
  164. height: 100%;
  165. display: flex;
  166. flex-direction: column;
  167. justify-content: center;
  168. .signName {
  169. flex: 1;
  170. border-top: 1px solid #ccc;
  171. }
  172. }
  173. .footer {
  174. height: 40px;
  175. display: flex;
  176. justify-content: space-between;
  177. align-items: center;
  178. .gtnGroup {
  179. width: 50%;
  180. margin-left: 20px;
  181. }
  182. .otherSet {
  183. width: 50%;
  184. display: flex;
  185. align-items: center;
  186. .penTxt {
  187. width: 70px;
  188. }
  189. .selSize {
  190. width: 70px;
  191. }
  192. .el-select__caret {
  193. position: absolute;
  194. right: -3px;
  195. }
  196. .b1,
  197. .b2,
  198. .b3 {
  199. background: #000;
  200. border-radius: 50%;
  201. }
  202. .circleWrap {
  203. display: flex;
  204. justify-content: center;
  205. align-items: center;
  206. width: 58px;
  207. height: 58px;
  208. cursor: pointer;
  209. margin-right: 20px;
  210. }
  211. .active {
  212. border: 1px dashed #0074d9;
  213. }
  214. .b1 {
  215. width: 4px;
  216. height: 4px;
  217. }
  218. .b2 {
  219. width: 6px;
  220. height: 6px;
  221. }
  222. .b3 {
  223. width: 8px;
  224. height: 8px;
  225. }
  226. }
  227. }
  228. .signNameModel {
  229. .vxe-modal--content {
  230. padding: 0 !important;
  231. }
  232. }
  233. </style>

使用并回显:

  1. <template>
  2. <div v-if="onShiftPersonUrl" class="img">
  3. <img class="w-full h-full" :src="onShiftPersonUrl" />
  4. </div>
  5. <SignaturePad :sign-visible="signVisible" @signed="signed" />
  6. </template>
  7. <script lang="ts" setup>
  8. import SignaturePad from '@/views/components/Signature.vue';
  9. const onShiftPersonUrl = ref();
  10. const signed = (imgSrc?: any) => {
  11. signVisible.value = false;
  12. if (!imgSrc) return;
  13. onShiftPersonUrl.value = imgSrc;
  14. };
  15. <script/>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/893583
推荐阅读
相关标签
  

闽ICP备14008679号