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

时间:2025-03-28 11:30:48
  • <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 = () => {
  • = true;
  • = true;
  • = false;
  • = false;
  • = {
  • penColor: '#000',
  • minWidth: 1,
  • maxWidth: 1,
  • };
  • };
  • // 撤销
  • const undo = () => {
  • ();
  • };
  • // 清除
  • const clear = () => {
  • ();
  • };
  • // 取消
  • const cancel = () => {
  • = false;
  • emit('signed');
  • };
  • // 保存
  • const save = () => {
  • const { isEmpty, data } = ();
  • if (!data) return ('请先进行签名');
  • = false;
  • emit('signed', data);
  • };
  • // 调节画笔粗细大小
  • const selSize = (val:any) => {
  • = {
  • penColor: '#000',
  • minWidth: val,
  • maxWidth: val,
  • };
  • if (val === 1) {
  • = true;
  • = false;
  • = false;
  • } else if (val === 2) {
  • = false;
  • = true;
  • = false;
  • } else if (val === 3) {
  • = false;
  • = false;
  • = true;
  • }
  • };
  • watchEffect(() => {
  • if () {
  • 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>