| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <template>
- <section>
- <el-upload
- list-type="picture-card"
- accept="image/*"
- :action="uploadUrl"
- :on-preview="handlePictureCardPreview"
- :on-success="handleSuccess"
- :on-remove="handleRemove"
- v-model:file-list="fileList"
- @before-upload="beforeUpload"
- multiple
- >
- <el-icon>
- <Plus />
- </el-icon>
- <template #tip>
- <div class="el-upload__tip">
- <slot></slot>
- </div>
- </template>
- </el-upload>
- <ElImageViewer v-if="showPreview" :url-list="[previewUrl]" teleported @close="showPreview = false" />
- </section>
- </template>
- <script setup>
- import resolveUrl from 'resolve-url'
- import { ref, watch } from 'vue'
- import { ElMessage } from 'element-plus'
- import { Plus } from '@vicons/tabler'
- import { useImageSize } from '@/utils/imageSize'
- const props = defineProps({
- modelValue: Array,
- maxWidth: {
- type: Number,
- default: -1
- },
- maxHeight: {
- type: Number,
- default: -1
- },
- maxSize: {
- type: Number,
- default: 1024 * 1024
- }
- })
- const emit = defineEmits(['update:modelValue'])
- const uploadUrl = resolveUrl(import.meta.env.VITE_API_BASE_URL, '/api/file/upload')
- const fileList = ref([])
- const loading = ref(false)
- const showPreview = ref(false)
- const previewUrl = ref(null)
- watch(
- () => props.modelValue,
- (val) => {
- if (val && val.join() === fileList.value.map((i) => i.realUrl).join()) {
- return
- }
- updateFileList(val)
- }
- )
- updateFileList(props.modelValue || [])
- function updateFileList(list) {
- fileList.value = list.map((i) => {
- return {
- url: i,
- realUrl: i
- }
- })
- }
- async function beforeUpload(file) {
- if (!/^image/.test(file.type)) {
- this.$message.error('只能上传图片格式!')
- return false
- }
- if (this.maxSize > 0 && file.size > this.maxSize) {
- this.$message.error('上传图片大小不能超过 ' + this.maxSize / 1024 + 'KB!')
- return false
- }
- const { width, height } = await useImageSize(URL.createObjectURL(file))
- if (props.maxWidth > 0 && width > props.maxWidth) {
- this.$message.error('上传图片宽度不能超过 ' + props.maxWidth + 'px!')
- return false
- } else if (props.maxHeight > 0 && height > props.maxHeight) {
- this.$message.error('上传图片高度不能超过 ' + props.maxHeight + 'px!')
- return false
- } else {
- loading.value = true
- return true
- }
- }
- function handlePictureCardPreview(file) {
- previewUrl.value = file.url || file.realUrl
- showPreview.value = true
- }
- function handleSuccess(res, file, fileList) {
- file.realUrl = res.url
- emit(
- 'update:modelValue',
- fileList.map((i) => i.realUrl)
- )
- }
- function handleRemove(file, fileList) {
- emit(
- 'update:modelValue',
- fileList.map((i) => i.realUrl)
- )
- }
- </script>
- <style lang="less" scoped></style>
|