feat:剪切板上传

This commit is contained in:
李亮亮 2024-01-16 10:33:31 +08:00
parent a6f5920e95
commit 18c3060e54
1 changed files with 53 additions and 59 deletions

View File

@ -8,15 +8,9 @@
<div class="border-2 border-dashed border-slate-400 rounded-md relative"> <div class="border-2 border-dashed border-slate-400 rounded-md relative">
<loading-overlay :loading="loading" /> <loading-overlay :loading="loading" />
<div <div class="grid p-4 gap-4 grid-cols-4 min-h-[240px]" @drop.prevent="onFileDrop" @dragover.prevent>
class="grid p-4 gap-4 grid-cols-4 min-h-[240px]" <div v-if="convertedImages.length === 0"
@drop.prevent="onFileDrop" class="absolute -z-10 left-0 top-0 w-full h-full flex items-center justify-center">
@dragover.prevent
>
<div
v-if="convertedImages.length === 0"
class="absolute -z-10 left-0 top-0 w-full h-full flex items-center justify-center"
>
<div class="text-gray-500"> <div class="text-gray-500">
<font-awesome-icon :icon="faCopy" /> <font-awesome-icon :icon="faCopy" />
粘贴或拖动图片至此处 粘贴或拖动图片至此处
@ -24,79 +18,59 @@
</div> </div>
<transition-group name="el-fade-in-linear"> <transition-group name="el-fade-in-linear">
<div <div class="col-span-3 md:col-span-1" v-for="item in convertedImages" :key="item.tmpSrc">
class="col-span-3 md:col-span-1" <image-box :src="item.tmpSrc" :size="item.file.size" :name="item.file.name"
v-for="item in convertedImages" @delete="removeImage(item.tmpSrc)" mode="converted" />
:key="item.tmpSrc"
>
<image-box
:src="item.tmpSrc"
:size="item.file.size"
:name="item.file.name"
@delete="removeImage(item.tmpSrc)"
mode="converted"
/>
</div> </div>
</transition-group> </transition-group>
</div> </div>
</div> </div>
<div class="w-full rounded-md shadow-sm overflow-hidden mt-4 grid grid-cols-8"> <div class="w-full rounded-md shadow-sm overflow-hidden mt-4 grid grid-cols-8">
<div class="md:col-span-1 col-span-8"> <div class="md:col-span-1 col-span-8">
<div <div class="w-full h-10 bg-blue-500 cursor-pointer flex items-center justify-center text-white" :class="{
class="w-full h-10 bg-blue-500 cursor-pointer flex items-center justify-center text-white" 'area-disabled': loading
:class="{ }" @click="input?.click()">
'area-disabled': loading
}"
@click="input?.click()"
>
<font-awesome-icon :icon="faImages" class="mr-2" /> <font-awesome-icon :icon="faImages" class="mr-2" />
选择图片 选择图片
</div> </div>
</div> </div>
<div class="md:col-span-5 col-span-8"> <div class="md:col-span-4 col-span-8">
<div class="w-full h-10 bg-slate-200 leading-10 px-4 text-center md:text-left"> <div class="w-full h-10 bg-slate-200 leading-10 px-4 text-center md:text-left">
已选择 {{ convertedImages.length }} {{ formatBytes(imagesTotalSize) }} 已选择 {{ convertedImages.length }} {{ formatBytes(imagesTotalSize) }}
</div> </div>
</div> </div>
<div class="md:col-span-1 col-span-3"> <div class="md:col-span-1 col-span-3">
<div <div class="w-full bg-red-500 cursor-pointer h-10 flex items-center justify-center text-white" :class="{
class="w-full bg-red-500 cursor-pointer h-10 flex items-center justify-center text-white" 'area-disabled': loading
:class="{ }" @click="clipboardUpload">
'area-disabled': loading <font-awesome-icon :icon="faTrashAlt" class="mr-2" />
}" 剪切板上传
@click="clearInput" </div>
> </div>
<div class="md:col-span-1 col-span-3">
<div class="w-full bg-red-500 cursor-pointer h-10 flex items-center justify-center text-white" :class="{
'area-disabled': loading
}" @click="clearInput">
<font-awesome-icon :icon="faTrashAlt" class="mr-2" /> <font-awesome-icon :icon="faTrashAlt" class="mr-2" />
清除 清除
</div> </div>
</div> </div>
<div class="md:col-span-1 col-span-5"> <div class="md:col-span-1 col-span-5">
<div <div class="w-full h-10 flex items-center justify-center text-white bg-green-500 cursor-pointer" :class="{
class="w-full h-10 flex items-center justify-center text-white bg-green-500 cursor-pointer" 'area-disabled': convertedImages.length === 0 || loading
:class="{ }" @click="uploadImages">
'area-disabled': convertedImages.length === 0 || loading
}"
@click="uploadImages"
>
<font-awesome-icon :icon="faUpload" class="mr-2" /> <font-awesome-icon :icon="faUpload" class="mr-2" />
上传 上传
</div> </div>
</div> </div>
</div> </div>
<result-list v-show="imgResultList && imgResultList.length" :image-list="imgResultList" ref="resultList" class="mt-4" /> <result-list v-show="imgResultList && imgResultList.length" :image-list="imgResultList" ref="resultList"
class="mt-4" />
</div> </div>
<input <input ref="input" type="file" accept="image/*" class="hidden" multiple @change="onInputChange" />
ref="input"
type="file"
accept="image/*"
class="hidden"
multiple
@change="onInputChange"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -105,7 +79,7 @@ import { faUpload } from '@fortawesome/free-solid-svg-icons'
import { computed, onMounted, onUnmounted, ref } from 'vue' import { computed, onMounted, onUnmounted, ref } from 'vue'
import LoadingOverlay from '../components/LoadingOverlay.vue' import LoadingOverlay from '../components/LoadingOverlay.vue'
import formatBytes from '../utils/format-bytes' import formatBytes from '../utils/format-bytes'
import {ElNotification as elNotify } from 'element-plus' import { ElNotification as elNotify } from 'element-plus'
import { requestUploadImages } from '../utils/request' import { requestUploadImages } from '../utils/request'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import ImageBox from '../components/ImageBox.vue' import ImageBox from '../components/ImageBox.vue'
@ -142,8 +116,28 @@ onUnmounted(() => {
}) })
const clearInput = () => { const clearInput = () => {
convertedImages.value = [] convertedImages.value = []
imgResultList.value = [] imgResultList.value = []
}
const clipboardUpload = () => {
const clipboardContents = await navigator.clipboard.read();
for (const item of clipboardContents) {
if (!item.types.includes("image/png")) {
throw new Error("剪切板中不是图片!");
}
const blob = await item.getType("image/png");
const file = new File([blob], "clipboard.png", {
type: "image/png",
});
convertedImages.value = [
...convertedImages.value,
{
file,
tmpSrc: URL.createObjectURL(file)
}
]
}
} }
const appendConvertedImages = async (files: FileList | null | undefined) => { const appendConvertedImages = async (files: FileList | null | undefined) => {
@ -203,11 +197,11 @@ const uploadImages = () => {
type: 'success' type: 'success'
}) })
convertedImages.value = [] convertedImages.value = []
imgResultList.value = res imgResultList.value = res
// console.log(res) // console.log(res)
// router.push('/') // router.push('/')
}) })
.catch(() => {}) .catch(() => { })
.finally(() => { .finally(() => {
loading.value = false loading.value = false
}) })