一、老规矩,先看效果
二、做法步骤
1、安装
npm install vue-esign --save
2、引入
// 引入电子签名
import vueEsign from "vue-esign";
// 使用电子签名
Vue.use(vueEsign);
3、将签字功能进行组件封装
说明:我这里的 uploadFile 方法是上传图片到服务器的方法,需要将base64格式转为file格式进行上传,如果你不需要转格式,生成照片方法handleGenerate返回的base64就可以
代码如下
<template>
<el-dialog append-to-body class="sign-dialog" title="电子签名" :visible.sync="visible">
<div class="box">
<vue-esign ref="esign" :width="800" :height="400" :isCrop="isCrop" :lineWidth="lineWidth" :lineColor="lineColor"
:bgColor.sync="bgColor" />
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleReset">清空画板</el-button>
<el-button type="primary" @click="handleGenerate">生成签名</el-button>
<el-button @click="visible = false">关闭</el-button>
</span>
</el-dialog>
</template>
<script>
import { uploadFile } from "@/api/publicApi";
export default {
data() {
return {
visible: false,
lineWidth: 6,
lineColor: "#000000",
bgColor: "#FFFFFF",
resultImg: "",
isCrop: false,
};
},
methods: {
// 初始化方法
init() {
this.visible = true;
this.$nextTick(() => {
this.$refs.esign.reset();
});
},
// 清空画板
handleReset() {
this.$refs.esign.reset();
},
// 生成照片
handleGenerate() {
this.$refs.esign
.generate()
.then((base64) => {
// 1.先转为 blob格式 file.content是此文件的base64格式
console.log(base64);
let blob = this.dataURLtoBlob(base64);
// 拿到文件名
let fileName = "电子签名.jpg";
// 2,在转为 file类型
let file = this.blobToFile(blob, fileName);
const formData = new FormData();
formData.append("file", file);
//我这里是转了格式并且上传了服务器,调了方法,如果你不需要,直接
//this.$emit("handleImg", base64); 就可以
uploadFile(formData).then((res) => {
this.resultImg = res.fileUrls[0];
this.$emit("handleImg", this.resultImg);
this.visible = false;
});
})
.catch((err) => {
this.$message.error("请先签字再生成签名"); // 画布没有签字时会执行这里 'Not Signned'
});
},
//1,先将base64转换为blob
dataURLtoBlob(baseurl) {
var arr = baseurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
},
//2,再将blob转换为file
blobToFile(theBlob, fileName) {
theBlob.lastModifiedDate = new Date(); // 文件最后的修改日期
theBlob.name = fileName; // 文件名
return new File([theBlob], fileName, {
type: theBlob.type,
lastModified: Date.now(),
});
},
},
};
</script>
<style lang="scss">
.sign-dialog {
.el-dialog {
width: 840px;
}
.box {
margin: 0 auto;
background: #ecf0fa;
border-radius: 3px;
width: 800px;
overflow: hidden;
}
}
</style>
4、父组件引用调用
//html
<div class="signDiv">
<div class="signDivBj">
<img v-if="form.signImg" :src="form.signImg" alt="" />
</div>
<el-button type="primary" @click="sign">点击签名</el-button>
</div>
<!-- 电子签名组件 -->
<VueEsign v-if="showVueEsign" @handleImg="handleImg" ref="dialog-Esign" />
<script>
import VueEsign from "@/components/Esign/index.vue";
export default {
components: {
VueEsign,
},
data() {
return {
// 电子签名弹窗
showVueEsign: false,
// 表单参数
form: {
signImg: "",
},
}
},
methods: {
// 点击电子签名的方法
sign() {
// 展示签名组件
this.showVueEsign = true;
this.$nextTick(() => {
// 触发组件的初始化方法
this.$refs["dialog-Esign"].init();
});
},
// 回显电子签名图片
handleImg(signImg) {
//使用$set为this.form添加signImg,并且signImg具有自己的getter和setter(响应式)触发Vue更新页面
this.$set(this.form, "signImg", signImg);
},
};
</script>
<style lang="scss" scoped>
.signDiv {
width: 100%;
height: auto;
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
.signDivBj {
width: 140px;
height: 70px;
margin-right: 20px;
background-color: #ffffff;
border: 1px dashed #666666;
border-radius: 5px;
overflow: hidden;
display: flex;
img {
width: 100%;
height: 100%;
}
}
}
</style>