feat:剪切板上传
This commit is contained in:
parent
a6f5920e95
commit
18c3060e54
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue