文档结构
完整代码
App.vue文件
<script setup>
import Home from '@/components/ImageUpload.vue'
import { ref } from 'vue';
let show=ref(false)
</script>
<template>
<button @click="show=!show">显示</button>
<Home v-model:display="show"></Home>
</template>
说明:
ImageUpload 组件引入收需要传入一个 display 参数,用于控制组件的显示隐藏
ImageUpload.vue文件
<script>
import { ref, computed, watch } from 'vue'
// import { UploadFilled } from '@element-plus/icons-vue'
// import {upImg} from '@/api/ImagesUpload'
export default {
props: {
display: Boolean
},
setup(props, context) {
//图片base64
let imgBase64 = ref('')
//上传图片
function uploadImage(file) {
const isImage = file.type.startsWith('image/')
if (!isImage) {
ElMessage({
message: '只可以上传图片',
type: 'warning',
})
return isImage
}
convertToBase64(file, async (base64String) => {
//发送请求
putImg(base64String)
})
return false
}
//转化图片为base64
function convertToBase64(file, callback) {
const reader = new FileReader()
reader.onload = (event) => {
callback(event.target.result)
}
reader.readAsDataURL(file)
}
//监听剪切板函数
function handlePaste(event) {
const items = (event.clipboardData || window.clipboardData).items;
let file = null;
if (!items || items.length === 0) {
ElMessage({
message: '当前浏览器不支持本地',
type: 'error',
})
return;
}
// 搜索剪切板items
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
file = items[i].getAsFile();
break;
}
}
if (!file) {
ElMessage({
message: '粘贴内容非图片',
type: 'warning',
})
return;
}
convertToBase64(file, (base64Str) => {
putImg(base64Str)
})
}
//发送请求
function putImg(base64Str) {
imgBase64.value = base64Str
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
//发送请求(此方法应该自己定义)
upImg({
image_base64: base64Str
})
.then((res) => {
// 处理异常情况
if (!res.success) {
ElMessage({
message: res.error_message,
type: 'error',
})
return
}
//成功响应
loading.close()
})
.catch((error) => {
// 处理错误
ElMessage({
message: '识别失败,请重新上传',
type: 'error',
})
console.error(error)
loading.close()
})
}
//初始化
function init() {
imgBase64.value = ''
}
watch(() => props.display, (val, oldVal) => {
if (val) {
document.addEventListener('paste', handlePaste)
} else {
document.removeEventListener('paste', handlePaste)
init()
}
})
return {
uploadImage,
imgBase64,
}
},
computed: {
//是否显示组件
showBox: {
get() {
return this.display
},
set(value) {
console.log(value);
// this.$emit('update:display', value)
}
}
},
}
</script>
<template>
<el-dialog v-model="showBox" align-center title="上传图片-智能识图" width="50%">
<!--上传组件-->
<el-upload :before-upload="uploadImage" action="#" class="upload-demo" drag multiple>
<el-icon class="el-icon--upload">
<img style="width: 80%;object-fit: cover;" src="https://tse4-mm.cn.bing.net/th/id/OIP-C.X-5ho42VHJwTZg1ixPxo4wAAAA?w=211&h=180&c=7&r=0&o=5&dpr=1.5&pid=1.7" alt="">
</el-icon>
<div class="el-upload__text">
拖拽文件到此处,或者
<em>点击上传</em>
<p style="font-size: 13px">支持微信截图后在此处粘贴( Ctrl + v)</p>
</div>
<template #tip>
<div class="el-upload__tip">
<!-- jpg/png files with a size less than 500kb-->
</div>
</template>
</el-upload>
</el-dialog>
</template>
<style scoped></style>
代码分析:
imgBase64
用来保存选择图片的base64,方便回显或者其他操作
showbox 使用计算属性,当组件被关闭的时候走 set函数,此时可以触发方法携带一些参数给父级组件;
computed: {
//是否显示组件
showBox: {
get() {
return this.display
},
set(value) {
console.log(value);
// this.$emit('update:display', value)
}
}
},
uploadImage函数
在 el-upload 组件上传前获取上传的文件,判断是不是图片,如果是调用 convertToBase64 方法转换图片为 baes64 并在回调函数中请求接口
//上传图片
function uploadImage(file) {
const isImage = file.type.startsWith('image/')
if (!isImage) {
ElMessage({
message: '只可以上传图片',
type: 'warning',
})
return isImage
}
convertToBase64(file, async (base64String) => {
//发送请求
putImg(base64String)
})
return false
}
convertToBase64函数
需要传入 el 上传组件的 file 和回调函数,图片转化成 base64 后,调用传入的方法
//转化图片为base64
function convertToBase64(file, callback) {
const reader = new FileReader()
reader.onload = (event) => {
callback(event.target.result)
}
reader.readAsDataURL(file)
}
handlePaste函数
监听剪切板,判断粘贴内容是不是图片并获取最近的一张截图,如果是图片调用 convertToBase64函数 并请求接口
putImg函数 请求接口,在发送请求前才会更新当前保存的图片
function putImg(base64Str) {
imgBase64.value = base64Str
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
//发送请求(此方法应该自己定义)
upImg({
image_base64: base64Str
})
.then((res) => {
// 处理异常情况
if (!res.success) {
ElMessage({
message: res.error_message,
type: 'error',
})
return
}
//成功响应
loading.close()
})
.catch((error) => {
// 处理错误
ElMessage({
message: '识别失败,请重新上传',
type: 'error',
})
console.error(error)
loading.close()
})
}
init函数
初始化,清空当前保存的图片
function init() {
imgBase64.value = ''
}
watch
监听 props.display ,当 display 为 true 的时候,也就是上传组件显示的时候,网页开始监听剪贴操作,反之为 false 的时候,组件关闭的同时,取消监听,并初始化
watch(() => props.display, (val, oldVal) => {
if (val) {
document.addEventListener('paste', handlePaste)
} else {
document.removeEventListener('paste', handlePaste)
init()
}
})