fast-element-plus 2.0.12 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/components/upload/src/upload.mjs +2 -9
- package/dist/components/upload/src/upload.mjs.map +1 -1
- package/dist/components/upload/src/useUpload.d.ts +1 -0
- package/dist/components/upload/src/useUpload.mjs +27 -12
- package/dist/components/upload/src/useUpload.mjs.map +1 -1
- package/dist/components/uploadImage/src/uploadImage.d.ts +21 -9
- package/dist/components/uploadImage/src/uploadImage.mjs +13 -5
- package/dist/components/uploadImage/src/uploadImage.mjs.map +1 -1
- package/dist/components/uploadImages/src/uploadImages.mjs +5 -3
- package/dist/components/uploadImages/src/uploadImages.mjs.map +1 -1
- package/dist/constants/regex.d.ts +14 -2
- package/dist/constants/regex.mjs +18 -6
- package/dist/constants/regex.mjs.map +1 -1
- package/dist/index.global.min.js +2 -2
- package/dist/index.global.min.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Fast.Element.Plus are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.0.14] - 2026-09-10
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Restricted `FaUploadImage` to a `string | null` model and fixed it to single-file selection.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Prevented upload validation from cancelling valid `FaUpload` requests before Element Plus synchronizes its file list.
|
|
14
|
+
- Validated file type and size when files are selected in manual-upload mode, and kept only the newly successful file in single-file mode.
|
|
15
|
+
- Preserved existing upload-file metadata while synchronizing URL models and derived new file names from the final URL path without query parameters or fragments.
|
|
16
|
+
|
|
17
|
+
## [2.0.13] - 2026-09-04
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Tightened mainland China mobile-number validation and expanded email validation to support standard local-part characters and general top-level domains.
|
|
22
|
+
- Added medium-password, six-digit verification-code, and four-character image-CAPTCHA regular expressions, and disallowed whitespace in medium and strong passwords.
|
|
23
|
+
|
|
5
24
|
## [2.0.12] - 2026-09-03
|
|
6
25
|
|
|
7
26
|
### Changed
|
|
@@ -136,6 +155,8 @@ All notable changes to Fast.Element.Plus are documented in this file.
|
|
|
136
155
|
- Scoped Table styles and added responsive IconSelector styling.
|
|
137
156
|
- Improved dialogs, drawers, tables, forms, trees, selectors, car-number input, images, and uploads for dark mode, touch input, and narrow viewports.
|
|
138
157
|
|
|
158
|
+
[2.0.14]: https://gitee.com/FastDotnet/fast.element.plus/releases/tag/v2.0.14
|
|
159
|
+
[2.0.13]: https://gitee.com/FastDotnet/fast.element.plus/releases/tag/v2.0.13
|
|
139
160
|
[2.0.12]: https://gitee.com/FastDotnet/fast.element.plus/releases/tag/v2.0.12
|
|
140
161
|
[2.0.11]: https://gitee.com/FastDotnet/fast.element.plus/releases/tag/v2.0.11
|
|
141
162
|
[2.0.10]: https://gitee.com/FastDotnet/fast.element.plus/releases/tag/v2.0.10
|
|
@@ -46,7 +46,7 @@ var upload_default = defineComponent({
|
|
|
46
46
|
emits: faUploadEmits,
|
|
47
47
|
slots: makeSlots(),
|
|
48
48
|
setup(props, { slots, emit, expose }) {
|
|
49
|
-
const { fileList, loading, formContext, maxSizeMB, handleHttpRequest, handleOnSuccess, handleOnError, handleOnRemove, handleOnExceed, handleOnUpload } = useUpload("FaUpload", "文件", props, emit, {
|
|
49
|
+
const { fileList, loading, formContext, maxSizeMB, handleHttpRequest, handleOnSuccess, handleOnError, handleOnRemove, handleOnExceed, handleOnUpload, handleOnChange } = useUpload("FaUpload", "文件", props, emit, {
|
|
50
50
|
get maxSize() {
|
|
51
51
|
return props.maxSize;
|
|
52
52
|
},
|
|
@@ -62,15 +62,8 @@ var upload_default = defineComponent({
|
|
|
62
62
|
});
|
|
63
63
|
const uploadRef = ref();
|
|
64
64
|
const httpRequest = computed(() => props.httpRequest === uploadProps.httpRequest.default ? handleHttpRequest : props.httpRequest);
|
|
65
|
-
const handleOnChange = (uploadFile, uploadFiles) => {
|
|
66
|
-
if (uploadFile.status === "ready" && !handleOnUpload(uploadFile)) {
|
|
67
|
-
fileList.value = fileList.value.filter((item) => item.uid !== uploadFile.uid);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
props.onChange?.(uploadFile, uploadFiles);
|
|
71
|
-
};
|
|
72
65
|
const handleBeforeUpload = (rawFile) => {
|
|
73
|
-
if (!
|
|
66
|
+
if (!handleOnUpload(rawFile)) return false;
|
|
74
67
|
return props.beforeUpload?.(rawFile) ?? true;
|
|
75
68
|
};
|
|
76
69
|
const elUploadProps = useProps(props, uploadProps, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.mjs","names":["update:modelValue","update:fileList"],"sources":["../../../../src/components/upload/src/upload.tsx"],"sourcesContent":["import { Fragment, computed, defineComponent, ref } from \"vue\";\nimport { UploadFilled } from \"@element-plus/icons-vue\";\nimport { ElIcon, ElUpload, uploadProps } from \"element-plus\";\nimport { isArray, isNull, isString } from \"lodash-unified\";\nimport { definePropType, makeSlots, useExpose, useProps, useRender } from \"../../../utils\";\nimport { useUpload } from \"./useUpload\";\nimport type { UploadFile, UploadInstance, UploadProps, UploadUserFile } from \"element-plus\";\nimport type { VNode } from \"vue\";\n\n/** FaUpload 的运行时 Props 定义。 */\nexport const faUploadProps = {\n\t...uploadProps,\n\t/** @description whether to activate drag and drop mode */\n\tdrag: {\n\t\ttype: Boolean,\n\t\tdefault: true,\n\t},\n\t/** @description maximum number of uploads allowed */\n\tlimit: {\n\t\ttype: Number,\n\t\tdefault: 1,\n\t},\n\t/** @description v-model绑定值 */\n\tmodelValue: definePropType<string | string[] | null>([String, Array]),\n\t/** @description 大小限制,单位kb */\n\tmaxSize: {\n\t\ttype: definePropType<string | number>([String, Number]),\n\t\tdefault: 5120,\n\t},\n\t/** @description 图片上传接口,优先级最高 */\n\tuploadApi: {\n\t\ttype: definePropType<(formData: FormData) => Promise<string>>(Function),\n\t},\n\t/** @description 图片上传地址 */\n\tuploadUrl: String,\n};\n\n/** FaUpload 的运行时 Emits 定义。 */\nexport const faUploadEmits = {\n\t/** @description v-model 回调 */\n\t\"update:modelValue\": (value: string | string[] | null): boolean => isString(value) || isArray(value) || isNull(value),\n\t/** @description v-model:fileList 回调 */\n\t\"update:fileList\": (value: UploadUserFile[]): boolean => isArray(value),\n};\n\n/** FaUpload 的插槽参数。 */\nexport interface FaUploadSlots extends Record<string, unknown> {\n\t/** @description 默认内容插槽 */\n\tdefault: never;\n\t/** @description 触发文件选择框的内容 */\n\ttrigger: never;\n\t/** @description 提示说明文字 */\n\ttip: never;\n\t/** @description 缩略图模板的内容 */\n\tfile: { file: UploadFile; index: number };\n}\n\nexport default defineComponent({\n\tname: \"FaUpload\",\n\tprops: faUploadProps,\n\temits: faUploadEmits,\n\tslots: makeSlots<FaUploadSlots>(),\n\tsetup(props, { slots, emit, expose }) {\n\t\tconst {\n\t\t\tfileList,\n\t\t\tloading,\n\t\t\tformContext,\n\t\t\tmaxSizeMB,\n\t\t\thandleHttpRequest,\n\t\t\thandleOnSuccess,\n\t\t\thandleOnError,\n\t\t\thandleOnRemove,\n\t\t\thandleOnExceed,\n\t\t\thandleOnUpload,\n\t\t} = useUpload(\"FaUpload\", \"文件\", props, emit, {\n\t\t\tget maxSize() {\n\t\t\t\treturn props.maxSize;\n\t\t\t},\n\t\t\tget uploadApi() {\n\t\t\t\treturn props.uploadApi;\n\t\t\t},\n\t\t\tget uploadUrl() {\n\t\t\t\treturn props.uploadUrl || (props.action === uploadProps.action.default ? undefined : props.action);\n\t\t\t},\n\t\t});\n\n\t\tconst disabled = computed(() => {\n\t\t\treturn props.disabled === true || formContext?.disabled === true;\n\t\t});\n\n\t\tconst uploadRef = ref<UploadInstance>();\n\t\tconst httpRequest = computed(() => (props.httpRequest === uploadProps.httpRequest.default ? handleHttpRequest : props.httpRequest));\n\n\t\tconst
|
|
1
|
+
{"version":3,"file":"upload.mjs","names":["update:modelValue","update:fileList"],"sources":["../../../../src/components/upload/src/upload.tsx"],"sourcesContent":["import { Fragment, computed, defineComponent, ref } from \"vue\";\nimport { UploadFilled } from \"@element-plus/icons-vue\";\nimport { ElIcon, ElUpload, uploadProps } from \"element-plus\";\nimport { isArray, isNull, isString } from \"lodash-unified\";\nimport { definePropType, makeSlots, useExpose, useProps, useRender } from \"../../../utils\";\nimport { useUpload } from \"./useUpload\";\nimport type { UploadFile, UploadInstance, UploadProps, UploadUserFile } from \"element-plus\";\nimport type { VNode } from \"vue\";\n\n/** FaUpload 的运行时 Props 定义。 */\nexport const faUploadProps = {\n\t...uploadProps,\n\t/** @description whether to activate drag and drop mode */\n\tdrag: {\n\t\ttype: Boolean,\n\t\tdefault: true,\n\t},\n\t/** @description maximum number of uploads allowed */\n\tlimit: {\n\t\ttype: Number,\n\t\tdefault: 1,\n\t},\n\t/** @description v-model绑定值 */\n\tmodelValue: definePropType<string | string[] | null>([String, Array]),\n\t/** @description 大小限制,单位kb */\n\tmaxSize: {\n\t\ttype: definePropType<string | number>([String, Number]),\n\t\tdefault: 5120,\n\t},\n\t/** @description 图片上传接口,优先级最高 */\n\tuploadApi: {\n\t\ttype: definePropType<(formData: FormData) => Promise<string>>(Function),\n\t},\n\t/** @description 图片上传地址 */\n\tuploadUrl: String,\n};\n\n/** FaUpload 的运行时 Emits 定义。 */\nexport const faUploadEmits = {\n\t/** @description v-model 回调 */\n\t\"update:modelValue\": (value: string | string[] | null): boolean => isString(value) || isArray(value) || isNull(value),\n\t/** @description v-model:fileList 回调 */\n\t\"update:fileList\": (value: UploadUserFile[]): boolean => isArray(value),\n};\n\n/** FaUpload 的插槽参数。 */\nexport interface FaUploadSlots extends Record<string, unknown> {\n\t/** @description 默认内容插槽 */\n\tdefault: never;\n\t/** @description 触发文件选择框的内容 */\n\ttrigger: never;\n\t/** @description 提示说明文字 */\n\ttip: never;\n\t/** @description 缩略图模板的内容 */\n\tfile: { file: UploadFile; index: number };\n}\n\nexport default defineComponent({\n\tname: \"FaUpload\",\n\tprops: faUploadProps,\n\temits: faUploadEmits,\n\tslots: makeSlots<FaUploadSlots>(),\n\tsetup(props, { slots, emit, expose }) {\n\t\tconst {\n\t\t\tfileList,\n\t\t\tloading,\n\t\t\tformContext,\n\t\t\tmaxSizeMB,\n\t\t\thandleHttpRequest,\n\t\t\thandleOnSuccess,\n\t\t\thandleOnError,\n\t\t\thandleOnRemove,\n\t\t\thandleOnExceed,\n\t\t\thandleOnUpload,\n\t\t\thandleOnChange,\n\t\t} = useUpload(\"FaUpload\", \"文件\", props, emit, {\n\t\t\tget maxSize() {\n\t\t\t\treturn props.maxSize;\n\t\t\t},\n\t\t\tget uploadApi() {\n\t\t\t\treturn props.uploadApi;\n\t\t\t},\n\t\t\tget uploadUrl() {\n\t\t\t\treturn props.uploadUrl || (props.action === uploadProps.action.default ? undefined : props.action);\n\t\t\t},\n\t\t});\n\n\t\tconst disabled = computed(() => {\n\t\t\treturn props.disabled === true || formContext?.disabled === true;\n\t\t});\n\n\t\tconst uploadRef = ref<UploadInstance>();\n\t\tconst httpRequest = computed(() => (props.httpRequest === uploadProps.httpRequest.default ? handleHttpRequest : props.httpRequest));\n\n\t\tconst handleBeforeUpload: UploadProps[\"beforeUpload\"] = (rawFile) => {\n\t\t\tif (!handleOnUpload(rawFile)) return false;\n\t\t\treturn props.beforeUpload?.(rawFile) ?? true;\n\t\t};\n\n\t\tconst elUploadProps = useProps(props, uploadProps, [\n\t\t\t\"fileList\",\n\t\t\t\"disabled\",\n\t\t\t\"httpRequest\",\n\t\t\t\"beforeUpload\",\n\t\t\t\"onExceed\",\n\t\t\t\"onSuccess\",\n\t\t\t\"onError\",\n\t\t\t\"onRemove\",\n\t\t\t\"onChange\",\n\t\t]);\n\n\t\tuseRender(() => (\n\t\t\t<ElUpload\n\t\t\t\t{...elUploadProps.value}\n\t\t\t\tref={uploadRef}\n\t\t\t\tclass=\"fa-upload\"\n\t\t\t\tvLoading={loading.value}\n\t\t\t\tvModel:fileList={fileList.value}\n\t\t\t\tdisabled={disabled.value}\n\t\t\t\thttpRequest={httpRequest.value}\n\t\t\t\tbeforeUpload={handleBeforeUpload}\n\t\t\t\tonExceed={handleOnExceed}\n\t\t\t\tonSuccess={handleOnSuccess}\n\t\t\t\tonError={handleOnError}\n\t\t\t\tonRemove={handleOnRemove}\n\t\t\t\tonChange={handleOnChange}\n\t\t\t>\n\t\t\t\t{{\n\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\tslots.default ? (\n\t\t\t\t\t\t\tslots.default()\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t<ElIcon class=\"el-icon--upload\">\n\t\t\t\t\t\t\t\t\t<UploadFilled />\n\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t<div class=\"el-upload__text\">\n\t\t\t\t\t\t\t\t\tDrop file here or <em>click to upload</em>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t),\n\t\t\t\t\t...(slots.trigger && { trigger: (): VNode | VNode[] => slots.trigger?.() ?? [] }),\n\t\t\t\t\ttip: () =>\n\t\t\t\t\t\tslots.tip ? (\n\t\t\t\t\t\t\tslots.tip()\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t<div class=\"el-upload__tip\">files with a size less than {maxSizeMB.value.toString()}MB</div>\n\t\t\t\t\t\t\t\t{!props.showFileList && fileList.value.length > 0 && (\n\t\t\t\t\t\t\t\t\t<div class=\"el-upload__tip\">\n\t\t\t\t\t\t\t\t\t\t{fileList.value.map((item, index) => (\n\t\t\t\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t\t\t\t{item.name}\n\t\t\t\t\t\t\t\t\t\t\t\t{fileList.value.length <= index && <br />}\n\t\t\t\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t),\n\t\t\t\t\t...(slots.file && {\n\t\t\t\t\t\tfile: ({ file, index }: { file: UploadFile; index: number }): VNode | VNode[] => slots.file?.({ file, index }) ?? [],\n\t\t\t\t\t}),\n\t\t\t\t}}\n\t\t\t</ElUpload>\n\t\t));\n\n\t\treturn useExpose(expose, {\n\t\t\t/** @description 取消上传请求 */\n\t\t\tabort: computed(() => uploadRef.value?.abort),\n\t\t\t/** @description 手动上传文件列表 */\n\t\t\tsubmit: computed(() => uploadRef.value?.submit),\n\t\t\t/** @description 清空已上传的文件列表(该方法不支持在 before-upload 中调用) */\n\t\t\tclearFiles: computed(() => uploadRef.value?.clearFiles),\n\t\t\t/** @description 手动选择文件 */\n\t\t\thandleStart: computed(() => uploadRef.value?.handleStart),\n\t\t\t/** @description 手动移除文件。file 和 rawFile 已被合并。 */\n\t\t\thandleRemove: computed(() => uploadRef.value?.handleRemove),\n\t\t\t/** @description 加载状态 */\n\t\t\tloading,\n\t\t\t/** @description 文件集合 */\n\t\t\tfileList,\n\t\t});\n\t},\n});\n"],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ interface UploadComposable {
|
|
|
14
14
|
handleOnRemove: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void;
|
|
15
15
|
handleOnExceed: (files: File[], uploadFiles: UploadUserFile[]) => void;
|
|
16
16
|
handleOnUpload: (file: UploadFile | UploadRawFile) => boolean;
|
|
17
|
+
handleOnChange: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void;
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* 创建上传组件共享的文件状态和操作方法。
|
|
@@ -34,14 +34,16 @@ const useUpload = (componentName, fileTypeName, props, emit, data) => {
|
|
|
34
34
|
if (!props.disabled && props.autoUpload && !data?.uploadApi && !data?.uploadUrl && props.httpRequest === uploadProps.httpRequest.default) console.warn(`[Fast:${componentName}]`, "uploadApi 和 uploadUrl 至少需要提供一个。");
|
|
35
35
|
});
|
|
36
36
|
const handleValue = (files = fileList.value) => {
|
|
37
|
+
let value;
|
|
37
38
|
if (files.length > 0) {
|
|
38
|
-
if (props.multiple === true)
|
|
39
|
+
if (props.multiple === true) value = files.flatMap((item) => item.url ? [item.url] : []);
|
|
39
40
|
else {
|
|
40
41
|
const fileUrl = files[0]?.url;
|
|
41
42
|
if (!fileUrl) return;
|
|
42
|
-
|
|
43
|
+
value = fileUrl;
|
|
43
44
|
}
|
|
44
|
-
} else
|
|
45
|
+
} else value = props.multiple === true ? [] : null;
|
|
46
|
+
emit("update:modelValue", value);
|
|
45
47
|
};
|
|
46
48
|
const handleHttpRequest = async (options) => {
|
|
47
49
|
const propsData = options.data;
|
|
@@ -72,9 +74,9 @@ const useUpload = (componentName, fileTypeName, props, emit, data) => {
|
|
|
72
74
|
};
|
|
73
75
|
const handleOnSuccess = (fileUrl, uploadFile, uploadFiles) => {
|
|
74
76
|
if (!fileUrl) return;
|
|
75
|
-
if (!props.multiple && uploadFiles.length > 1) uploadFiles.shift();
|
|
76
77
|
uploadFile.url = fileUrl;
|
|
77
|
-
|
|
78
|
+
if (!props.multiple && uploadFiles.length > 1) uploadFiles.splice(0, uploadFiles.length, uploadFile);
|
|
79
|
+
handleValue(uploadFiles);
|
|
78
80
|
if (formItemContext?.prop) formContext?.validateField([formItemContext.prop]);
|
|
79
81
|
ElMessage.success("上传成功");
|
|
80
82
|
props.onSuccess?.(fileUrl, uploadFile, uploadFiles);
|
|
@@ -110,25 +112,37 @@ const useUpload = (componentName, fileTypeName, props, emit, data) => {
|
|
|
110
112
|
}
|
|
111
113
|
return true;
|
|
112
114
|
};
|
|
115
|
+
const handleOnChange = (uploadFile, uploadFiles) => {
|
|
116
|
+
if (props.autoUpload === false && uploadFile.status === "ready" && !handleOnUpload(uploadFile)) {
|
|
117
|
+
fileList.value = uploadFiles.filter((item) => item.uid !== uploadFile.uid);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
props.onChange?.(uploadFile, uploadFiles);
|
|
121
|
+
};
|
|
113
122
|
/**
|
|
114
123
|
* 监听 v-model 绑定数据
|
|
115
124
|
*/
|
|
116
125
|
watch(() => props.modelValue, (newValue) => {
|
|
117
126
|
if (newValue) {
|
|
118
127
|
if (isArray(newValue)) fileList.value = newValue.map((m) => {
|
|
119
|
-
|
|
120
|
-
|
|
128
|
+
const find = fileList.value.find((f) => f.url === m);
|
|
129
|
+
const urlWithoutParams = m.split(/[?#]/u)[0] ?? "";
|
|
130
|
+
const fileName = urlWithoutParams.slice(urlWithoutParams.lastIndexOf("/") + 1);
|
|
131
|
+
return find ?? {
|
|
132
|
+
name: fileName,
|
|
121
133
|
status: "success",
|
|
122
|
-
uid:
|
|
134
|
+
uid: genFileId(),
|
|
123
135
|
url: m
|
|
124
136
|
};
|
|
125
137
|
});
|
|
126
138
|
else {
|
|
127
139
|
const find = fileList.value.find((f) => f.url === newValue);
|
|
128
|
-
|
|
129
|
-
|
|
140
|
+
const urlWithoutParams = newValue.split(/[?#]/u)[0] ?? "";
|
|
141
|
+
const fileName = urlWithoutParams.slice(urlWithoutParams.lastIndexOf("/") + 1);
|
|
142
|
+
fileList.value = [find ?? {
|
|
143
|
+
name: fileName,
|
|
130
144
|
status: "success",
|
|
131
|
-
uid:
|
|
145
|
+
uid: genFileId(),
|
|
132
146
|
url: newValue
|
|
133
147
|
}];
|
|
134
148
|
}
|
|
@@ -146,7 +160,8 @@ const useUpload = (componentName, fileTypeName, props, emit, data) => {
|
|
|
146
160
|
handleOnError,
|
|
147
161
|
handleOnRemove,
|
|
148
162
|
handleOnExceed,
|
|
149
|
-
handleOnUpload
|
|
163
|
+
handleOnUpload,
|
|
164
|
+
handleOnChange
|
|
150
165
|
};
|
|
151
166
|
};
|
|
152
167
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUpload.mjs","names":[],"sources":["../../../../src/components/upload/src/useUpload.ts"],"sourcesContent":["import { useVModel } from \"@vueuse/core\";\nimport { computed, inject, onMounted, ref, watch } from \"vue\";\nimport { ElMessage, ElNotification, formContextKey, formItemContextKey, genFileId, uploadProps } from \"element-plus\";\nimport { isArray, isNumber } from \"lodash-unified\";\nimport { Decimal } from \"decimal.js\";\nimport { uploadUtil } from \"../utils/upload\";\nimport type {\n\tFormContext,\n\tFormItemContext,\n\tUploadFile,\n\tUploadFiles,\n\tUploadProps,\n\tUploadRawFile,\n\tUploadRequestOptions,\n\tUploadUserFile,\n} from \"element-plus\";\nimport type { ComputedRef, Ref, WritableComputedRef } from \"vue\";\n\ninterface UploadComposable {\n\tfileList: WritableComputedRef<UploadUserFile[]>;\n\tloading: Ref<boolean>;\n\tformContext: FormContext | undefined;\n\tformItemContext: FormItemContext | undefined;\n\tmaxSizeMB: ComputedRef<Decimal>;\n\thandleValue: () => void;\n\thandleHttpRequest: (options: UploadRequestOptions) => Promise<void>;\n\thandleOnSuccess: (fileUrl: string, uploadFile: UploadFile, uploadFiles: UploadFiles) => void;\n\thandleOnError: (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => void;\n\thandleOnRemove: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void;\n\thandleOnExceed: (files: File[], uploadFiles: UploadUserFile[]) => void;\n\thandleOnUpload: (file: UploadFile | UploadRawFile) => boolean;\n}\n\n/**\n * 创建上传组件共享的文件状态和操作方法。\n *\n * @param componentName - 组件名称。\n * @param fileTypeName - 文件类型名称。\n * @param props - 上传组件的 Props。\n * @param emit - 上传组件的事件触发器。\n * @param options - 文件大小和类型校验配置。\n * @returns 文件列表、加载状态和上传操作方法。\n */\nexport const useUpload = <T extends string | string[]>(\n\tcomponentName: string,\n\tfileTypeName: string,\n\tprops: Partial<UploadProps> & {\n\t\tmodelValue?: T | null;\n\t},\n\temit: ((event: \"update:fileList\", value: UploadUserFile[]) => void) & ((event: \"update:modelValue\", value: T | null) => void),\n\tdata?: {\n\t\tmaxSize?: string | number;\n\t\tuploadApi?: (formData: FormData) => Promise<string>;\n\t\tuploadUrl?: string;\n\t}\n): UploadComposable => {\n\tconst fileListModel = useVModel(props, \"fileList\", emit, { passive: true });\n\tconst fileList = computed<UploadUserFile[]>({\n\t\tget: () => fileListModel.value ?? [],\n\t\tset: (value) => {\n\t\t\tfileListModel.value = value;\n\t\t},\n\t});\n\n\tconst loading = ref(false);\n\tlet activeUploadCount = 0;\n\n\t// 获取 el-form 组件上下文\n\tconst formContext = inject(formContextKey, undefined);\n\t// 获取 el-form-item 组件上下文\n\tconst formItemContext = inject(formItemContextKey, undefined);\n\n\tconst mbNum = new Decimal(1024);\n\tconst maxSizeKB = computed(() => new Decimal(isNumber(data?.maxSize) ? data.maxSize : Number(data?.maxSize)));\n\tconst maxSizeMB = computed(() => maxSizeKB.value.div(mbNum));\n\n\tonMounted(() => {\n\t\tif (!props.disabled && props.autoUpload && !data?.uploadApi && !data?.uploadUrl && props.httpRequest === uploadProps.httpRequest.default) {\n\t\t\tconsole.warn(`[Fast:${componentName}]`, \"uploadApi 和 uploadUrl 至少需要提供一个。\");\n\t\t}\n\t});\n\n\tconst handleValue = (files: UploadUserFile[] = fileList.value): void => {\n\t\tif (files.length > 0) {\n\t\t\tif (props.multiple === true) {\n\t\t\t\tconst value = files.flatMap((item) => (item.url ? [item.url] : []));\n\t\t\t\temit(\"update:modelValue\", value as T);\n\t\t\t} else {\n\t\t\t\tconst fileUrl = files[0]?.url;\n\t\t\t\tif (!fileUrl) return;\n\t\t\t\temit(\"update:modelValue\", fileUrl as T);\n\t\t\t}\n\t\t} else {\n\t\t\temit(\"update:modelValue\", props.multiple === true ? ([] as unknown as T) : null);\n\t\t}\n\t};\n\n\tconst handleHttpRequest = async (options: UploadRequestOptions): Promise<void> => {\n\t\tconst propsData = options.data;\n\t\tif (!data?.uploadApi && !data?.uploadUrl) {\n\t\t\tconst error = new Error(`上传${fileTypeName}接口 uploadApi 或地址 uploadUrl 不能为空。`);\n\t\t\tElMessage.error(`上传${fileTypeName}Api或地址不能为空`);\n\t\t\tconsole.error(`[Fast:${componentName}]`, error.message);\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t\tactiveUploadCount++;\n\t\tloading.value = true;\n\t\ttry {\n\t\t\tlet fileUrl: string;\n\t\t\tif (data?.uploadApi) {\n\t\t\t\tfileUrl = await uploadUtil.uploadFileByApi(data.uploadApi, options.file, options.filename, propsData);\n\t\t\t} else {\n\t\t\t\tconst headers =\n\t\t\t\t\toptions.headers instanceof Headers\n\t\t\t\t\t\t? options.headers\n\t\t\t\t\t\t: new Headers(\n\t\t\t\t\t\t\t\tObject.entries(options.headers).flatMap(([key, value]) =>\n\t\t\t\t\t\t\t\t\tvalue === null || value === undefined ? [] : [[key, String(value)] as [string, string]]\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t);\n\t\t\t\tfileUrl = await uploadUtil.uploadFile(data?.uploadUrl ?? options.action, options.file, options.filename, propsData, {\n\t\t\t\t\theaders,\n\t\t\t\t\tmethod: options.method,\n\t\t\t\t\twithCredentials: options.withCredentials,\n\t\t\t\t});\n\t\t\t}\n\t\t\toptions.onSuccess(fileUrl);\n\t\t} finally {\n\t\t\tactiveUploadCount = Math.max(activeUploadCount - 1, 0);\n\t\t\tloading.value = activeUploadCount > 0;\n\t\t}\n\t};\n\n\tconst handleOnSuccess = (fileUrl: string, uploadFile: UploadFile, uploadFiles: UploadFiles): void => {\n\t\tif (!fileUrl) return;\n\t\tif (!props.multiple && uploadFiles.length > 1) {\n\t\t\tuploadFiles.shift();\n\t\t}\n\t\tuploadFile.url = fileUrl;\n\t\thandleValue();\n\t\t// 调用 el-form 内部的校验方法(可自动校验)\n\t\tif (formItemContext?.prop) void formContext?.validateField([formItemContext.prop]);\n\t\tElMessage.success(\"上传成功\");\n\t\tprops.onSuccess?.(fileUrl, uploadFile, uploadFiles);\n\t};\n\n\tconst handleOnError = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles): void => {\n\t\tElNotification({\n\t\t\tmessage: `【${uploadFile.name}】${fileTypeName}上传失败,请您重新上传`,\n\t\t\ttype: \"error\",\n\t\t});\n\t\tprops.onError?.(error, uploadFile, uploadFiles);\n\t};\n\n\tconst handleOnRemove = (uploadFile: UploadFile, uploadFiles: UploadFiles): void => {\n\t\thandleValue(uploadFiles);\n\t\tprops.onRemove?.(uploadFile, uploadFiles);\n\t};\n\n\tconst handleOnExceed = (files: File[], uploadFiles: UploadUserFile[]): void => {\n\t\tElMessage.warning(`最多只能上传 ${props.limit} 个${fileTypeName},请移除后再进行上传`);\n\t\tprops.onExceed?.(files, uploadFiles);\n\t};\n\n\tconst handleOnUpload = (file: UploadFile | UploadRawFile): boolean => {\n\t\tconst fileSizeKB = new Decimal(file.size ?? 0).div(mbNum);\n\n\t\tif (fileSizeKB.greaterThan(maxSizeKB.value)) {\n\t\t\tconsole.warn(`[Fast:${componentName}]`, `【${file.name}】${fileTypeName}上传大小不能超过 ${maxSizeMB.value.toString()}MB。`);\n\t\t\tElMessage.warning(`【${file.name}】${fileTypeName}上传大小不能超过 ${maxSizeMB.value.toString()}MB`);\n\t\t\treturn false;\n\t\t}\n\n\t\tconst rawFile = \"type\" in file ? file : file.raw;\n\t\tif (!rawFile) return false;\n\t\tif (!uploadUtil.matchesAccept(rawFile, props.accept)) {\n\t\t\tconst uploadFileNames = uploadUtil.detectFileType(props.accept ?? \"\");\n\t\t\tconsole.warn(`[Fast:${componentName}]`, `只允许上传【${uploadFileNames}】格式的${fileTypeName}。`);\n\t\t\tElMessage.warning(`只允许上传【${uploadFileNames}】格式的${fileTypeName}`);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t};\n\n\t/**\n\t * 监听 v-model 绑定数据\n\t */\n\twatch(\n\t\t() => props.modelValue,\n\t\t(newValue) => {\n\t\t\tif (newValue) {\n\t\t\t\tif (isArray(newValue)) {\n\t\t\t\t\tfileList.value = newValue.map((m) => {\n\t\t\t\t\t\tconst find = fileList.value.find((f) => f.url === m);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: \"\",\n\t\t\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\t\t\tuid: find?.uid ?? genFileId(),\n\t\t\t\t\t\t\turl: m,\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst find = fileList.value.find((f) => f.url === newValue);\n\t\t\t\t\tfileList.value = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: \"\",\n\t\t\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\t\t\tuid: find?.uid ?? genFileId(),\n\t\t\t\t\t\t\turl: newValue,\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfileList.value = [];\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\timmediate: true,\n\t\t}\n\t);\n\n\treturn {\n\t\tfileList,\n\t\tloading,\n\t\tformContext,\n\t\tformItemContext,\n\t\tmaxSizeMB,\n\t\thandleValue,\n\t\thandleHttpRequest,\n\t\thandleOnSuccess,\n\t\thandleOnError,\n\t\thandleOnRemove,\n\t\thandleOnExceed,\n\t\thandleOnUpload,\n\t};\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useUpload.mjs","names":[],"sources":["../../../../src/components/upload/src/useUpload.ts"],"sourcesContent":["import { useVModel } from \"@vueuse/core\";\nimport { computed, inject, onMounted, ref, watch } from \"vue\";\nimport { ElMessage, ElNotification, formContextKey, formItemContextKey, genFileId, uploadProps } from \"element-plus\";\nimport { isArray, isNumber } from \"lodash-unified\";\nimport { Decimal } from \"decimal.js\";\nimport { uploadUtil } from \"../utils/upload\";\nimport type {\n\tFormContext,\n\tFormItemContext,\n\tUploadFile,\n\tUploadFiles,\n\tUploadProps,\n\tUploadRawFile,\n\tUploadRequestOptions,\n\tUploadUserFile,\n} from \"element-plus\";\nimport type { ComputedRef, Ref, WritableComputedRef } from \"vue\";\n\ninterface UploadComposable {\n\tfileList: WritableComputedRef<UploadUserFile[]>;\n\tloading: Ref<boolean>;\n\tformContext: FormContext | undefined;\n\tformItemContext: FormItemContext | undefined;\n\tmaxSizeMB: ComputedRef<Decimal>;\n\thandleValue: () => void;\n\thandleHttpRequest: (options: UploadRequestOptions) => Promise<void>;\n\thandleOnSuccess: (fileUrl: string, uploadFile: UploadFile, uploadFiles: UploadFiles) => void;\n\thandleOnError: (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => void;\n\thandleOnRemove: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void;\n\thandleOnExceed: (files: File[], uploadFiles: UploadUserFile[]) => void;\n\thandleOnUpload: (file: UploadFile | UploadRawFile) => boolean;\n\thandleOnChange: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void;\n}\n\n/**\n * 创建上传组件共享的文件状态和操作方法。\n *\n * @param componentName - 组件名称。\n * @param fileTypeName - 文件类型名称。\n * @param props - 上传组件的 Props。\n * @param emit - 上传组件的事件触发器。\n * @param options - 文件大小和类型校验配置。\n * @returns 文件列表、加载状态和上传操作方法。\n */\nexport const useUpload = <T extends string | string[]>(\n\tcomponentName: string,\n\tfileTypeName: string,\n\tprops: Partial<UploadProps> & {\n\t\tmodelValue?: T | null;\n\t},\n\temit: ((event: \"update:fileList\", value: UploadUserFile[]) => void) & ((event: \"update:modelValue\", value: T | null) => void),\n\tdata?: {\n\t\tmaxSize?: string | number;\n\t\tuploadApi?: (formData: FormData) => Promise<string>;\n\t\tuploadUrl?: string;\n\t}\n): UploadComposable => {\n\tconst fileListModel = useVModel(props, \"fileList\", emit, { passive: true });\n\tconst fileList = computed<UploadUserFile[]>({\n\t\tget: () => fileListModel.value ?? [],\n\t\tset: (value) => {\n\t\t\tfileListModel.value = value;\n\t\t},\n\t});\n\n\tconst loading = ref(false);\n\tlet activeUploadCount = 0;\n\n\t// 获取 el-form 组件上下文\n\tconst formContext = inject(formContextKey, undefined);\n\t// 获取 el-form-item 组件上下文\n\tconst formItemContext = inject(formItemContextKey, undefined);\n\n\tconst mbNum = new Decimal(1024);\n\tconst maxSizeKB = computed(() => new Decimal(isNumber(data?.maxSize) ? data.maxSize : Number(data?.maxSize)));\n\tconst maxSizeMB = computed(() => maxSizeKB.value.div(mbNum));\n\n\tonMounted(() => {\n\t\tif (!props.disabled && props.autoUpload && !data?.uploadApi && !data?.uploadUrl && props.httpRequest === uploadProps.httpRequest.default) {\n\t\t\tconsole.warn(`[Fast:${componentName}]`, \"uploadApi 和 uploadUrl 至少需要提供一个。\");\n\t\t}\n\t});\n\n\tconst handleValue = (files: UploadUserFile[] = fileList.value): void => {\n\t\tlet value: T | null;\n\t\tif (files.length > 0) {\n\t\t\tif (props.multiple === true) {\n\t\t\t\tvalue = files.flatMap((item) => (item.url ? [item.url] : [])) as T;\n\t\t\t} else {\n\t\t\t\tconst fileUrl = files[0]?.url;\n\t\t\t\tif (!fileUrl) return;\n\t\t\t\tvalue = fileUrl as T;\n\t\t\t}\n\t\t} else {\n\t\t\tvalue = props.multiple === true ? ([] as unknown as T) : null;\n\t\t}\n\t\temit(\"update:modelValue\", value);\n\t};\n\n\tconst handleHttpRequest = async (options: UploadRequestOptions): Promise<void> => {\n\t\tconst propsData = options.data;\n\t\tif (!data?.uploadApi && !data?.uploadUrl) {\n\t\t\tconst error = new Error(`上传${fileTypeName}接口 uploadApi 或地址 uploadUrl 不能为空。`);\n\t\t\tElMessage.error(`上传${fileTypeName}Api或地址不能为空`);\n\t\t\tconsole.error(`[Fast:${componentName}]`, error.message);\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t\tactiveUploadCount++;\n\t\tloading.value = true;\n\t\ttry {\n\t\t\tlet fileUrl: string;\n\t\t\tif (data?.uploadApi) {\n\t\t\t\tfileUrl = await uploadUtil.uploadFileByApi(data.uploadApi, options.file, options.filename, propsData);\n\t\t\t} else {\n\t\t\t\tconst headers =\n\t\t\t\t\toptions.headers instanceof Headers\n\t\t\t\t\t\t? options.headers\n\t\t\t\t\t\t: new Headers(\n\t\t\t\t\t\t\t\tObject.entries(options.headers).flatMap(([key, value]) =>\n\t\t\t\t\t\t\t\t\tvalue === null || value === undefined ? [] : [[key, String(value)] as [string, string]]\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t);\n\t\t\t\tfileUrl = await uploadUtil.uploadFile(data?.uploadUrl ?? options.action, options.file, options.filename, propsData, {\n\t\t\t\t\theaders,\n\t\t\t\t\tmethod: options.method,\n\t\t\t\t\twithCredentials: options.withCredentials,\n\t\t\t\t});\n\t\t\t}\n\t\t\toptions.onSuccess(fileUrl);\n\t\t} finally {\n\t\t\tactiveUploadCount = Math.max(activeUploadCount - 1, 0);\n\t\t\tloading.value = activeUploadCount > 0;\n\t\t}\n\t};\n\n\tconst handleOnSuccess = (fileUrl: string, uploadFile: UploadFile, uploadFiles: UploadFiles): void => {\n\t\tif (!fileUrl) return;\n\t\tuploadFile.url = fileUrl;\n\t\tif (!props.multiple && uploadFiles.length > 1) {\n\t\t\tuploadFiles.splice(0, uploadFiles.length, uploadFile);\n\t\t}\n\t\thandleValue(uploadFiles);\n\t\t// 调用 el-form 内部的校验方法(可自动校验)\n\t\tif (formItemContext?.prop) void formContext?.validateField([formItemContext.prop]);\n\t\tElMessage.success(\"上传成功\");\n\t\tprops.onSuccess?.(fileUrl, uploadFile, uploadFiles);\n\t};\n\n\tconst handleOnError = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles): void => {\n\t\tElNotification({\n\t\t\tmessage: `【${uploadFile.name}】${fileTypeName}上传失败,请您重新上传`,\n\t\t\ttype: \"error\",\n\t\t});\n\t\tprops.onError?.(error, uploadFile, uploadFiles);\n\t};\n\n\tconst handleOnRemove = (uploadFile: UploadFile, uploadFiles: UploadFiles): void => {\n\t\thandleValue(uploadFiles);\n\t\tprops.onRemove?.(uploadFile, uploadFiles);\n\t};\n\n\tconst handleOnExceed = (files: File[], uploadFiles: UploadUserFile[]): void => {\n\t\tElMessage.warning(`最多只能上传 ${props.limit} 个${fileTypeName},请移除后再进行上传`);\n\t\tprops.onExceed?.(files, uploadFiles);\n\t};\n\n\tconst handleOnUpload = (file: UploadFile | UploadRawFile): boolean => {\n\t\tconst fileSizeKB = new Decimal(file.size ?? 0).div(mbNum);\n\n\t\tif (fileSizeKB.greaterThan(maxSizeKB.value)) {\n\t\t\tconsole.warn(`[Fast:${componentName}]`, `【${file.name}】${fileTypeName}上传大小不能超过 ${maxSizeMB.value.toString()}MB。`);\n\t\t\tElMessage.warning(`【${file.name}】${fileTypeName}上传大小不能超过 ${maxSizeMB.value.toString()}MB`);\n\t\t\treturn false;\n\t\t}\n\n\t\tconst rawFile = \"type\" in file ? file : file.raw;\n\t\tif (!rawFile) return false;\n\t\tif (!uploadUtil.matchesAccept(rawFile, props.accept)) {\n\t\t\tconst uploadFileNames = uploadUtil.detectFileType(props.accept ?? \"\");\n\t\t\tconsole.warn(`[Fast:${componentName}]`, `只允许上传【${uploadFileNames}】格式的${fileTypeName}。`);\n\t\t\tElMessage.warning(`只允许上传【${uploadFileNames}】格式的${fileTypeName}`);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tconst handleOnChange = (uploadFile: UploadFile, uploadFiles: UploadFiles): void => {\n\t\tif (props.autoUpload === false && uploadFile.status === \"ready\" && !handleOnUpload(uploadFile)) {\n\t\t\tfileList.value = uploadFiles.filter((item) => item.uid !== uploadFile.uid);\n\t\t\treturn;\n\t\t}\n\t\tprops.onChange?.(uploadFile, uploadFiles);\n\t};\n\n\t/**\n\t * 监听 v-model 绑定数据\n\t */\n\twatch(\n\t\t() => props.modelValue,\n\t\t(newValue) => {\n\t\t\tif (newValue) {\n\t\t\t\tif (isArray(newValue)) {\n\t\t\t\t\tfileList.value = newValue.map((m) => {\n\t\t\t\t\t\tconst find = fileList.value.find((f) => f.url === m);\n\t\t\t\t\t\tconst urlWithoutParams = m.split(/[?#]/u)[0] ?? \"\";\n\t\t\t\t\t\tconst fileName = urlWithoutParams.slice(urlWithoutParams.lastIndexOf(\"/\") + 1);\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\tfind ?? {\n\t\t\t\t\t\t\t\tname: fileName,\n\t\t\t\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\t\t\t\tuid: genFileId(),\n\t\t\t\t\t\t\t\turl: m,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst find = fileList.value.find((f) => f.url === newValue);\n\t\t\t\t\tconst urlWithoutParams = newValue.split(/[?#]/u)[0] ?? \"\";\n\t\t\t\t\tconst fileName = urlWithoutParams.slice(urlWithoutParams.lastIndexOf(\"/\") + 1);\n\t\t\t\t\tfileList.value = [\n\t\t\t\t\t\tfind ?? {\n\t\t\t\t\t\t\tname: fileName,\n\t\t\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\t\t\tuid: genFileId(),\n\t\t\t\t\t\t\turl: newValue,\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfileList.value = [];\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\timmediate: true,\n\t\t}\n\t);\n\n\treturn {\n\t\tfileList,\n\t\tloading,\n\t\tformContext,\n\t\tformItemContext,\n\t\tmaxSizeMB,\n\t\thandleValue,\n\t\thandleHttpRequest,\n\t\thandleOnSuccess,\n\t\thandleOnError,\n\t\thandleOnRemove,\n\t\thandleOnExceed,\n\t\thandleOnUpload,\n\t\thandleOnChange,\n\t};\n};\n"],"mappings":"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"}
|
|
@@ -16,13 +16,18 @@ export declare const faUploadImageProps: {
|
|
|
16
16
|
type: import("vue").PropType<"picture" | "text" | "picture-card">;
|
|
17
17
|
default: string;
|
|
18
18
|
};
|
|
19
|
+
/** @description whether uploading multiple files is permitted */
|
|
20
|
+
multiple: {
|
|
21
|
+
type: BooleanConstructor;
|
|
22
|
+
default: boolean;
|
|
23
|
+
};
|
|
19
24
|
/** @description whether to show the uploaded file list */
|
|
20
25
|
showFileList: {
|
|
21
26
|
type: BooleanConstructor;
|
|
22
27
|
default: boolean;
|
|
23
28
|
};
|
|
24
29
|
/** @description v-model绑定值 */
|
|
25
|
-
modelValue: import("vue").PropType<string |
|
|
30
|
+
modelValue: import("vue").PropType<string | null>;
|
|
26
31
|
/** @description 大小限制,单位kb */
|
|
27
32
|
maxSize: {
|
|
28
33
|
type: (NumberConstructor | StringConstructor)[];
|
|
@@ -137,7 +142,6 @@ export declare const faUploadImageProps: {
|
|
|
137
142
|
};
|
|
138
143
|
method: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<StringConstructor, unknown, unknown, "post", boolean>;
|
|
139
144
|
data: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<(new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (((new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>))) | null)[], unknown, unknown, () => import("element-plus/es/utils/typescript.mjs").Mutable<{}>, boolean>;
|
|
140
|
-
multiple: BooleanConstructor;
|
|
141
145
|
name: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<StringConstructor, unknown, unknown, "file", boolean>;
|
|
142
146
|
withCredentials: BooleanConstructor;
|
|
143
147
|
fileList: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<(new (...args: any[]) => UploadUserFile[]) | (() => UploadUserFile[]) | (((new (...args: any[]) => UploadUserFile[]) | (() => UploadUserFile[])) | null)[], unknown, unknown, () => [], boolean>;
|
|
@@ -158,7 +162,7 @@ export declare const faUploadImageProps: {
|
|
|
158
162
|
/** FaUploadImage 的运行时 Emits 定义。 */
|
|
159
163
|
export declare const faUploadImageEmits: {
|
|
160
164
|
/** @description v-model 回调 */
|
|
161
|
-
"update:modelValue": (value: string |
|
|
165
|
+
"update:modelValue": (value: string | null) => boolean;
|
|
162
166
|
/** @description v-model:fileList 回调 */
|
|
163
167
|
"update:fileList": (value: UploadUserFile[]) => boolean;
|
|
164
168
|
};
|
|
@@ -183,13 +187,18 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
183
187
|
type: import("vue").PropType<"picture" | "text" | "picture-card">;
|
|
184
188
|
default: string;
|
|
185
189
|
};
|
|
190
|
+
/** @description whether uploading multiple files is permitted */
|
|
191
|
+
multiple: {
|
|
192
|
+
type: BooleanConstructor;
|
|
193
|
+
default: boolean;
|
|
194
|
+
};
|
|
186
195
|
/** @description whether to show the uploaded file list */
|
|
187
196
|
showFileList: {
|
|
188
197
|
type: BooleanConstructor;
|
|
189
198
|
default: boolean;
|
|
190
199
|
};
|
|
191
200
|
/** @description v-model绑定值 */
|
|
192
|
-
modelValue: import("vue").PropType<string |
|
|
201
|
+
modelValue: import("vue").PropType<string | null>;
|
|
193
202
|
/** @description 大小限制,单位kb */
|
|
194
203
|
maxSize: {
|
|
195
204
|
type: (NumberConstructor | StringConstructor)[];
|
|
@@ -304,7 +313,6 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
304
313
|
};
|
|
305
314
|
method: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<StringConstructor, unknown, unknown, "post", boolean>;
|
|
306
315
|
data: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<(new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (((new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>))) | null)[], unknown, unknown, () => import("element-plus/es/utils/typescript.mjs").Mutable<{}>, boolean>;
|
|
307
|
-
multiple: BooleanConstructor;
|
|
308
316
|
name: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<StringConstructor, unknown, unknown, "file", boolean>;
|
|
309
317
|
withCredentials: BooleanConstructor;
|
|
310
318
|
fileList: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<(new (...args: any[]) => UploadUserFile[]) | (() => UploadUserFile[]) | (((new (...args: any[]) => UploadUserFile[]) | (() => UploadUserFile[])) | null)[], unknown, unknown, () => [], boolean>;
|
|
@@ -342,7 +350,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
342
350
|
previewList: import("vue").ComputedRef<string[]>;
|
|
343
351
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
344
352
|
/** @description v-model 回调 */
|
|
345
|
-
"update:modelValue": (value: string |
|
|
353
|
+
"update:modelValue": (value: string | null) => boolean;
|
|
346
354
|
/** @description v-model:fileList 回调 */
|
|
347
355
|
"update:fileList": (value: UploadUserFile[]) => boolean;
|
|
348
356
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
@@ -361,13 +369,18 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
361
369
|
type: import("vue").PropType<"picture" | "text" | "picture-card">;
|
|
362
370
|
default: string;
|
|
363
371
|
};
|
|
372
|
+
/** @description whether uploading multiple files is permitted */
|
|
373
|
+
multiple: {
|
|
374
|
+
type: BooleanConstructor;
|
|
375
|
+
default: boolean;
|
|
376
|
+
};
|
|
364
377
|
/** @description whether to show the uploaded file list */
|
|
365
378
|
showFileList: {
|
|
366
379
|
type: BooleanConstructor;
|
|
367
380
|
default: boolean;
|
|
368
381
|
};
|
|
369
382
|
/** @description v-model绑定值 */
|
|
370
|
-
modelValue: import("vue").PropType<string |
|
|
383
|
+
modelValue: import("vue").PropType<string | null>;
|
|
371
384
|
/** @description 大小限制,单位kb */
|
|
372
385
|
maxSize: {
|
|
373
386
|
type: (NumberConstructor | StringConstructor)[];
|
|
@@ -482,7 +495,6 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
482
495
|
};
|
|
483
496
|
method: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<StringConstructor, unknown, unknown, "post", boolean>;
|
|
484
497
|
data: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<(new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (((new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>))) | null)[], unknown, unknown, () => import("element-plus/es/utils/typescript.mjs").Mutable<{}>, boolean>;
|
|
485
|
-
multiple: BooleanConstructor;
|
|
486
498
|
name: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<StringConstructor, unknown, unknown, "file", boolean>;
|
|
487
499
|
withCredentials: BooleanConstructor;
|
|
488
500
|
fileList: import("element-plus/es/utils/vue/props/types.mjs").EpPropFinalized<(new (...args: any[]) => UploadUserFile[]) | (() => UploadUserFile[]) | (((new (...args: any[]) => UploadUserFile[]) | (() => UploadUserFile[])) | null)[], unknown, unknown, () => [], boolean>;
|
|
@@ -500,7 +512,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
500
512
|
limit: NumberConstructor;
|
|
501
513
|
directory: BooleanConstructor;
|
|
502
514
|
}>> & Readonly<{
|
|
503
|
-
"onUpdate:modelValue"?: ((value: string |
|
|
515
|
+
"onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
|
|
504
516
|
"onUpdate:fileList"?: ((value: UploadUserFile[]) => any) | undefined;
|
|
505
517
|
}>, {
|
|
506
518
|
data: import("element-plus/es/utils/vue/props/types.mjs").EpPropMergeType<(new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | ((new (...args: any[]) => import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>> | Promise<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | (() => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus/es/utils/typescript.mjs").Mutable<Record<string, any>>> | ((rawFile: import("element-plus").UploadRawFile) => import("element-plus/es/utils/typescript.mjs").Awaitable<import("element-plus").UploadData>)) | null)[], unknown, unknown>;
|
|
@@ -30,13 +30,18 @@ const faUploadImageProps = {
|
|
|
30
30
|
type: definePropType(String),
|
|
31
31
|
default: "picture"
|
|
32
32
|
},
|
|
33
|
+
/** @description whether uploading multiple files is permitted */
|
|
34
|
+
multiple: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: false
|
|
37
|
+
},
|
|
33
38
|
/** @description whether to show the uploaded file list */
|
|
34
39
|
showFileList: {
|
|
35
40
|
type: Boolean,
|
|
36
41
|
default: false
|
|
37
42
|
},
|
|
38
43
|
/** @description v-model绑定值 */
|
|
39
|
-
modelValue: definePropType(
|
|
44
|
+
modelValue: definePropType(String),
|
|
40
45
|
/** @description 大小限制,单位kb */
|
|
41
46
|
maxSize: {
|
|
42
47
|
type: [String, Number],
|
|
@@ -60,7 +65,7 @@ const faUploadImageProps = {
|
|
|
60
65
|
/** FaUploadImage 的运行时 Emits 定义。 */
|
|
61
66
|
const faUploadImageEmits = {
|
|
62
67
|
/** @description v-model 回调 */
|
|
63
|
-
"update:modelValue": (value) => isString(value) ||
|
|
68
|
+
"update:modelValue": (value) => isString(value) || isNull(value),
|
|
64
69
|
/** @description v-model:fileList 回调 */
|
|
65
70
|
"update:fileList": (value) => isArray(value)
|
|
66
71
|
};
|
|
@@ -70,7 +75,7 @@ var uploadImage_default = defineComponent({
|
|
|
70
75
|
emits: faUploadImageEmits,
|
|
71
76
|
slots: makeSlots(),
|
|
72
77
|
setup(props, { slots, emit, expose }) {
|
|
73
|
-
const { fileList, loading, formContext, maxSizeMB, handleHttpRequest, handleOnSuccess, handleOnError, handleOnRemove, handleOnExceed, handleOnUpload } = useUpload("FaUploadImage", "图片", props, emit, {
|
|
78
|
+
const { fileList, loading, formContext, maxSizeMB, handleHttpRequest, handleOnSuccess, handleOnError, handleOnRemove, handleOnExceed, handleOnUpload, handleOnChange } = useUpload("FaUploadImage", "图片", props, emit, {
|
|
74
79
|
get maxSize() {
|
|
75
80
|
return props.maxSize;
|
|
76
81
|
},
|
|
@@ -117,7 +122,8 @@ var uploadImage_default = defineComponent({
|
|
|
117
122
|
"onExceed",
|
|
118
123
|
"onSuccess",
|
|
119
124
|
"onError",
|
|
120
|
-
"onRemove"
|
|
125
|
+
"onRemove",
|
|
126
|
+
"onChange"
|
|
121
127
|
]);
|
|
122
128
|
useRender(() => createVNode(Fragment, null, [withDirectives(createVNode(ElUpload, mergeProps(elUploadProps.value, {
|
|
123
129
|
"ref": uploadRef,
|
|
@@ -128,13 +134,15 @@ var uploadImage_default = defineComponent({
|
|
|
128
134
|
},
|
|
129
135
|
"fileList": fileList.value,
|
|
130
136
|
"onUpdate:fileList": ($event) => fileList.value = $event,
|
|
137
|
+
"multiple": false,
|
|
131
138
|
"disabled": disabled.value,
|
|
132
139
|
"httpRequest": httpRequest.value,
|
|
133
140
|
"beforeUpload": handleBeforeUpload,
|
|
134
141
|
"onExceed": handleOnExceed,
|
|
135
142
|
"onSuccess": handleOnSuccess,
|
|
136
143
|
"onError": handleOnError,
|
|
137
|
-
"onRemove": handleOnRemove
|
|
144
|
+
"onRemove": handleOnRemove,
|
|
145
|
+
"onChange": handleOnChange
|
|
138
146
|
}), {
|
|
139
147
|
default: () => fileList.value.length > 0 ? createVNode(Fragment, null, [createVNode("img", {
|
|
140
148
|
"class": "el-upload-list__item-thumbnail",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadImage.mjs","names":["update:modelValue","update:fileList"],"sources":["../../../../src/components/uploadImage/src/uploadImage.tsx"],"sourcesContent":["import { Fragment, computed, defineComponent, reactive, ref, withModifiers } from \"vue\";\nimport { Delete, Edit, UploadFilled, ZoomIn } from \"@element-plus/icons-vue\";\nimport { ElIcon, ElImageViewer, ElUpload, uploadProps } from \"element-plus\";\nimport { isArray, isNull, isString } from \"lodash-unified\";\nimport { FaMimeType } from \"../../../constants\";\nimport { addCssUnit, definePropType, makeSlots, randomString, useExpose, useProps, useRender, withDefineType } from \"../../../utils\";\nimport { useUpload } from \"../../upload/src/useUpload\";\nimport type { UploadFile, UploadInstance, UploadProps, UploadUserFile, uploadListTypes } from \"element-plus\";\n\n/** FaUploadImage 的运行时 Props 定义。 */\nexport const faUploadImageProps = {\n\t...uploadProps,\n\t/** @description whether to activate drag and drop mode */\n\tdrag: {\n\t\ttype: Boolean,\n\t\tdefault: true,\n\t},\n\t/** @description accepted [file types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept), will not work when `thumbnail-mode === true` */\n\taccept: {\n\t\ttype: String,\n\t\tdefault: (): string => FaMimeType.Image,\n\t},\n\t/** @description type of file list */\n\tlistType: {\n\t\ttype: definePropType<(typeof uploadListTypes)[number]>(String),\n\t\tdefault: \"picture\",\n\t},\n\t/** @description whether to show the uploaded file list */\n\tshowFileList: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\t/** @description v-model绑定值 */\n\tmodelValue: definePropType<string | string[] | null>([String, Array]),\n\t/** @description 大小限制,单位kb */\n\tmaxSize: {\n\t\ttype: [String, Number],\n\t\tdefault: 2048,\n\t},\n\t/** @description 图片上传接口,优先级最高 */\n\tuploadApi: {\n\t\ttype: definePropType<(formData: FormData) => Promise<string>>(Function),\n\t},\n\t/** @description 图片上传地址 */\n\tuploadUrl: String,\n\t/** @description 宽度 */\n\twidth: {\n\t\ttype: [String, Number],\n\t\tdefault: 150,\n\t},\n\t/** @description 高度 */\n\theight: {\n\t\ttype: [String, Number],\n\t\tdefault: 150,\n\t},\n};\n\n/** FaUploadImage 的运行时 Emits 定义。 */\nexport const faUploadImageEmits = {\n\t/** @description v-model 回调 */\n\t\"update:modelValue\": (value: string | string[] | null): boolean => isString(value) || isArray(value) || isNull(value),\n\t/** @description v-model:fileList 回调 */\n\t\"update:fileList\": (value: UploadUserFile[]): boolean => isArray(value),\n};\n\n/** FaUploadImage 的插槽参数。 */\nexport interface FaUploadImageSlots extends Record<string, unknown> {\n\t/** @description 默认内容插槽 */\n\tdefault: never;\n}\n\nexport default defineComponent({\n\tname: \"FaUploadImage\",\n\tprops: faUploadImageProps,\n\temits: faUploadImageEmits,\n\tslots: makeSlots<FaUploadImageSlots>(),\n\tsetup(props, { slots, emit, expose }) {\n\t\tconst {\n\t\t\tfileList,\n\t\t\tloading,\n\t\t\tformContext,\n\t\t\tmaxSizeMB,\n\t\t\thandleHttpRequest,\n\t\t\thandleOnSuccess,\n\t\t\thandleOnError,\n\t\t\thandleOnRemove,\n\t\t\thandleOnExceed,\n\t\t\thandleOnUpload,\n\t\t} = useUpload<string | string[]>(\"FaUploadImage\", \"图片\", props, emit, {\n\t\t\tget maxSize() {\n\t\t\t\treturn props.maxSize;\n\t\t\t},\n\t\t\tget uploadApi() {\n\t\t\t\treturn props.uploadApi;\n\t\t\t},\n\t\t\tget uploadUrl() {\n\t\t\t\treturn props.uploadUrl || (props.action === uploadProps.action.default ? undefined : props.action);\n\t\t\t},\n\t\t});\n\n\t\tconst disabled = computed(() => {\n\t\t\treturn props.disabled === true || formContext?.disabled === true;\n\t\t});\n\n\t\tconst state = reactive({\n\t\t\tuploadKey: `fa-upload-image__${randomString(8)}`,\n\t\t\tpreview: false,\n\t\t\tpreviewList: withDefineType<string[]>([]),\n\t\t});\n\n\t\tconst uploadRef = ref<UploadInstance>();\n\t\tconst httpRequest = computed(() => (props.httpRequest === uploadProps.httpRequest.default ? handleHttpRequest : props.httpRequest));\n\n\t\tconst handleEdit = (): void => {\n\t\t\tconst uploadInputEl = document.querySelector(`.${state.uploadKey} .el-upload__input`);\n\t\t\tuploadInputEl?.dispatchEvent(new MouseEvent(\"click\"));\n\t\t};\n\n\t\tconst handlePreview = (): void => {\n\t\t\tconst fileUrl = fileList.value[0]?.url;\n\t\t\tif (!fileUrl) return;\n\t\t\tstate.previewList = [fileUrl];\n\t\t\tstate.preview = true;\n\t\t};\n\n\t\tconst handleRemove = (): void => {\n\t\t\tconst file = fileList.value[0];\n\t\t\tif (file) uploadRef.value?.handleRemove(file as UploadFile);\n\t\t};\n\n\t\tconst handleBeforeUpload: UploadProps[\"beforeUpload\"] = (rawFile) => {\n\t\t\tif (!handleOnUpload(rawFile)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (props.beforeUpload) {\n\t\t\t\treturn props.beforeUpload(rawFile);\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tconst elUploadProps = useProps(props, uploadProps, [\n\t\t\t\"fileList\",\n\t\t\t\"disabled\",\n\t\t\t\"httpRequest\",\n\t\t\t\"beforeUpload\",\n\t\t\t\"onExceed\",\n\t\t\t\"onSuccess\",\n\t\t\t\"onError\",\n\t\t\t\"onRemove\",\n\t\t]);\n\n\t\tuseRender(() => (\n\t\t\t<Fragment>\n\t\t\t\t<ElUpload\n\t\t\t\t\t{...elUploadProps.value}\n\t\t\t\t\tref={uploadRef}\n\t\t\t\t\tclass={[\"fa-upload-image\", state.uploadKey]}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\"--width\": addCssUnit(props.width),\n\t\t\t\t\t\t\"--height\": addCssUnit(props.height),\n\t\t\t\t\t}}\n\t\t\t\t\tvLoading={loading.value}\n\t\t\t\t\tvModel:fileList={fileList.value}\n\t\t\t\t\tdisabled={disabled.value}\n\t\t\t\t\thttpRequest={httpRequest.value}\n\t\t\t\t\tbeforeUpload={handleBeforeUpload}\n\t\t\t\t\tonExceed={handleOnExceed}\n\t\t\t\t\tonSuccess={handleOnSuccess}\n\t\t\t\t\tonError={handleOnError}\n\t\t\t\t\tonRemove={handleOnRemove}\n\t\t\t\t>\n\t\t\t\t\t{{\n\t\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\t\tfileList.value.length > 0 ? (\n\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t<img class=\"el-upload-list__item-thumbnail\" src={fileList.value[0]?.url} />\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"el-upload-list__item-actions\"\n\t\t\t\t\t\t\t\t\t\tonClick={withModifiers(() => {\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}, [\"stop\"])}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={() => handlePreview()} title=\"查看\">\n\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t<ZoomIn />\n\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t{!disabled.value && (\n\t\t\t\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={handleEdit} title=\"编辑\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Edit />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={() => handleRemove()} title=\"删除\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Delete />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t) : slots.default ? (\n\t\t\t\t\t\t\t\tslots.default()\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t<ElIcon class=\"el-icon--upload\">\n\t\t\t\t\t\t\t\t\t\t<UploadFilled />\n\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t<div class=\"el-upload__text\">\n\t\t\t\t\t\t\t\t\t\tDrop file here <br />\n\t\t\t\t\t\t\t\t\t\t<em>click to upload</em>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\ttip: () => <div class=\"el-upload__tip\">file with a size less than {maxSizeMB.value.toString()}MB</div>,\n\t\t\t\t\t}}\n\t\t\t\t</ElUpload>\n\t\t\t\t{state.preview && (\n\t\t\t\t\t<ElImageViewer\n\t\t\t\t\t\tcloseOnPressEscape\n\t\t\t\t\t\thideOnClickModal\n\t\t\t\t\t\tteleported\n\t\t\t\t\t\tonClose={() => (state.preview = false)}\n\t\t\t\t\t\turlList={state.previewList}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Fragment>\n\t\t));\n\n\t\treturn useExpose(expose, {\n\t\t\t/** @description 取消上传请求 */\n\t\t\tabort: computed(() => uploadRef.value?.abort),\n\t\t\t/** @description 手动上传文件列表 */\n\t\t\tsubmit: computed(() => uploadRef.value?.submit),\n\t\t\t/** @description 清空已上传的文件列表(该方法不支持在 before-upload 中调用) */\n\t\t\tclearFiles: computed(() => uploadRef.value?.clearFiles),\n\t\t\t/** @description 手动选择文件 */\n\t\t\thandleStart: computed(() => uploadRef.value?.handleStart),\n\t\t\t/** @description 手动移除文件。file 和 rawFile 已被合并。 */\n\t\t\thandleRemove: computed(() => uploadRef.value?.handleRemove),\n\t\t\t/** @description 加载状态 */\n\t\t\tloading,\n\t\t\t/** @description 文件集合 */\n\t\t\tfileList,\n\t\t\t/** @description 预览 */\n\t\t\tpreview: computed(() => state.preview),\n\t\t\t/** @description 预览集合 */\n\t\t\tpreviewList: computed(() => state.previewList),\n\t\t});\n\t},\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uploadImage.mjs","names":["update:modelValue","update:fileList"],"sources":["../../../../src/components/uploadImage/src/uploadImage.tsx"],"sourcesContent":["import { Fragment, computed, defineComponent, reactive, ref, withModifiers } from \"vue\";\nimport { Delete, Edit, UploadFilled, ZoomIn } from \"@element-plus/icons-vue\";\nimport { ElIcon, ElImageViewer, ElUpload, uploadProps } from \"element-plus\";\nimport { isArray, isNull, isString } from \"lodash-unified\";\nimport { FaMimeType } from \"../../../constants\";\nimport { addCssUnit, definePropType, makeSlots, randomString, useExpose, useProps, useRender, withDefineType } from \"../../../utils\";\nimport { useUpload } from \"../../upload/src/useUpload\";\nimport type { UploadFile, UploadInstance, UploadProps, UploadUserFile, uploadListTypes } from \"element-plus\";\n\n/** FaUploadImage 的运行时 Props 定义。 */\nexport const faUploadImageProps = {\n\t...uploadProps,\n\t/** @description whether to activate drag and drop mode */\n\tdrag: {\n\t\ttype: Boolean,\n\t\tdefault: true,\n\t},\n\t/** @description accepted [file types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept), will not work when `thumbnail-mode === true` */\n\taccept: {\n\t\ttype: String,\n\t\tdefault: (): string => FaMimeType.Image,\n\t},\n\t/** @description type of file list */\n\tlistType: {\n\t\ttype: definePropType<(typeof uploadListTypes)[number]>(String),\n\t\tdefault: \"picture\",\n\t},\n\t/** @description whether uploading multiple files is permitted */\n\tmultiple: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\t/** @description whether to show the uploaded file list */\n\tshowFileList: {\n\t\ttype: Boolean,\n\t\tdefault: false,\n\t},\n\t/** @description v-model绑定值 */\n\tmodelValue: definePropType<string | null>(String),\n\t/** @description 大小限制,单位kb */\n\tmaxSize: {\n\t\ttype: [String, Number],\n\t\tdefault: 2048,\n\t},\n\t/** @description 图片上传接口,优先级最高 */\n\tuploadApi: {\n\t\ttype: definePropType<(formData: FormData) => Promise<string>>(Function),\n\t},\n\t/** @description 图片上传地址 */\n\tuploadUrl: String,\n\t/** @description 宽度 */\n\twidth: {\n\t\ttype: [String, Number],\n\t\tdefault: 150,\n\t},\n\t/** @description 高度 */\n\theight: {\n\t\ttype: [String, Number],\n\t\tdefault: 150,\n\t},\n};\n\n/** FaUploadImage 的运行时 Emits 定义。 */\nexport const faUploadImageEmits = {\n\t/** @description v-model 回调 */\n\t\"update:modelValue\": (value: string | null): boolean => isString(value) || isNull(value),\n\t/** @description v-model:fileList 回调 */\n\t\"update:fileList\": (value: UploadUserFile[]): boolean => isArray(value),\n};\n\n/** FaUploadImage 的插槽参数。 */\nexport interface FaUploadImageSlots extends Record<string, unknown> {\n\t/** @description 默认内容插槽 */\n\tdefault: never;\n}\n\nexport default defineComponent({\n\tname: \"FaUploadImage\",\n\tprops: faUploadImageProps,\n\temits: faUploadImageEmits,\n\tslots: makeSlots<FaUploadImageSlots>(),\n\tsetup(props, { slots, emit, expose }) {\n\t\tconst {\n\t\t\tfileList,\n\t\t\tloading,\n\t\t\tformContext,\n\t\t\tmaxSizeMB,\n\t\t\thandleHttpRequest,\n\t\t\thandleOnSuccess,\n\t\t\thandleOnError,\n\t\t\thandleOnRemove,\n\t\t\thandleOnExceed,\n\t\t\thandleOnUpload,\n\t\t\thandleOnChange,\n\t\t} = useUpload<string>(\"FaUploadImage\", \"图片\", props, emit, {\n\t\t\tget maxSize() {\n\t\t\t\treturn props.maxSize;\n\t\t\t},\n\t\t\tget uploadApi() {\n\t\t\t\treturn props.uploadApi;\n\t\t\t},\n\t\t\tget uploadUrl() {\n\t\t\t\treturn props.uploadUrl || (props.action === uploadProps.action.default ? undefined : props.action);\n\t\t\t},\n\t\t});\n\n\t\tconst disabled = computed(() => {\n\t\t\treturn props.disabled === true || formContext?.disabled === true;\n\t\t});\n\n\t\tconst state = reactive({\n\t\t\tuploadKey: `fa-upload-image__${randomString(8)}`,\n\t\t\tpreview: false,\n\t\t\tpreviewList: withDefineType<string[]>([]),\n\t\t});\n\n\t\tconst uploadRef = ref<UploadInstance>();\n\t\tconst httpRequest = computed(() => (props.httpRequest === uploadProps.httpRequest.default ? handleHttpRequest : props.httpRequest));\n\n\t\tconst handleEdit = (): void => {\n\t\t\tconst uploadInputEl = document.querySelector(`.${state.uploadKey} .el-upload__input`);\n\t\t\tuploadInputEl?.dispatchEvent(new MouseEvent(\"click\"));\n\t\t};\n\n\t\tconst handlePreview = (): void => {\n\t\t\tconst fileUrl = fileList.value[0]?.url;\n\t\t\tif (!fileUrl) return;\n\t\t\tstate.previewList = [fileUrl];\n\t\t\tstate.preview = true;\n\t\t};\n\n\t\tconst handleRemove = (): void => {\n\t\t\tconst file = fileList.value[0];\n\t\t\tif (file) uploadRef.value?.handleRemove(file as UploadFile);\n\t\t};\n\n\t\tconst handleBeforeUpload: UploadProps[\"beforeUpload\"] = (rawFile) => {\n\t\t\tif (!handleOnUpload(rawFile)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (props.beforeUpload) {\n\t\t\t\treturn props.beforeUpload(rawFile);\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tconst elUploadProps = useProps(props, uploadProps, [\n\t\t\t\"fileList\",\n\t\t\t\"disabled\",\n\t\t\t\"httpRequest\",\n\t\t\t\"beforeUpload\",\n\t\t\t\"onExceed\",\n\t\t\t\"onSuccess\",\n\t\t\t\"onError\",\n\t\t\t\"onRemove\",\n\t\t\t\"onChange\",\n\t\t]);\n\n\t\tuseRender(() => (\n\t\t\t<Fragment>\n\t\t\t\t<ElUpload\n\t\t\t\t\t{...elUploadProps.value}\n\t\t\t\t\tref={uploadRef}\n\t\t\t\t\tclass={[\"fa-upload-image\", state.uploadKey]}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\"--width\": addCssUnit(props.width),\n\t\t\t\t\t\t\"--height\": addCssUnit(props.height),\n\t\t\t\t\t}}\n\t\t\t\t\tvLoading={loading.value}\n\t\t\t\t\tvModel:fileList={fileList.value}\n\t\t\t\t\tmultiple={false}\n\t\t\t\t\tdisabled={disabled.value}\n\t\t\t\t\thttpRequest={httpRequest.value}\n\t\t\t\t\tbeforeUpload={handleBeforeUpload}\n\t\t\t\t\tonExceed={handleOnExceed}\n\t\t\t\t\tonSuccess={handleOnSuccess}\n\t\t\t\t\tonError={handleOnError}\n\t\t\t\t\tonRemove={handleOnRemove}\n\t\t\t\t\tonChange={handleOnChange}\n\t\t\t\t>\n\t\t\t\t\t{{\n\t\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\t\tfileList.value.length > 0 ? (\n\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t<img class=\"el-upload-list__item-thumbnail\" src={fileList.value[0]?.url} />\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"el-upload-list__item-actions\"\n\t\t\t\t\t\t\t\t\t\tonClick={withModifiers(() => {\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}, [\"stop\"])}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={() => handlePreview()} title=\"查看\">\n\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t<ZoomIn />\n\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t{!disabled.value && (\n\t\t\t\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={handleEdit} title=\"编辑\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Edit />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={() => handleRemove()} title=\"删除\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Delete />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t) : slots.default ? (\n\t\t\t\t\t\t\t\tslots.default()\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t<ElIcon class=\"el-icon--upload\">\n\t\t\t\t\t\t\t\t\t\t<UploadFilled />\n\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t<div class=\"el-upload__text\">\n\t\t\t\t\t\t\t\t\t\tDrop file here <br />\n\t\t\t\t\t\t\t\t\t\t<em>click to upload</em>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\ttip: () => <div class=\"el-upload__tip\">file with a size less than {maxSizeMB.value.toString()}MB</div>,\n\t\t\t\t\t}}\n\t\t\t\t</ElUpload>\n\t\t\t\t{state.preview && (\n\t\t\t\t\t<ElImageViewer\n\t\t\t\t\t\tcloseOnPressEscape\n\t\t\t\t\t\thideOnClickModal\n\t\t\t\t\t\tteleported\n\t\t\t\t\t\tonClose={() => (state.preview = false)}\n\t\t\t\t\t\turlList={state.previewList}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Fragment>\n\t\t));\n\n\t\treturn useExpose(expose, {\n\t\t\t/** @description 取消上传请求 */\n\t\t\tabort: computed(() => uploadRef.value?.abort),\n\t\t\t/** @description 手动上传文件列表 */\n\t\t\tsubmit: computed(() => uploadRef.value?.submit),\n\t\t\t/** @description 清空已上传的文件列表(该方法不支持在 before-upload 中调用) */\n\t\t\tclearFiles: computed(() => uploadRef.value?.clearFiles),\n\t\t\t/** @description 手动选择文件 */\n\t\t\thandleStart: computed(() => uploadRef.value?.handleStart),\n\t\t\t/** @description 手动移除文件。file 和 rawFile 已被合并。 */\n\t\t\thandleRemove: computed(() => uploadRef.value?.handleRemove),\n\t\t\t/** @description 加载状态 */\n\t\t\tloading,\n\t\t\t/** @description 文件集合 */\n\t\t\tfileList,\n\t\t\t/** @description 预览 */\n\t\t\tpreview: computed(() => state.preview),\n\t\t\t/** @description 预览集合 */\n\t\t\tpreviewList: computed(() => state.previewList),\n\t\t});\n\t},\n});\n"],"mappings":"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"}
|
|
@@ -59,7 +59,7 @@ var uploadImages_default = defineComponent({
|
|
|
59
59
|
emits: faUploadImagesEmits,
|
|
60
60
|
slots: makeSlots(),
|
|
61
61
|
setup(props, { slots, emit, expose }) {
|
|
62
|
-
const { fileList, loading, formContext, maxSizeMB, handleHttpRequest, handleOnSuccess, handleOnError, handleOnRemove, handleOnExceed, handleOnUpload } = useUpload("FaUploadImages", "图片", props, emit, {
|
|
62
|
+
const { fileList, loading, formContext, maxSizeMB, handleHttpRequest, handleOnSuccess, handleOnError, handleOnRemove, handleOnExceed, handleOnUpload, handleOnChange } = useUpload("FaUploadImages", "图片", props, emit, {
|
|
63
63
|
get maxSize() {
|
|
64
64
|
return props.maxSize;
|
|
65
65
|
},
|
|
@@ -107,7 +107,8 @@ var uploadImages_default = defineComponent({
|
|
|
107
107
|
"onExceed",
|
|
108
108
|
"onSuccess",
|
|
109
109
|
"onError",
|
|
110
|
-
"onRemove"
|
|
110
|
+
"onRemove",
|
|
111
|
+
"onChange"
|
|
111
112
|
]);
|
|
112
113
|
useRender(() => createVNode(Fragment, null, [withDirectives(createVNode(ElUpload, mergeProps(elUploadProps.value, {
|
|
113
114
|
"ref": uploadRef,
|
|
@@ -125,7 +126,8 @@ var uploadImages_default = defineComponent({
|
|
|
125
126
|
"onExceed": handleOnExceed,
|
|
126
127
|
"onSuccess": handleOnSuccess,
|
|
127
128
|
"onError": handleOnError,
|
|
128
|
-
"onRemove": handleOnRemove
|
|
129
|
+
"onRemove": handleOnRemove,
|
|
130
|
+
"onChange": handleOnChange
|
|
129
131
|
}), {
|
|
130
132
|
default: () => fileList.value.length < props.limit && slots.default ? slots.default() : createVNode(ElIcon, null, { default: () => [createVNode(Plus, null, null)] }),
|
|
131
133
|
tip: () => createVNode("div", { "class": "el-upload__tip" }, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadImages.mjs","names":["update:modelValue","update:fileList"],"sources":["../../../../src/components/uploadImages/src/uploadImages.tsx"],"sourcesContent":["import { Fragment, computed, defineComponent, reactive, ref } from \"vue\";\nimport { Delete, Edit, Plus, ZoomIn } from \"@element-plus/icons-vue\";\nimport { ElIcon, ElImageViewer, ElUpload, uploadProps } from \"element-plus\";\nimport { isArray, isNull } from \"lodash-unified\";\nimport { FaMimeType } from \"../../../constants\";\nimport { definePropType, makeSlots, randomString, useExpose, useProps, useRender, withDefineType } from \"../../../utils\";\nimport { useUpload } from \"../../upload/src/useUpload\";\nimport type { UploadFile, UploadInstance, UploadProps, UploadUserFile, uploadListTypes } from \"element-plus\";\n\n/** FaUploadImages 的运行时 Props 定义。 */\nexport const faUploadImagesProps = {\n\t...uploadProps,\n\t/** @description accepted [file types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept), will not work when `thumbnail-mode === true` */\n\taccept: {\n\t\ttype: String,\n\t\tdefault: (): string => FaMimeType.Image,\n\t},\n\t/** @description type of file list */\n\tlistType: {\n\t\ttype: definePropType<(typeof uploadListTypes)[number]>(String),\n\t\tdefault: \"picture-card\",\n\t},\n\t/** @description whether uploading multiple files is permitted */\n\tmultiple: {\n\t\ttype: Boolean,\n\t\tdefault: true,\n\t},\n\t/** @description maximum number of uploads allowed */\n\tlimit: {\n\t\ttype: Number,\n\t\tdefault: 9,\n\t},\n\t/** @description v-model绑定值 */\n\tmodelValue: definePropType<string[] | null>([Array]),\n\t/** @description 大小限制,单位kb */\n\tmaxSize: {\n\t\ttype: [String, Number],\n\t\tdefault: 2048,\n\t},\n\t/** @description 图片上传接口,优先级最高 */\n\tuploadApi: {\n\t\ttype: definePropType<(formData: FormData) => Promise<string>>(Function),\n\t},\n\t/** @description 图片上传地址 */\n\tuploadUrl: String,\n};\n\n/** FaUploadImages 的运行时 Emits 定义。 */\nexport const faUploadImagesEmits = {\n\t/** @description v-model 回调 */\n\t\"update:modelValue\": (value: string[] | null): boolean => isArray(value) || isNull(value),\n\t/** @description v-model:fileList 回调 */\n\t\"update:fileList\": (value: UploadUserFile[]): boolean => isArray(value),\n};\n\n/** FaUploadImages 的插槽参数。 */\nexport interface FaUploadImagesSlots extends Record<string, unknown> {\n\t/** @description 默认内容插槽 */\n\tdefault: never;\n}\n\nexport default defineComponent({\n\tname: \"FaUploadImages\",\n\tprops: faUploadImagesProps,\n\temits: faUploadImagesEmits,\n\tslots: makeSlots<FaUploadImagesSlots>(),\n\tsetup(props, { slots, emit, expose }) {\n\t\tconst {\n\t\t\tfileList,\n\t\t\tloading,\n\t\t\tformContext,\n\t\t\tmaxSizeMB,\n\t\t\thandleHttpRequest,\n\t\t\thandleOnSuccess,\n\t\t\thandleOnError,\n\t\t\thandleOnRemove,\n\t\t\thandleOnExceed,\n\t\t\thandleOnUpload,\n\t\t} = useUpload<string[]>(\"FaUploadImages\", \"图片\", props, emit, {\n\t\t\tget maxSize() {\n\t\t\t\treturn props.maxSize;\n\t\t\t},\n\t\t\tget uploadApi() {\n\t\t\t\treturn props.uploadApi;\n\t\t\t},\n\t\t\tget uploadUrl() {\n\t\t\t\treturn props.uploadUrl || (props.action === uploadProps.action.default ? undefined : props.action);\n\t\t\t},\n\t\t});\n\n\t\tconst disabled = computed(() => {\n\t\t\treturn props.disabled === true || formContext?.disabled === true;\n\t\t});\n\n\t\tconst state = reactive({\n\t\t\tuploadKey: `fa-upload-images__${randomString(8)}`,\n\t\t\tpreview: false,\n\t\t\tpreviewIndex: -1,\n\t\t\tpreviewList: withDefineType<string[]>([]),\n\t\t});\n\n\t\tconst uploadRef = ref<UploadInstance>();\n\t\tconst httpRequest = computed(() => (props.httpRequest === uploadProps.httpRequest.default ? handleHttpRequest : props.httpRequest));\n\n\t\tconst handleEdit = (): void => {\n\t\t\tconst uploadInputEl = document.querySelector(`.${state.uploadKey} .el-upload__input`);\n\t\t\tuploadInputEl?.dispatchEvent(new MouseEvent(\"click\"));\n\t\t};\n\n\t\tconst handlePreview = (uploadFile: UploadFile): void => {\n\t\t\tstate.previewIndex = fileList.value.findIndex((f) => f.url === uploadFile.url);\n\t\t\tstate.previewList = fileList.value.flatMap((item) => (item.url ? [item.url] : []));\n\t\t\tstate.preview = true;\n\t\t};\n\n\t\tconst handleRemove = (index: number): void => {\n\t\t\tconst file = fileList.value[index];\n\t\t\tif (file) uploadRef.value?.handleRemove(file as UploadFile);\n\t\t};\n\n\t\tconst handleBeforeUpload: UploadProps[\"beforeUpload\"] = (rawFile) => {\n\t\t\tif (!handleOnUpload(rawFile)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (props.beforeUpload) {\n\t\t\t\treturn props.beforeUpload(rawFile);\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tconst elUploadProps = useProps(props, uploadProps, [\n\t\t\t\"fileList\",\n\t\t\t\"multiple\",\n\t\t\t\"disabled\",\n\t\t\t\"httpRequest\",\n\t\t\t\"beforeUpload\",\n\t\t\t\"onExceed\",\n\t\t\t\"onSuccess\",\n\t\t\t\"onError\",\n\t\t\t\"onRemove\",\n\t\t]);\n\n\t\tuseRender(() => (\n\t\t\t<Fragment>\n\t\t\t\t<ElUpload\n\t\t\t\t\t{...elUploadProps.value}\n\t\t\t\t\tref={uploadRef}\n\t\t\t\t\tclass={[\"fa-upload-images\", state.uploadKey, { \"fa-upload-images__hidden-upload\": fileList.value.length >= props.limit }]}\n\t\t\t\t\tvLoading={loading.value}\n\t\t\t\t\tvModel:fileList={fileList.value}\n\t\t\t\t\tmultiple={true}\n\t\t\t\t\tdisabled={disabled.value}\n\t\t\t\t\thttpRequest={httpRequest.value}\n\t\t\t\t\tbeforeUpload={handleBeforeUpload}\n\t\t\t\t\tonExceed={handleOnExceed}\n\t\t\t\t\tonSuccess={handleOnSuccess}\n\t\t\t\t\tonError={handleOnError}\n\t\t\t\t\tonRemove={handleOnRemove}\n\t\t\t\t>\n\t\t\t\t\t{{\n\t\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\t\tfileList.value.length < props.limit && slots.default ? (\n\t\t\t\t\t\t\t\tslots.default()\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t<Plus />\n\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\ttip: () => <div class=\"el-upload__tip\">files with a size less than {maxSizeMB.value.toString()}MB</div>,\n\t\t\t\t\t\tfile: ({ file, index }: { file: UploadFile; index: number }) => (\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<img class=\"el-upload-list__item-thumbnail\" src={file.url} />\n\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-actions\">\n\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-preview\" onClick={() => handlePreview(file)} title=\"查看\">\n\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t<ZoomIn />\n\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{!disabled.value && (\n\t\t\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={handleEdit} title=\"编辑\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Edit />\n\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={() => handleRemove(index)} title=\"删除\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Delete />\n\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t),\n\t\t\t\t\t}}\n\t\t\t\t</ElUpload>\n\t\t\t\t{state.preview && (\n\t\t\t\t\t<ElImageViewer\n\t\t\t\t\t\tcloseOnPressEscape\n\t\t\t\t\t\thideOnClickModal\n\t\t\t\t\t\tteleported\n\t\t\t\t\t\tinitialIndex={Math.max(state.previewIndex, 0)}\n\t\t\t\t\t\tonClose={() => (state.preview = false)}\n\t\t\t\t\t\turlList={state.previewList}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Fragment>\n\t\t));\n\n\t\treturn useExpose(expose, {\n\t\t\t/** @description 取消上传请求 */\n\t\t\tabort: computed(() => uploadRef.value?.abort),\n\t\t\t/** @description 手动上传文件列表 */\n\t\t\tsubmit: computed(() => uploadRef.value?.submit),\n\t\t\t/** @description 清空已上传的文件列表(该方法不支持在 before-upload 中调用) */\n\t\t\tclearFiles: computed(() => uploadRef.value?.clearFiles),\n\t\t\t/** @description 手动选择文件 */\n\t\t\thandleStart: computed(() => uploadRef.value?.handleStart),\n\t\t\t/** @description 手动移除文件。file 和 rawFile 已被合并。 */\n\t\t\thandleRemove: computed(() => uploadRef.value?.handleRemove),\n\t\t\t/** @description 加载状态 */\n\t\t\tloading,\n\t\t\t/** @description 文件集合 */\n\t\t\tfileList,\n\t\t\t/** @description 预览 */\n\t\t\tpreview: computed(() => state.preview),\n\t\t\t/** @description 预览集合 */\n\t\t\tpreviewList: computed(() => state.previewList),\n\t\t});\n\t},\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uploadImages.mjs","names":["update:modelValue","update:fileList"],"sources":["../../../../src/components/uploadImages/src/uploadImages.tsx"],"sourcesContent":["import { Fragment, computed, defineComponent, reactive, ref } from \"vue\";\nimport { Delete, Edit, Plus, ZoomIn } from \"@element-plus/icons-vue\";\nimport { ElIcon, ElImageViewer, ElUpload, uploadProps } from \"element-plus\";\nimport { isArray, isNull } from \"lodash-unified\";\nimport { FaMimeType } from \"../../../constants\";\nimport { definePropType, makeSlots, randomString, useExpose, useProps, useRender, withDefineType } from \"../../../utils\";\nimport { useUpload } from \"../../upload/src/useUpload\";\nimport type { UploadFile, UploadInstance, UploadProps, UploadUserFile, uploadListTypes } from \"element-plus\";\n\n/** FaUploadImages 的运行时 Props 定义。 */\nexport const faUploadImagesProps = {\n\t...uploadProps,\n\t/** @description accepted [file types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept), will not work when `thumbnail-mode === true` */\n\taccept: {\n\t\ttype: String,\n\t\tdefault: (): string => FaMimeType.Image,\n\t},\n\t/** @description type of file list */\n\tlistType: {\n\t\ttype: definePropType<(typeof uploadListTypes)[number]>(String),\n\t\tdefault: \"picture-card\",\n\t},\n\t/** @description whether uploading multiple files is permitted */\n\tmultiple: {\n\t\ttype: Boolean,\n\t\tdefault: true,\n\t},\n\t/** @description maximum number of uploads allowed */\n\tlimit: {\n\t\ttype: Number,\n\t\tdefault: 9,\n\t},\n\t/** @description v-model绑定值 */\n\tmodelValue: definePropType<string[] | null>([Array]),\n\t/** @description 大小限制,单位kb */\n\tmaxSize: {\n\t\ttype: [String, Number],\n\t\tdefault: 2048,\n\t},\n\t/** @description 图片上传接口,优先级最高 */\n\tuploadApi: {\n\t\ttype: definePropType<(formData: FormData) => Promise<string>>(Function),\n\t},\n\t/** @description 图片上传地址 */\n\tuploadUrl: String,\n};\n\n/** FaUploadImages 的运行时 Emits 定义。 */\nexport const faUploadImagesEmits = {\n\t/** @description v-model 回调 */\n\t\"update:modelValue\": (value: string[] | null): boolean => isArray(value) || isNull(value),\n\t/** @description v-model:fileList 回调 */\n\t\"update:fileList\": (value: UploadUserFile[]): boolean => isArray(value),\n};\n\n/** FaUploadImages 的插槽参数。 */\nexport interface FaUploadImagesSlots extends Record<string, unknown> {\n\t/** @description 默认内容插槽 */\n\tdefault: never;\n}\n\nexport default defineComponent({\n\tname: \"FaUploadImages\",\n\tprops: faUploadImagesProps,\n\temits: faUploadImagesEmits,\n\tslots: makeSlots<FaUploadImagesSlots>(),\n\tsetup(props, { slots, emit, expose }) {\n\t\tconst {\n\t\t\tfileList,\n\t\t\tloading,\n\t\t\tformContext,\n\t\t\tmaxSizeMB,\n\t\t\thandleHttpRequest,\n\t\t\thandleOnSuccess,\n\t\t\thandleOnError,\n\t\t\thandleOnRemove,\n\t\t\thandleOnExceed,\n\t\t\thandleOnUpload,\n\t\t\thandleOnChange,\n\t\t} = useUpload<string[]>(\"FaUploadImages\", \"图片\", props, emit, {\n\t\t\tget maxSize() {\n\t\t\t\treturn props.maxSize;\n\t\t\t},\n\t\t\tget uploadApi() {\n\t\t\t\treturn props.uploadApi;\n\t\t\t},\n\t\t\tget uploadUrl() {\n\t\t\t\treturn props.uploadUrl || (props.action === uploadProps.action.default ? undefined : props.action);\n\t\t\t},\n\t\t});\n\n\t\tconst disabled = computed(() => {\n\t\t\treturn props.disabled === true || formContext?.disabled === true;\n\t\t});\n\n\t\tconst state = reactive({\n\t\t\tuploadKey: `fa-upload-images__${randomString(8)}`,\n\t\t\tpreview: false,\n\t\t\tpreviewIndex: -1,\n\t\t\tpreviewList: withDefineType<string[]>([]),\n\t\t});\n\n\t\tconst uploadRef = ref<UploadInstance>();\n\t\tconst httpRequest = computed(() => (props.httpRequest === uploadProps.httpRequest.default ? handleHttpRequest : props.httpRequest));\n\n\t\tconst handleEdit = (): void => {\n\t\t\tconst uploadInputEl = document.querySelector(`.${state.uploadKey} .el-upload__input`);\n\t\t\tuploadInputEl?.dispatchEvent(new MouseEvent(\"click\"));\n\t\t};\n\n\t\tconst handlePreview = (uploadFile: UploadFile): void => {\n\t\t\tstate.previewIndex = fileList.value.findIndex((f) => f.url === uploadFile.url);\n\t\t\tstate.previewList = fileList.value.flatMap((item) => (item.url ? [item.url] : []));\n\t\t\tstate.preview = true;\n\t\t};\n\n\t\tconst handleRemove = (index: number): void => {\n\t\t\tconst file = fileList.value[index];\n\t\t\tif (file) uploadRef.value?.handleRemove(file as UploadFile);\n\t\t};\n\n\t\tconst handleBeforeUpload: UploadProps[\"beforeUpload\"] = (rawFile) => {\n\t\t\tif (!handleOnUpload(rawFile)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (props.beforeUpload) {\n\t\t\t\treturn props.beforeUpload(rawFile);\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tconst elUploadProps = useProps(props, uploadProps, [\n\t\t\t\"fileList\",\n\t\t\t\"multiple\",\n\t\t\t\"disabled\",\n\t\t\t\"httpRequest\",\n\t\t\t\"beforeUpload\",\n\t\t\t\"onExceed\",\n\t\t\t\"onSuccess\",\n\t\t\t\"onError\",\n\t\t\t\"onRemove\",\n\t\t\t\"onChange\",\n\t\t]);\n\n\t\tuseRender(() => (\n\t\t\t<Fragment>\n\t\t\t\t<ElUpload\n\t\t\t\t\t{...elUploadProps.value}\n\t\t\t\t\tref={uploadRef}\n\t\t\t\t\tclass={[\"fa-upload-images\", state.uploadKey, { \"fa-upload-images__hidden-upload\": fileList.value.length >= props.limit }]}\n\t\t\t\t\tvLoading={loading.value}\n\t\t\t\t\tvModel:fileList={fileList.value}\n\t\t\t\t\tmultiple={true}\n\t\t\t\t\tdisabled={disabled.value}\n\t\t\t\t\thttpRequest={httpRequest.value}\n\t\t\t\t\tbeforeUpload={handleBeforeUpload}\n\t\t\t\t\tonExceed={handleOnExceed}\n\t\t\t\t\tonSuccess={handleOnSuccess}\n\t\t\t\t\tonError={handleOnError}\n\t\t\t\t\tonRemove={handleOnRemove}\n\t\t\t\t\tonChange={handleOnChange}\n\t\t\t\t>\n\t\t\t\t\t{{\n\t\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\t\tfileList.value.length < props.limit && slots.default ? (\n\t\t\t\t\t\t\t\tslots.default()\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t<Plus />\n\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\ttip: () => <div class=\"el-upload__tip\">files with a size less than {maxSizeMB.value.toString()}MB</div>,\n\t\t\t\t\t\tfile: ({ file, index }: { file: UploadFile; index: number }) => (\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<img class=\"el-upload-list__item-thumbnail\" src={file.url} />\n\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-actions\">\n\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-preview\" onClick={() => handlePreview(file)} title=\"查看\">\n\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t<ZoomIn />\n\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{!disabled.value && (\n\t\t\t\t\t\t\t\t\t\t<Fragment>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={handleEdit} title=\"编辑\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Edit />\n\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"el-upload-list__item-icon\" onClick={() => handleRemove(index)} title=\"删除\">\n\t\t\t\t\t\t\t\t\t\t\t\t<ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Delete />\n\t\t\t\t\t\t\t\t\t\t\t\t</ElIcon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t),\n\t\t\t\t\t}}\n\t\t\t\t</ElUpload>\n\t\t\t\t{state.preview && (\n\t\t\t\t\t<ElImageViewer\n\t\t\t\t\t\tcloseOnPressEscape\n\t\t\t\t\t\thideOnClickModal\n\t\t\t\t\t\tteleported\n\t\t\t\t\t\tinitialIndex={Math.max(state.previewIndex, 0)}\n\t\t\t\t\t\tonClose={() => (state.preview = false)}\n\t\t\t\t\t\turlList={state.previewList}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Fragment>\n\t\t));\n\n\t\treturn useExpose(expose, {\n\t\t\t/** @description 取消上传请求 */\n\t\t\tabort: computed(() => uploadRef.value?.abort),\n\t\t\t/** @description 手动上传文件列表 */\n\t\t\tsubmit: computed(() => uploadRef.value?.submit),\n\t\t\t/** @description 清空已上传的文件列表(该方法不支持在 before-upload 中调用) */\n\t\t\tclearFiles: computed(() => uploadRef.value?.clearFiles),\n\t\t\t/** @description 手动选择文件 */\n\t\t\thandleStart: computed(() => uploadRef.value?.handleStart),\n\t\t\t/** @description 手动移除文件。file 和 rawFile 已被合并。 */\n\t\t\thandleRemove: computed(() => uploadRef.value?.handleRemove),\n\t\t\t/** @description 加载状态 */\n\t\t\tloading,\n\t\t\t/** @description 文件集合 */\n\t\t\tfileList,\n\t\t\t/** @description 预览 */\n\t\t\tpreview: computed(() => state.preview),\n\t\t\t/** @description 预览集合 */\n\t\t\tpreviewList: computed(() => state.previewList),\n\t\t});\n\t},\n});\n"],"mappings":"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"}
|