最近项目遇到的要求是弹出框上传文件,需要用到页面截图,由于使用的是Vue3的框架于是选择用vue-web-screen-shot组件进行操作。(由于插件是Vue3编写的,所以只适用于Vue3的项目,如果是Vue2的项目,截图组件可以使用js-web-screen-shot)
需要实现的效果如下:
点击截图后弹窗消失,用户可随意在页面中截图等操作
确认后在弹窗中显示截图列表,上传表格
整个操作步骤实现如下:
1.在项目中添加vue-web-screen-shot组件
//使用以下代码添加插件
yarn add vue-web-screen-shot
# or
npm install vue-web-screen-shot --save
// 导入截屏插件
import screenShort from "vue-web-screen-shot";
const app = createApp(App);
// 使用截屏插件
app.use(screenShort, { enableWebRtc: false })
//省略弹框其他部分
...
快捷截图
//直接使用组件即可,不用在该页面继续添加
如果将screen-short组件放在弹出框内部,则隐藏弹出框时会连同截屏组件一起隐藏,所以建议放在外部,并给dialog弹出框单独加一个div,用showScreenShort控制弹出框显示和隐藏
参数说明
如示例代码所示,在template中直接使用
screen-short
插件,绑定组件需要的事件处理函数即可。接下来就跟大家讲下组件中每个属性的意义:
- screenshotStatus 用于控制组件是否出现在dom中
- @destroy-component 用于接收截图组件传递的销毁消息,我们需要在对应的函数中销毁截图组件
- @get-image-data 用于接收截图组件传递的框选区域的base64图片信息,我们需要为他提供一个函数来接收截图组件传递的消息
可选参数
截图插件有一个可选参数,它接受一个对象,对象每个key的作用如下:
enableWebRtc
是否启用webrtc,值为boolean类型,值为false则使用html2canvas来截图level
截图容器层级,值为number类型。clickCutFullScreen
单击截全屏启用状态,值为boolean
类型, 默认为false
hiddenToolIco
需要隐藏的截图工具栏图标,值为{ save?: boolean; undo?: boolean; confirm?: boolean }
类型,默认为{}
。传你需要隐藏的图标名称,将值设为true
即可。enableCORS
html2canvas截图模式下跨域的启用状态,值为boolean
类型,默认为false
proxyAddress
html2canvas截图模式下的图片服务器代理地址,值为string
类型,默认为undefined
截图功能实现代码如下:
接下来制作截图的列表框,循环的是js代码中64编码uploadlist表,由于用户可能需要对图片进行查看、删除等操作,加入点击事件
//在之前的弹窗快捷截图后边
//查看大图也是一个弹出框的形式
查看大图
//涉及语法
// 查看图片大图
删除截图代码:
function deleteImg(name) {
console.log(name);
uploadlist.value.forEach((value, index, array) => {
if (name == value.name) {
array.splice(index, 1);
}
});
}
因为之前可能会涉及到文件的删除,所以考虑在最后上传的时候再将所有的截图64编码进行数据转换。
async function submitForm(formEl) {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
//上述是绑定了表格验证
//下面开始上传文件
let formData = new FormData();
formData.append('description', servicesForm.value['description']);
//这里是关于截图部分的64base转码
if (uploadlist.value.length > 0) {
uploadlist.value.forEach((e) => {
//通过atob将base64进行编码
var bytes = window.atob(e.image.split(',')[1]);
//处理异常,将ASCII码小于0的转换为大于0,进行二进制转换
var buffer = new ArrayBuffer(bytes.length);
//生成一个8位数的数组
var uint = new Uint8Array(buffer);
//根据长度返回相对应的Unicode 编码
for (var i = 0; i < bytes.length; i++) {
uint[i] = bytes.charCodeAt(i);
}
//Blob对象,type为图片的格式
var imageFile = new Blob([buffer], { type: 'image/jpeg' });
//最后将转换的文件放入要上传的数组中
imageFilelist.push(imageFile);
});
//将已转换好的文件进行上传
for (var i = 0; i < imageFilelist.length; i++) {
formData.append('picFiles', imageFilelist[i], guid() + '.jpg');
}
}
//上传接口,上传formData数据,关闭弹出框
addFeedback(formData).then((data) => {
closeDialog();
emit('updateData', '');
});
}
});
}
以上。