UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

1 lines 24.6 kB
{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-upload/index.vue"],"sourcesContent":["<template>\r\n <div :class=\"prefixCls\">\r\n <!-- 上传框左边 -->\r\n <div\r\n :class=\"inputWrapClasses\"\r\n @click=\"handleClickInput\"\r\n @drop.prevent=\"handleDrag\"\r\n @dragover.prevent=\"handleDragOver\"\r\n @dragleave.prevent=\"handleDragleave\"\r\n v-if=\"uploadDirection === 'left'\"\r\n v-show=\"renderUpload\"\r\n >\r\n <input\r\n type=\"file\"\r\n ref=\"input\"\r\n :class=\"`${prefixCls}-input`\"\r\n :accept=\"accept\"\r\n :multiple=\"multiple\"\r\n :capture=\"capture\"\r\n @change=\"handleChange\"\r\n v-if=\"!readonly\"\r\n />\r\n <slot>\r\n <div :class=\"inputContentClasses\" :style=\"getSizeStyle(previewSize)\">\r\n <!-- 图标 -->\r\n <ivue-icon :class=\"`${prefixCls}-content__icon`\"\r\n >cloud_upload</ivue-icon\r\n >\r\n <p :class=\"`${prefixCls}-content__text`\">点击上传</p>\r\n </div>\r\n </slot>\r\n </div>\r\n\r\n <!-- 列表 -->\r\n <upload-list\r\n :files=\"data.fileList\"\r\n :failedIcon=\"failedIcon\"\r\n :deletable=\"deletable\"\r\n :name=\"name\"\r\n :previewSize=\"previewSize\"\r\n :beforeDelete=\"beforeDelete\"\r\n :previewFullImage=\"previewFullImage\"\r\n :imageFit=\"imageFit\"\r\n @on-delete=\"handleRemove\"\r\n @on-preview=\"handlePreview\"\r\n v-if=\"previewImage\"\r\n >\r\n <!-- 自定义覆盖在预览区域上方的内容 -->\r\n <template v-if=\"$slots['preview-cover']\" #preview-cover=\"{ file }\">\r\n <slot name=\"preview-cover\" :file=\"file\"></slot>\r\n </template>\r\n <!-- 自定义预览图片区域内容 -->\r\n <template v-if=\"$slots['preview-image']\" #preview-image>\r\n <slot name=\"preview-image\"></slot>\r\n </template>\r\n </upload-list>\r\n\r\n <!-- 放大图片 -->\r\n <image-preview\r\n transfer\r\n :bodyOverflow=\"bodyOverflow\"\r\n :previewList=\"data.imagePreviewList\"\r\n :initialIndex=\"data.imagePreviewInitialIndex\"\r\n v-model=\"data.imagePreview\"\r\n @on-close=\"handleClosePreview\"\r\n ></image-preview>\r\n\r\n <!-- 上传框右边 -->\r\n <div\r\n :class=\"inputWrapClasses\"\r\n @click=\"handleClickInput\"\r\n @drop.prevent=\"handleDrag\"\r\n @dragover.prevent=\"handleDragOver\"\r\n @dragleave.prevent=\"handleDragleave\"\r\n v-if=\"uploadDirection === 'right'\"\r\n v-show=\"renderUpload\"\r\n >\r\n <input\r\n type=\"file\"\r\n ref=\"input\"\r\n :class=\"`${prefixCls}-input`\"\r\n :accept=\"accept\"\r\n :multiple=\"multiple\"\r\n :capture=\"capture\"\r\n @change=\"handleChange\"\r\n v-if=\"!readonly\"\r\n />\r\n <slot>\r\n <div :class=\"inputContentClasses\" :style=\"getSizeStyle(previewSize)\">\r\n <!-- 图标 -->\r\n <ivue-icon :class=\"`${prefixCls}-content__icon`\"\r\n >cloud_upload</ivue-icon\r\n >\r\n <p :class=\"`${prefixCls}-content__text`\">点击上传</p>\r\n </div>\r\n </slot>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport { defineComponent, computed, ref, reactive, PropType, watch } from 'vue';\r\n\r\nimport IvueIcon from '../ivue-icon/index.vue';\r\nimport UploadList from './upload-list.vue';\r\nimport ImagePreview from '../ivue-image-preview';\r\n\r\nimport { oneOf } from '../../utils/assist';\r\nimport { isPromise } from '../../utils/validate';\r\nimport { Interceptor } from '../../utils/interceptor';\r\n\r\nimport {\r\n readFileContent,\r\n isOversize,\r\n UploaderFileListItem,\r\n UploaderResultType,\r\n UploaderMaxSize,\r\n filterFiles,\r\n toArray,\r\n getSizeStyle,\r\n} from '../../utils/helpers';\r\n\r\n// type\r\nimport {\r\n Props,\r\n Data,\r\n UploaderAfterRead,\r\n UploaderBeforeRead,\r\n} from './types/upload';\r\n\r\nconst prefixCls = 'ivue-upload';\r\n\r\nexport default defineComponent({\r\n name: prefixCls,\r\n emits: [\r\n 'update:modelValue',\r\n 'on-oversize',\r\n 'on-delete',\r\n 'on-preview',\r\n 'on-drag-upload-error',\r\n 'on-close-preview',\r\n ],\r\n props: {\r\n /**\r\n * 上传组件类型\r\n *\r\n * @type {String}\r\n *\r\n * select (点击选择)\r\n *\r\n * drag (支持拖动)\r\n */\r\n type: {\r\n type: String,\r\n validator(value: string) {\r\n return oneOf(value, ['select', 'drag']);\r\n },\r\n default: 'select',\r\n },\r\n /**\r\n * 接受的上传类型\r\n *\r\n * @type {String}\r\n */\r\n accept: {\r\n type: String,\r\n default: 'image/*',\r\n },\r\n /**\r\n * 拖拽接受的上传类型后缀\r\n *\r\n * @type {Array}\r\n */\r\n dragAccept: {\r\n type: Array,\r\n },\r\n /**\r\n * 是否支持多选文件\r\n *\r\n * @type {Boolean}\r\n */\r\n multiple: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否禁用\r\n *\r\n * @type {Boolean}\r\n */\r\n disabled: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否将上传区域设置为只读状态\r\n *\r\n * @type {Boolean}\r\n */\r\n readonly: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 图片选取模式,可选值为 camera (直接调起摄像头)\r\n *\r\n * @type {String}\r\n */\r\n capture: {\r\n type: String as PropType<any>,\r\n },\r\n /**\r\n * 文件读取结果类型,可选值为 file text dataUrl url\r\n *\r\n * @type {String}\r\n */\r\n resultType: {\r\n type: String as PropType<UploaderResultType>,\r\n default: 'dataUrl',\r\n },\r\n /**\r\n * 返回的数据\r\n *\r\n * @type {Array}\r\n */\r\n modelValue: {\r\n type: Array as PropType<UploaderFileListItem[]>,\r\n default: () => [],\r\n },\r\n /**\r\n * 文件大小限制,单位为 byte\r\n *\r\n * @type {number | string | (file: File) => boolean}\r\n */\r\n maxSize: {\r\n type: [Number, String, Function] as PropType<UploaderMaxSize>,\r\n default: Number.MAX_VALUE,\r\n },\r\n /**\r\n * 文件上传数量限制\r\n *\r\n * @type {Number, String}\r\n */\r\n maxCount: {\r\n type: [Number, String],\r\n default: Number.MAX_VALUE,\r\n },\r\n /**\r\n * 文件读取完成后的回调函数\r\n *\r\n * @type {Boolean}\r\n */\r\n afterRead: {\r\n type: Function as PropType<UploaderAfterRead>,\r\n },\r\n /**\r\n * before-read\t文件读取前的回调函数,返回 false 可终止文件读取,支持返回 Promise\r\n *\r\n * @type {Function}\r\n */\r\n beforeRead: {\r\n type: Function as PropType<UploaderBeforeRead>,\r\n },\r\n /**\r\n * 标识符,可以在回调函数的第二项参数中获取\r\n *\r\n * @type {Number, String}\r\n */\r\n name: {\r\n type: [Number, String],\r\n default: '',\r\n },\r\n /**\r\n * 错误时的图标\r\n *\r\n * @type {String}\r\n */\r\n failedIcon: {\r\n type: String,\r\n default: '',\r\n },\r\n /**\r\n * 是否展示删除按钮\r\n *\r\n * @type {Boolean}\r\n */\r\n deletable: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * 是否展示上传区域\r\n *\r\n * @type {Boolean}\r\n */\r\n showUpload: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * 预览图和上传区域的尺寸,默认单位为 px\r\n *\r\n * @type {Number | String}\r\n */\r\n previewSize: [Number, String],\r\n /**\r\n * 是否在上传完成后展示预览图\r\n *\r\n * @type {Boolean}\r\n */\r\n previewImage: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * 文件删除前的回调函数,返回 false 可终止文件读取,\r\n * 支持返回 Promise\r\n *\r\n * @type {Function}\r\n */\r\n beforeDelete: {\r\n type: Function as PropType<Interceptor>,\r\n },\r\n /**\r\n * 预览图片放大\r\n *\r\n * @type {Boolean}\r\n */\r\n previewFullImage: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * 预览图片开始位置下标\r\n *\r\n * @type {Boolean}\r\n */\r\n previewImageInitialIndex: {\r\n type: Number,\r\n default: -1,\r\n },\r\n /**\r\n * 防止body滚动\r\n *\r\n * @type {Boolean}\r\n */\r\n bodyOverflow: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * 上传方向\r\n *\r\n * @type {String}\r\n */\r\n uploadDirection: {\r\n type: String,\r\n validator(value: string) {\r\n return oneOf(value, ['left', 'right']);\r\n },\r\n default: 'right',\r\n },\r\n /**\r\n * 预览图裁剪模式\r\n *\r\n * @type {String}\r\n */\r\n imageFit: {\r\n type: String,\r\n validator(value: string) {\r\n return oneOf(value, ['contain', 'cover', 'fill', 'none', 'scale-down']);\r\n },\r\n default: 'cover',\r\n },\r\n },\r\n setup(props: Props, { emit }) {\r\n // dom\r\n const input = ref(null);\r\n\r\n // data\r\n const data = reactive<Data>({\r\n /**\r\n * 当前选择状态\r\n *\r\n * @type {Array}\r\n */\r\n fileList: props.modelValue,\r\n /**\r\n * 拖动是否完成\r\n *\r\n * @type {Boolean}\r\n */\r\n dragOver: false,\r\n /**\r\n * 图片预览\r\n *\r\n * @type {Boolean}\r\n */\r\n imagePreview: false,\r\n /**\r\n * 图片预览列表\r\n *\r\n * @type {Array}\r\n */\r\n imagePreviewList: [],\r\n /**\r\n * 图片预览下标\r\n *\r\n * @type {Number}\r\n */\r\n imagePreviewInitialIndex: 0,\r\n });\r\n\r\n // computed\r\n\r\n const inputWrapClasses = computed(() => {\r\n return [\r\n {\r\n [`${prefixCls}-select`]: props.type === 'select',\r\n },\r\n ];\r\n });\r\n\r\n const inputContentClasses = computed(() => {\r\n return [\r\n {\r\n [`${prefixCls}-content`]: true,\r\n [`${prefixCls}-readonly`]: props.readonly,\r\n [`${prefixCls}-disabled`]: props.disabled,\r\n [`${prefixCls}-drag`]: props.type === 'drag',\r\n [`${prefixCls}-dragOver`]: props.type === 'drag' && data.dragOver,\r\n },\r\n ];\r\n });\r\n\r\n // 判断图片上传数量\r\n const renderUpload = computed(() => {\r\n if (props.modelValue.length >= props.maxCount || !props.showUpload) {\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // methods\r\n\r\n // 点击输入框\r\n const handleClickInput = () => {\r\n if (props.disabled || props.readonly) {\r\n return;\r\n }\r\n\r\n // 剩余数量\r\n const remainCount = +props.maxCount - props.modelValue.length;\r\n\r\n // 到达限制数量禁止上传\r\n if (remainCount === 0) {\r\n return;\r\n }\r\n\r\n input.value.click();\r\n };\r\n\r\n // 拖动\r\n const handleDrag = (e: DragEvent) => {\r\n data.dragOver = false;\r\n\r\n const files = e.dataTransfer.files;\r\n const file = files.length === 1 ? files[0] : [].slice.call(files);\r\n\r\n // 只上传文件\r\n if (files.length === 1) {\r\n // 接受的上传类型\r\n if (props.dragAccept) {\r\n const name = file.name.replace(/.*\\./g, '').toLowerCase();\r\n\r\n const findIndex = props.dragAccept.findIndex(\r\n (accept) => accept === name\r\n );\r\n\r\n if (findIndex > -1) {\r\n uploadFiles(file);\r\n }\r\n // 上传错误提示\r\n else {\r\n emit('on-drag-upload-error', file);\r\n }\r\n }\r\n // 没有限制\r\n else {\r\n uploadFiles(file);\r\n }\r\n }\r\n // 多个文件上传\r\n else {\r\n const arr = [];\r\n const errArr = [];\r\n\r\n file.forEach((item) => {\r\n // 接受的上传类型\r\n if (props.dragAccept) {\r\n const name = item.name.replace(/.*\\./g, '').toLowerCase();\r\n\r\n const findIndex = props.dragAccept.findIndex(\r\n (accept) => accept === name\r\n );\r\n\r\n if (findIndex > -1) {\r\n arr.push(item);\r\n }\r\n // 错误文件\r\n else {\r\n errArr.push(item);\r\n }\r\n } else {\r\n arr.push(item);\r\n }\r\n });\r\n\r\n // 多选\r\n if (errArr.length === 0) {\r\n emit('on-drag-upload-error', errArr);\r\n } else {\r\n uploadFiles(arr);\r\n }\r\n }\r\n };\r\n\r\n // 拖动进入\r\n const handleDragOver = () => {\r\n data.dragOver = true;\r\n };\r\n\r\n // 拖动离开\r\n const handleDragleave = () => {\r\n data.dragOver = false;\r\n };\r\n\r\n // 输入框数据改变\r\n const handleChange = (event) => {\r\n const { files } = event.target as HTMLInputElement;\r\n\r\n if (!files) {\r\n return;\r\n }\r\n\r\n const file =\r\n files.length === 1 ? files[0] : ([].slice.call(files) as File[]);\r\n\r\n // 文件读取前的回调函数\r\n if (props.beforeRead) {\r\n const response = props.beforeRead(file, getDetail());\r\n\r\n // 没有会调重置输入框\r\n if (!response) {\r\n resetInput();\r\n return;\r\n }\r\n\r\n if (isPromise(response)) {\r\n response\r\n .then((data) => {\r\n if (data) {\r\n uploadFiles(data);\r\n } else {\r\n uploadFiles(file);\r\n }\r\n })\r\n .catch(resetInput);\r\n return;\r\n }\r\n }\r\n\r\n // 获取上传文件\r\n uploadFiles(file);\r\n };\r\n\r\n // 获取上传文件\r\n const uploadFiles = (files: File | File[]) => {\r\n // 多个文件\r\n if (Array.isArray(files)) {\r\n // 剩余数量\r\n const remainCount = +props.maxCount - props.modelValue.length;\r\n\r\n if (files.length > remainCount) {\r\n files = files.slice(0, remainCount);\r\n }\r\n\r\n // 表示文件读取结果的类型\r\n Promise.all(\r\n files.map((file) => readFileContent(file, props.resultType))\r\n ).then((contents) => {\r\n const fileList = (files as File[]).map((file, index) => {\r\n const result: UploaderFileListItem = {\r\n file,\r\n status: '',\r\n message: '',\r\n };\r\n\r\n if (contents[index]) {\r\n result.content = contents[index] as string;\r\n }\r\n\r\n return result;\r\n });\r\n\r\n // 文件读取完成后的回调函数\r\n onAfterRead(fileList);\r\n });\r\n }\r\n // 单个文件\r\n else {\r\n // 读取文件数据\r\n readFileContent(files, props.resultType).then((content) => {\r\n const result: UploaderFileListItem = {\r\n file: files as File,\r\n status: '',\r\n message: '',\r\n };\r\n\r\n if (content) {\r\n result.content = content;\r\n }\r\n\r\n // 文件读取完成后的回调函数\r\n onAfterRead(result);\r\n });\r\n }\r\n };\r\n\r\n // 文件读取完成后的回调函数\r\n const onAfterRead = (\r\n items: UploaderFileListItem | UploaderFileListItem[]\r\n ) => {\r\n // 清除输入框数据\r\n resetInput();\r\n\r\n if (isOversize(items, props.maxSize)) {\r\n if (Array.isArray(items)) {\r\n const result = filterFiles(items, props.maxSize);\r\n items = result.valid;\r\n\r\n emit('on-oversize', result.invalid, getDetail());\r\n\r\n if (!items.length) {\r\n return;\r\n }\r\n } else {\r\n emit('on-oversize', items, getDetail());\r\n return;\r\n }\r\n }\r\n\r\n items = reactive(items);\r\n\r\n // emit('update:modelValue', [...props.modelValue, ...toArray(items)]);\r\n emit('update:modelValue', [].concat(props.modelValue, toArray(items)));\r\n\r\n if (props.afterRead) {\r\n props.afterRead(items, getDetail());\r\n }\r\n };\r\n\r\n // 清除输入框数据\r\n const resetInput = () => {\r\n if (input.value) {\r\n input.value.value = '';\r\n }\r\n };\r\n\r\n // 获取详情\r\n const getDetail = (index = props.modelValue.length) => ({\r\n name: props.name,\r\n index,\r\n });\r\n\r\n // 删除函数\r\n const handleRemove = (file: File, index: number) => {\r\n data.fileList.splice(index, 1);\r\n\r\n emit('update:modelValue', data.fileList);\r\n emit('on-delete', file, getDetail(index));\r\n };\r\n\r\n // 查看图片\r\n const handlePreview = (file: File, index: number) => {\r\n emit('on-preview', file);\r\n\r\n if (props.previewFullImage) {\r\n data.imagePreviewList = [...props.modelValue].map((item) => {\r\n return item.url || item.content;\r\n });\r\n\r\n // 传入了预览图片开始位置下标\r\n if (props.previewImageInitialIndex !== -1) {\r\n data.imagePreviewInitialIndex = props.previewImageInitialIndex;\r\n }\r\n // 默认预览图片开始位置下标\r\n else {\r\n data.imagePreviewInitialIndex = index;\r\n }\r\n\r\n data.imagePreview = true;\r\n }\r\n };\r\n\r\n // 关闭全屏图片预览时触发\r\n const handleClosePreview = () => {\r\n emit('on-close-preview');\r\n };\r\n\r\n // 监听数据变化\r\n watch(\r\n () => props.modelValue,\r\n (value) => {\r\n data.fileList = value;\r\n }\r\n );\r\n\r\n return {\r\n prefixCls,\r\n\r\n // data\r\n data,\r\n\r\n // dom\r\n input,\r\n\r\n // computed\r\n inputWrapClasses,\r\n inputContentClasses,\r\n renderUpload,\r\n\r\n // methods\r\n handleClickInput,\r\n handleDrag,\r\n handleDragOver,\r\n handleDragleave,\r\n handleChange,\r\n handleRemove,\r\n handlePreview,\r\n uploadFiles,\r\n getSizeStyle,\r\n handleClosePreview,\r\n };\r\n },\r\n components: {\r\n UploadList,\r\n IvueIcon,\r\n ImagePreview,\r\n },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_normalizeClass","_createCommentVNode","_withDirectives","_openBlock","_createElementBlock","_withModifiers","_renderSlot","_createElementVNode","_normalizeStyle","_createVNode","_createBlock","_createSlots","_withCtx"],"mappings":"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"}