@fesjs/fes-design
Version:
fes-design for PC
335 lines (331 loc) • 8.79 kB
JavaScript
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import { ref, computed, provide, toRefs, watch } from 'vue';
import { isArray, isEqual, isFunction } from 'lodash-es';
import { noop, hasOwn } from '../_util/utils';
import useFormAdaptor from '../_util/use/useFormAdaptor';
import getPrefixCls from '../_util/getPrefixCls';
import { useNormalModel } from '../_util/use/useModel';
import defaultRequest from './ajax';
import { key } from './const';
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
const prefixCls = getPrefixCls('upload');
function genUid(seed) {
return Date.now() + seed;
}
function getFile(rawFile, uploadFiles) {
return uploadFiles.find(file => file.uid === rawFile.uid);
}
var useUpload = (props, emit) => {
const isDragger = ref(false);
const inputRef = ref();
const requestList = ref({});
let tempIndex = 1;
const [uploadFiles, updateUploadFiles] = useNormalModel(props, emit, {
prop: 'fileList'
});
function initFile(rawFile) {
const uid = genUid(tempIndex++);
rawFile.uid = uid;
const file = {
name: rawFile.name,
percentage: 0,
status: 'ready',
size: rawFile.size,
raw: rawFile,
uid,
url: ''
};
return file;
}
function abort(file) {
const _requestList = requestList.value;
if (file) {
const uid = file.uid;
if (_requestList[uid]) {
_requestList[uid].abort();
}
} else {
Object.keys(_requestList).forEach(uid => {
const _uid = uid;
if (_requestList[_uid]) {
_requestList[_uid].abort();
}
delete _requestList[_uid];
});
}
}
function onStart(rawFile) {
const file = initFile(rawFile);
if (props.listType === 'picture-card') {
try {
file.url = URL.createObjectURL(rawFile);
} catch (error) {
console.error('[Upload]', error);
emit('error', {
error,
file,
fileList: uploadFiles.value
});
}
}
uploadFiles.value.push(file);
emit('change', {
file,
fileList: uploadFiles.value
});
}
function onExceed(files) {
emit('exceed', {
files,
fileList: uploadFiles.value
});
}
function onProgress(_ref) {
let {
event,
rawFile
} = _ref;
const file = getFile(rawFile, uploadFiles.value);
if (!file) {
return;
}
file.status = 'uploading';
file.percentage = event.percent || 0;
emit('progress', {
event,
file,
fileList: uploadFiles.value
});
}
function onSuccess(_ref2) {
let {
response,
rawFile
} = _ref2;
const file = getFile(rawFile, uploadFiles.value);
if (!file) {
return;
}
file.status = 'success';
file.response = response;
emit('success', {
response,
file,
fileList: uploadFiles.value
});
emit('change', {
file,
fileList: uploadFiles.value
});
}
function onError(_ref3) {
let {
error,
rawFile
} = _ref3;
const uploadFilesValue = uploadFiles.value;
const file = getFile(rawFile, uploadFilesValue);
if (!file) {
return;
}
file.status = 'error';
emit('error', {
error,
file,
fileList: uploadFilesValue
});
emit('change', {
file,
fileList: uploadFilesValue
});
}
function onRemove(rawFile, file) {
const uploadFilesValue = uploadFiles.value;
file = file || getFile(rawFile, uploadFilesValue);
if (!file) {
return;
}
const doRemove = () => {
abort(file);
uploadFilesValue.splice(uploadFilesValue.indexOf(file), 1);
emit('remove', {
file,
fileList: uploadFilesValue
});
emit('change', {
file,
fileList: uploadFilesValue
});
};
if (!props.beforeRemove) {
return doRemove();
}
if (isFunction(props.beforeRemove)) {
const before = props.beforeRemove(file, uploadFilesValue);
if (before instanceof Promise) {
before.then(() => {
doRemove();
}).catch(noop);
} else if (before !== false) {
doRemove();
}
}
}
const httpRequest = computed(() => {
var _props$httpRequest;
return (_props$httpRequest = props.httpRequest) !== null && _props$httpRequest !== void 0 ? _props$httpRequest : defaultRequest;
});
const post = rawFile => {
if (!props.httpRequest && !props.action) {
onRemove(rawFile);
console.error('[FUpload] 需配置action地址,才能执行上传');
return;
}
const {
uid
} = rawFile;
const options = {
headers: props.headers,
withCredentials: props.withCredentials,
data: props.data,
file: rawFile,
fileName: props.name,
action: props.action,
timeout: props.timeout,
transformResponse: props.transformResponse,
onProgress: e => {
onProgress({
event: e,
rawFile
});
},
onSuccess: res => {
onSuccess({
response: res,
rawFile
});
delete requestList.value[uid];
},
onError: err => {
onError({
error: err,
rawFile
});
delete requestList.value[uid];
}
};
const req = httpRequest.value(options);
requestList.value[uid] = req;
if (req instanceof Promise) {
req.then(options.onSuccess, options.onError);
}
};
const upload = async rawFile => {
inputRef.value.value = null;
if (!props.beforeUpload) {
return post(rawFile);
}
try {
let processedFile = await props.beforeUpload(rawFile);
if (processedFile === false) {
return onRemove(rawFile);
}
const fileType = Object.prototype.toString.call(processedFile);
if (fileType === '[object File]' || fileType === '[object Blob]') {
if (fileType === '[object Blob]') {
processedFile = new File([processedFile], rawFile.name, {
type: rawFile.type
});
}
Object.keys(rawFile).forEach(p => {
if (hasOwn(rawFile, p)) {
processedFile[p] = rawFile[p];
}
});
post(processedFile);
} else {
post(rawFile);
}
} catch (e) {
onRemove(rawFile);
}
};
const onUploadFiles = files => {
files = Array.from(files);
if (props.multipleLimit && props.fileList.length + files.length > props.multipleLimit) {
onExceed(files);
return;
}
let postFiles = files;
if (!props.multiple) {
postFiles = postFiles.slice(0, 1);
}
if (postFiles.length === 0) {
return;
}
postFiles.forEach(rawFile => {
onStart(rawFile);
upload(rawFile);
});
};
// 表单组件的总体disabled状态
const {
isFormDisabled
} = useFormAdaptor();
provide(key, _objectSpread(_objectSpread({}, toRefs(props)), {}, {
disabled: computed(() => {
return props.disabled || isFormDisabled.value;
}),
prefixCls,
uploadFiles,
onRemove,
onUploadFiles,
inputRef,
isDragger
}));
watch(() => props.fileList, fileList => {
if (!isArray(fileList)) {
fileList = [];
}
if (!isEqual(uploadFiles.value, fileList)) {
uploadFiles.value = fileList.map(file => {
return _objectSpread(_objectSpread({}, file), {}, {
uid: file.uid || genUid(tempIndex++),
status: file.status || 'success'
});
});
}
}, {
immediate: true,
deep: true
});
function clearFiles() {
updateUploadFiles([]);
}
function addFile(rawFile) {
if (!rawFile) {
return;
}
if (props.multipleLimit && props.fileList.length + 1 > props.multipleLimit) {
onExceed([rawFile]);
return;
}
onStart(rawFile);
upload(rawFile);
}
function removeFile(file) {
if (!file) {
return;
}
onRemove(null, file);
}
return {
uploadFiles,
isDragger,
clearFiles,
addFile,
removeFile
};
};
export { useUpload as default };