赞
踩
参考博客:https://www.cnblogs.com/smile-fanyin/p/16544271.html,里面还包含了橡皮擦功能,因为签名对橡皮擦功能需求不大,所以没有使用。
在做中石油后台管理项目时,遇到了交接班表格要求实现签字效果,在参考上述博客后,在vue3项目中实现了此功能,上源码:
<template> <a-modal v-model:visible="panelVisible" class="signNameModel" title="签字" width="600" height="400" size="large" :destroy-on-close="true" @cancel="cancel" > <template #default> <div class="signWrap"> <VueSignaturePad ref="signaturePadRef" width="100%" height="100%" :options="options" /> </div> </template> <template #footer> <div class="footer flex justify-between"> <div class="otherSet flex"> <div class="penTxt">笔刷大小:</div> <div class="circleWrap" :class="{ active: isActive1 }" @click="selSize(1)" > <div class="b1">·</div> </div> <div class="circleWrap" :class="{ active: isActive2 }" @click="selSize(2)" > <div class="b2">·</div> </div> <div class="circleWrap" :class="{ active: isActive3 }" @click="selSize(3)" > <div class="b3">·</div> </div> </div> <div class="gtnGroup"> <a-button type="primary" size="small" @click="undo">撤销</a-button> <a-button type="primary" size="small" style="margin-left: 20px" @click="clear" >清屏</a-button > <a-button type="primary" size="small" style="margin-left: 20px" @click="cancel" >取消</a-button > <a-button type="primary" size="small" style="margin-left: 20px" @click="save" >保存</a-button > </div> </div> </template> </a-modal> </template> <script lang="ts" setup> import { message } from 'ant-design-vue'; const panelVisible = ref<boolean>(false); const signaturePadRef = ref(); const options = ref({ penColor: '#000', minWidth: 1, // 控制画笔最小宽度 maxWidth: 1, // 控制画笔最大宽度 }); const isActive1 = ref<boolean>(true); const isActive2 = ref<boolean>(false); const isActive3 = ref<boolean>(false); const props = defineProps<{ signVisible: boolean; }>(); const { signVisible } = toRefs(props); const emit = defineEmits(['signed']); // 手写签名按钮的点击 const handleClick = () => { panelVisible.value = true; isActive1.value = true; isActive2.value = false; isActive3.value = false; options.value = { penColor: '#000', minWidth: 1, maxWidth: 1, }; }; // 撤销 const undo = () => { signaturePadRef.value.undoSignature(); }; // 清除 const clear = () => { signaturePadRef.value.clearSignature(); }; // 取消 const cancel = () => { panelVisible.value = false; emit('signed'); }; // 保存 const save = () => { const { isEmpty, data } = signaturePadRef.value.saveSignature(); if (!data) return message.error('请先进行签名'); panelVisible.value = false; emit('signed', data); }; // 调节画笔粗细大小 const selSize = (val:any) => { options.value = { penColor: '#000', minWidth: val, maxWidth: val, }; if (val === 1) { isActive1.value = true; isActive2.value = false; isActive3.value = false; } else if (val === 2) { isActive1.value = false; isActive2.value = true; isActive3.value = false; } else if (val === 3) { isActive1.value = false; isActive2.value = false; isActive3.value = true; } }; watchEffect(() => { if (signVisible.value) { handleClick(); } }); </script> <style scoped lang="less"> .img-wrap { width: 100%; height: 164px; margin-top: 2px; border: 1px solid #ccc; img { width: 70%; height: 100%; } } .signWrap { height: 100%; display: flex; flex-direction: column; justify-content: center; .signName { flex: 1; border-top: 1px solid #ccc; } } .footer { height: 40px; display: flex; justify-content: space-between; align-items: center; .gtnGroup { width: 50%; margin-left: 20px; } .otherSet { width: 50%; display: flex; align-items: center; .penTxt { width: 70px; } .selSize { width: 70px; } .el-select__caret { position: absolute; right: -3px; } .b1, .b2, .b3 { background: #000; border-radius: 50%; } .circleWrap { display: flex; justify-content: center; align-items: center; width: 58px; height: 58px; cursor: pointer; margin-right: 20px; } .active { border: 1px dashed #0074d9; } .b1 { width: 4px; height: 4px; } .b2 { width: 6px; height: 6px; } .b3 { width: 8px; height: 8px; } } } .signNameModel { .vxe-modal--content { padding: 0 !important; } } </style>
使用并回显:
- <template>
- <div v-if="onShiftPersonUrl" class="img">
- <img class="w-full h-full" :src="onShiftPersonUrl" />
- </div>
- <SignaturePad :sign-visible="signVisible" @signed="signed" />
- </template>
-
- <script lang="ts" setup>
- import SignaturePad from '@/views/components/Signature.vue';
-
- const onShiftPersonUrl = ref();
- const signed = (imgSrc?: any) => {
- signVisible.value = false;
- if (!imgSrc) return;
- onShiftPersonUrl.value = imgSrc;
- };
- <script/>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。