import { ElUpload, ElIcon, ElProgress } from 'element-plus' import { SuccessFilled, CircleCloseFilled, Paperclip } from '@element-plus/icons-vue' import './index.less' import { toRefs, defineComponent, computed } from 'vue' import CipButton from '@cip/components/cip-button' export default defineComponent({ name: 'CipUpload', props: { uploadFile: { // 文件上传 type: Function, default: (info) => {} }, accept: { // 可选择文件类型控制 type: String, default: '' // 所有 }, beforeRemove: Function, // 删除文件之前的钩子 onRemove: Function, // 文件列表移除文件时的钩子 beforeUpload: Function, // 上传文件之前的钩子 onError: Function, // 文件上传失败时的钩子 onSuccess: Function, // 文件上传成功时的钩子 onPreview: Function, // 点击文件列表中已上传的文件时的钩子 fileList: { type: Array, default: () => [] }, // 默认上传文件 multiple: Boolean, // 是否允许多个 disabled: Boolean, // 禁用状态 drag: Boolean, // 是否拖拽上传 action: String, // 上传地址 limit: Number, // 上传数量限制 showFileList: { // 是否展示默认,后期考虑不用默认的 type: Boolean, default: true }, itemStyle: { // 文件列表的行内样式 type: Object, default: () => ({}) }, listType: { // 展示形式 type: String, default: 'text' } }, emits: ['update:fileList'], inheritAttrs: false, setup (props, { slots, emit, attrs }) { const { fileList } = toRefs(props) const uploadDisabled = computed(() => props.disabled || props.limit <= fileList.value.length) function genDefault () { if (props.drag) { // 拖拽 return
点击或将文件拖拽到这里上传
{slots.tip?.()}
} else if (props.listType === 'picture-card') { // 缩略图 return uploadDisabled.value ||
上传
} else { // 默认 return } } async function deleteItem (index) { const uploadFiles = fileList.value.concat() const file = uploadFiles.splice(index, 1)[0] let flag try { flag = await props.beforeRemove?.(file, uploadFiles) } catch (err) { flag = props.beforeRemove?.(file, uploadFiles) } // 如果beforeRemove函数不存在 或者 返回值为true if (flag || !props.beforeRemove) { emit('update:fileList', uploadFiles) props.onRemove?.(file, uploadFiles) } } function genUpload (slots) { return emit('update:fileList', list)} class={'cip-upload-content'} action={props.action} httpRequest={httpRequest} beforeUpload={props.beforeUpload} multiple={props.multiple} disabled={props.disabled} accept={props.accept} drag={props.drag} show-file-list={false} > {{ // 1. default或者trigger存在,不渲染默认;渲染对应的default或者trigger;trigger在下面一行渲染 default: () => slots.default?.() || (slots.trigger ? undefined : genDefault()), // 这个trigger要这么写,如果给它赋值函数,会出bug trigger: slots.trigger ? () => slots.trigger() : undefined, tip: () => props.drag ||
{slots.tip?.()}
}}
} function httpRequest (opts) { function setStatus (status, uploadFile) { const uid = opts.file.uid const index = fileList.value.findIndex(file => file.uid === uid) if (status === 'error') { Object.assign(fileList.value[index], { status, opts }) } else if (status === 'success') { Object.assign(fileList.value[index], { status, ...uploadFile, opts: undefined }) } emit('update:fileList', fileList.value.concat()) } props.uploadFile(opts)?.then(file => { setStatus('success', file) props.onSuccess?.(file, opts.file, fileList.value.concat()) }).catch((err) => { setStatus('error') props.onError?.(err, opts.file, fileList.value.concat()) }) } function reUpload (item) { item.status = 'ready' httpRequest(item.opts) } function genItems () { return <> {genUpload(slots)} { fileList.value?.length === 0 ? undefined : } } function genPictureCard () { return <>
{slots.tip?.()}
} function genPicture () { return <> {genUpload(slots)} { fileList.value?.length === 0 ? undefined : } } const renderTypeMap = { text: genItems, 'picture-card': genPictureCard, picture: genPicture } return () =>
{ props.showFileList ? (renderTypeMap[props.listType]?.()) : genUpload(slots) }
} })