Skip to content

Commit

Permalink
Merge pull request #909 from WeBankFinTech/feat-inputFile-cancel
Browse files Browse the repository at this point in the history
feat(InputFile): 增加 FileItem 类型 uid 属性 及完善 自定义 slot 文档示例
  • Loading branch information
zym19960704 authored Nov 27, 2024
2 parents b447d0d + 655db05 commit 21985aa
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 8 deletions.
8 changes: 6 additions & 2 deletions components/input-file/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ import type {
ExtractPublicPropTypes,
} from '../_util/interface';

export interface FileItem extends File {
uid?: number | string;
}

const commonProps = {
modelValue: {
type: Array as PropType<File[]>,
default: (): File[] => [],
type: Array as PropType<FileItem[]>,
default: (): FileItem[] => [],
},
accept: {
type: Array as PropType<string[]>,
Expand Down
13 changes: 12 additions & 1 deletion components/input-file/useInputFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { computed, ref } from 'vue';
import { CHANGE_EVENT } from '../_util/constants';
import useFormAdaptor from '../_util/use/useFormAdaptor';
import { useNormalModel } from '../_util/use/useModel';
import type { InputFileEmit, InputFileProps } from './props';
import type { FileItem, InputFileEmit, InputFileProps } from './props';

function genUid(seed: number) {
return Date.now() + seed;
}

// <input type="file" /> 所需的数据
export const useInputFile = (props: InputFileProps, emit: InputFileEmit) => {
Expand All @@ -27,6 +31,8 @@ export const useInputFile = (props: InputFileProps, emit: InputFileEmit) => {
inputRef.value.click();
};

let tempIndex = 1;

const handleInputFileChange = (e: Event): void => {
const target = e.target as HTMLInputElement;

Expand All @@ -35,6 +41,11 @@ export const useInputFile = (props: InputFileProps, emit: InputFileEmit) => {
return;
}

files.forEach((rawFile: FileItem) => {
const uid = genUid(tempIndex++);
rawFile.uid = uid;
});

updateCurrentFiles(files);
emit(CHANGE_EVENT, files);

Expand Down
125 changes: 125 additions & 0 deletions docs/.vitepress/components/inputFile/custom.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<template>
<FForm layout="inline" :inlineItemWidth="120">
<FFormItem label="多选:">
<FSwitch v-model="multiple" />
</FFormItem>
<FFormItem label="禁用:">
<FSwitch v-model="disabled" />
</FFormItem>
</FForm>

<FDivider />

<FInputFile
v-model="fileList"
:multiple="multiple"
:disabled="disabled"
:accept="['image/*']"
@change="handleChange"
>
<FButton type="info" :disabled="disabled">
<template #icon>
<UploadOutlined />
</template>
请选择文件
</FButton>

<template #fileList="{ files }">
<div class="file-list">
<div
v-for="file in files"
:key="file.uid"
class="file-list-item"
>
<div class="file-list-name-wrapper">
<slot name="file" :file="file">
<FileOutlined />
<div class="file-list-name">{{ file.name }}</div>
</slot>
</div>
<div class="file-list-icon">
<CloseCircleFilled
v-if="!disabled"
class="file-list-icon-close"
@click="() => handleRemoveFile(file.uid)"
/>
</div>
</div>
</div>
</template>
</FInputFile>
</template>

<script setup>
import { ref } from 'vue';
const multiple = ref(true);
const disabled = ref(false);
const fileList = ref([]);
const handleChange = (files) =>
console.log('[inputFile.customSelect] [handleChange] files:', files, ', fileList:', fileList.value);
const handleRemoveFile = (uid) => {
const targetIndex = fileList.value.findIndex((file) => file.uid === uid);
fileList.value.splice(targetIndex, 1);
};
</script>

<style scoped lang="less">
.file-list {
width: 100%;
color: var(--f-sub-head-color);
font-size: var(--f-font-size-base);
line-height: 24px;
&-item {
display: flex;
align-items: center;
margin-top: 4px;
border-radius: var(--f-border-radius-sm);
&:first-child {
margin-top: 8px;
}
&:last-child {
margin-bottom: 8px;
}
.file-list-name-wrapper {
display: flex;
flex: 1;
align-items: center;
.file-list-name {
margin-left: 6px;
}
}
.file-list-icon {
display: flex;
align-items: center;
justify-content: flex-end;
width: 40px;
color: var(--f-text-color-secondary);
&-close {
display: none;
padding: 2px;
}
}
&:hover {
background-color: var(--f-hover-color-light);
.file-list-icon {
&-close {
display: inline-block;
}
}
}
}
}
:deep(.fes-input-file .fes-input-file-visible-content) {
display: flex;
flex-direction: column;
align-items: flex-start;
.fes-input-file-file-list {
width: 100%;
max-width: 500px;
}
}
</style>
26 changes: 21 additions & 5 deletions docs/.vitepress/components/inputFile/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,27 @@ basic.vue
dragAndDrop.vue
:::

## Props
### 自定义

:::demo
custom.vue
:::

## InputFile Props
| 属性 | 说明 | 类型 | 默认值 |
|----------|----------------|------------|---------|
| v-model | 选择的文件 | `File[]` | `[]` |
| v-model | 选择的文件 | `FileItem[]` | `[]` |
| multiple | 是否支持多选文件 | `boolean` | `false` |
| accept | 接受的文件类型 | `string[]` | `[]` |
| disabled | 是否禁用 | `boolean` | `false` |

## Events
## InputFile Events

| 事件名称 | 说明 | 回调参数 |
|----------|--------------|---------------------------|
| change | 选择文件后调用 | `(files: File[]) => void` |
| change | 选择文件后调用 | `(files: FileItem[]) => void` |

## Slots
## InputFile Slots

| 名称 | 说明 | 参数 |
|----------|--------------------|-------------|
Expand All @@ -48,3 +54,13 @@ dragAndDrop.vue
| 属性 | 说明 | 类型 | 默认值 |
|-------------------|--------------------------------------------------------------------|---------------------------|--------|
| onFileTypeInvalid | 拖拽文件类型不满足 `accept` 时的钩子函数,<br/>若未定义则使用内置提示 | `(files: File[]) => void` | - |

## 类型

### FileItem

```ts
interface FileItem extends File {
uid?: number | string;
}
```

0 comments on commit 21985aa

Please sign in to comment.