Skip to content

Commit

Permalink
feat: FUpload组件 fileList 支持 v-model 双向绑定 (#336)
Browse files Browse the repository at this point in the history
* fix: 解决上传组件,初始列表为空时清空无效的问题

* feat: upload组件 fileList 支持 v-model 双向绑定

* feat: upload组件,监听fileList变更逻辑优化
  • Loading branch information
ocean-gao authored Jun 26, 2023
1 parent 5636831 commit 490f515
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 36 deletions.
10 changes: 9 additions & 1 deletion components/upload/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,15 @@ export type UploadProps = Partial<ExtractPropTypes<typeof uploadProps>>;
export default defineComponent({
name: 'FUpload',
props: uploadProps,
emits: ['change', 'remove', 'success', 'error', 'progress', 'exceed'],
emits: [
'change',
'remove',
'success',
'error',
'progress',
'exceed',
'update:fileList',
],
setup(props, ctx) {
useTheme();
const { uploadFiles, isDragger } = useUpload(props, ctx.emit);
Expand Down
14 changes: 6 additions & 8 deletions components/upload/useUpload.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ref, provide, watch, computed, toRefs } from 'vue';
import { isEqual, isFunction, cloneDeep } from 'lodash-es';
import { 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 { key } from './const';

import type { UploadProps } from './upload';
Expand All @@ -22,13 +23,13 @@ function getFile(rawFile: UploadFile, uploadFiles: FileItem[]) {
export default (props: UploadProps, emit: any) => {
const isDragger = ref(false);
const inputRef = ref();
const uploadFiles = ref([]);
const requestList = ref<{
[key: number | string]: XMLHttpRequest;
}>({});
let cachedFiles: FileItem[] = [];
let tempIndex = 1;

const [uploadFiles] = useNormalModel(props, emit, { prop: 'fileList' });

function initFile(rawFile: UploadFile) {
const uid = genUid(tempIndex++);
rawFile.uid = uid;
Expand Down Expand Up @@ -269,13 +270,10 @@ export default (props: UploadProps, emit: any) => {
watch(
() => props.fileList,
(fileList) => {
if (!isEqual(cachedFiles, fileList)) {
cachedFiles = [];
if (!isEqual(uploadFiles.value, fileList)) {
uploadFiles.value = fileList.map((file) => {
const cloneFile = cloneDeep(file);
cachedFiles.push(cloneFile);
return {
...cloneFile,
...file,
uid: file.uid || genUid(tempIndex++),
status: file.status || 'success',
};
Expand Down
34 changes: 8 additions & 26 deletions docs/.vitepress/components/upload/common.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<FUpload
v-model:fileList="fileList"
action="https://run.mocky.io/v3/2d9d9844-4a46-4145-8f57-07e13768f565"
multiple
:multipleLimit="4"
:fileList="fileList"
:accept="accept"
:beforeUpload="beforeUpload"
@change="change"
Expand All @@ -25,41 +25,23 @@ import { ref } from 'vue';
export default {
setup() {
const fileList = ref([
{
uid: '1',
name: 'xxx.png',
status: 'done',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/xxx.png',
},
{
uid: '2',
name: 'yyy.png',
status: 'done',
url: 'http://www.baidu.com/yyy.png',
},
{
uid: '3',
name: 'zzz.png',
status: 'error',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/zzz.png',
},
]);
const fileList = ref([]);
const accept = ['image/*'];
const change = (param) => {
console.log('change:', param);
};
const remove = (param) => {
console.log('remove:', param);
console.log('remove:', param, fileList.value);
};
const success = (param) => {
console.log('success:', param);
console.log('success:', param, fileList.value);
};
const error = (param) => {
console.log('error:', param);
fileList.value = fileList.value.filter(
(file) => file.status !== 'error',
);
console.log('error:', param, fileList.value);
};
const exceed = (param) => {
console.log('exceed:', param);
Expand Down
6 changes: 5 additions & 1 deletion docs/.vitepress/components/upload/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ app.use(FUpload);

--COMMON

### 初始列表

--INITLIST

### 自定义上传的触发器

--DEFAULT
Expand Down Expand Up @@ -54,7 +58,7 @@ app.use(FUpload);
| beforeRemove | 删除文件之前的钩子,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除 | (file: FileItem, fileList: FileItem[]) => boolean \| Promise\<boolean\> | - |
| disabled | 是否禁用 | boolean | `false` |
| data | 上传接口附带的数据 | object | `{}` |
| fileList | 上传的文件列表, 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]| FileItem[] | `[]` |
| fileList(v-model) | 上传的文件列表, 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]| FileItem[] | `[]` |
| headers | 上传接口中请求附带的请求头 | object | `{}` |
| listType(第一期只支持`text`| 文件列表的类型,可选值有`text` / `picture-card` | string | `text` |
| multiple | 是否支持多选文件 | boolean | `false` |
Expand Down
98 changes: 98 additions & 0 deletions docs/.vitepress/components/upload/initList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<template>
<FUpload
action="https://run.mocky.io/v3/2d9d9844-4a46-4145-8f57-07e13768f565"
multiple
:multipleLimit="4"
:fileList="fileList"
:accept="accept"
:beforeUpload="beforeUpload"
@change="change"
@remove="remove"
@success="success"
@error="error"
@exceed="exceed"
@progress="progress"
>
<template #tip>
<div class="f-upload__tip">
只能上传 jpg/png 等图片文件,且不超过 5KB
</div>
</template>
</FUpload>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const fileList = ref([
{
uid: '1',
name: 'xxx.png',
status: 'done',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/xxx.png',
},
{
uid: '2',
name: 'yyy.png',
status: 'done',
url: 'http://www.baidu.com/yyy.png',
},
{
uid: '3',
name: 'zzz.png',
status: 'error',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/zzz.png',
},
]);
const accept = ['image/*'];
const change = (param) => {
console.log('change:', param);
};
const remove = (param) => {
console.log('remove:', param, fileList.value);
};
const success = (param) => {
console.log('success:', param, fileList.value);
};
const error = (param) => {
console.log('error:', param, fileList.value);
};
const exceed = (param) => {
console.log('exceed:', param);
};
const progress = (param) => {
console.log('progress:', param);
};
const beforeUpload = async (file) => {
console.log('file:', file);
if (file.size > 500 * 1024) {
console.log('超出5KB,无法上传!');
return false;
}
return true;
};
return {
fileList,
accept,
change,
remove,
success,
error,
exceed,
progress,
beforeUpload,
};
},
};
</script>
<style>
.f-upload__tip {
font-size: 12px;
margin-top: 7px;
color: #93949b;
}
</style>

0 comments on commit 490f515

Please sign in to comment.