Skip to content

Upload 上传

基础例子

uploadRequest 返回一个 Promise 用来接受成功/失败,以 axios 插件为例。

控制台
value:[
  {
    "name": "GovUi",
    "url": "/logo.png"
  }
]
查看代码

示例采用模拟 simulateUpload.js,实际项目可参考 axiosUpload.js

vue
<template>
	<demo-container>
		<gov-upload
			:uploadRequest="simulateUpload"
			v-model="value"
			buttonType="success"
			append="上传文件最大 500KB"
		/>
		<template #console>value:{{ value }}</template>
	</demo-container>
</template>

<script setup>
import { ref } from "vue";
// import uploadFile from "./js/axiosUpload.js";
import uploadFile from "./js/simulateUpload.js";

const value = ref([
	{
		name: "GovUi",
		url: "/logo.png",
	},
]);

function simulateUpload(file, fileId, onProgress) {
	return uploadFile({ myfile: file }, onProgress).then((response) => {
		// 返回 url 预览图片;返回 response 后端数据。
		return {
			url: "/logo.png",
			response,
		};
	});
}
</script>
js
/**
 * 模拟上传文件的函数
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */
function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return new Promise((resolve, reject) => {
		// 模拟上传进度
		let total = 0;
		const interval = setInterval(() => {
			if (total < 100) {
				total += 10;
				onProgress(total);
			} else {
				clearInterval(interval);
				// 模拟随机的成功或失败
				const success = Math.random() > 0.5 ? true : false;
				if (success) {
					// 设置预览地址 url;服务器数据 response
					resolve({
						message: "这是后端返回来的数据",
					});
				} else {
					reject(new Error("Upload failed"));
				}
			}
		}, 500);
	});
}

export default uploadFile;
js
/**
 * axios 插件上传文件的函数示例
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */

import axios from "axios";

function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return axios({
		method: "post",
		url: "你的上传接口URL", // 注意替换成你的上传接口URL
		data: formData,
		headers: { "Content-Type": "multipart/form-data" },
		onUploadProgress: ({ loaded, total }) => {
			const percentCompleted = Math.round((loaded * 100) / total);
			onProgress(percentCompleted);
		},
	})
		.then((response) => {
			if (response && response.data) {
				return response.data;
			} else {
				throw new Error("Upload failed");
			}
		})
		.catch((error) => {
			throw error;
		});
}

export default uploadFile;

设置多选

uploadMultiple 可以设置多选。

查看代码

示例采用模拟 simulateUpload.js,实际项目可参考 axiosUpload.js

vue
<template>
	<demo-container>
		<gov-upload
			v-model="value"
			multiple
			:uploadRequest="simulateUpload"
			buttonType="success"
			append="上传文件最大 500KB"
		/>
	</demo-container>
</template>

<script setup>
import { ref } from "vue";
// import uploadFile from "./js/axiosUpload.js";
import uploadFile from "./js/simulateUpload.js";

const value = ref([]);

function simulateUpload(file, fileId, onProgress) {
	return uploadFile({ myfile: file }, onProgress).then((response) => {
		// 返回 url 预览图片;返回 response 后端数据。
		return {
			url: "/logo.png",
			response,
		};
	});
}
</script>
js
/**
 * 模拟上传文件的函数
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */
function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return new Promise((resolve, reject) => {
		// 模拟上传进度
		let total = 0;
		const interval = setInterval(() => {
			if (total < 100) {
				total += 10;
				onProgress(total);
			} else {
				clearInterval(interval);
				// 模拟随机的成功或失败
				const success = Math.random() > 0.5 ? true : false;
				if (success) {
					// 设置预览地址 url;服务器数据 response
					resolve({
						message: "这是后端返回来的数据",
					});
				} else {
					reject(new Error("Upload failed"));
				}
			}
		}, 500);
	});
}

export default uploadFile;
js
/**
 * axios 插件上传文件的函数示例
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */

import axios from "axios";

function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return axios({
		method: "post",
		url: "你的上传接口URL", // 注意替换成你的上传接口URL
		data: formData,
		headers: { "Content-Type": "multipart/form-data" },
		onUploadProgress: ({ loaded, total }) => {
			const percentCompleted = Math.round((loaded * 100) / total);
			onProgress(percentCompleted);
		},
	})
		.then((response) => {
			if (response && response.data) {
				return response.data;
			} else {
				throw new Error("Upload failed");
			}
		})
		.catch((error) => {
			throw error;
		});
}

export default uploadFile;

按钮类型

buttonType 设置上传按钮风格。 buttonSize 设置上传按钮的大小。 buttonText 设置按钮的文字。

查看代码

示例采用模拟 simulateUpload.js,实际项目可参考 axiosUpload.js

vue
<template>
	<demo-container>
		<gov-upload
			v-model="value"
			buttonType="default"
			:uploadRequest="simulateUpload"
			append="上传文件最大 500KB"
		/>
		<hr />
		<gov-upload
			v-model="value"
			buttonType="primary"
			:uploadRequest="simulateUpload"
			append="上传文件最大 500KB"
		/>
		<hr />
		<gov-upload
			v-model="value"
			buttonType="success"
			:uploadRequest="simulateUpload"
			append="上传文件最大 500KB"
		/>
		<hr />
		<gov-upload
			v-model="value"
			buttonType="warning"
			:uploadRequest="simulateUpload"
			append="上传文件最大 500KB"
		/>
		<hr />
		<gov-upload
			v-model="value"
			buttonType="danger"
			:uploadRequest="simulateUpload"
			append="上传文件最大 500KB"
		/>
		<hr />
		<gov-upload
			v-model="value"
			buttonType="info"
			:uploadRequest="simulateUpload"
			append="上传文件最大 500KB"
		/>
	</demo-container>
</template>

<script setup>
import { ref } from "vue";
// import uploadFile from "./js/axiosUpload.js";
import uploadFile from "./js/simulateUpload.js";

const value = ref([]);

function simulateUpload(file, fileId, onProgress) {
	return uploadFile({ myfile: file }, onProgress).then((response) => {
		// 返回 url 预览图片;返回 response 后端数据。
		return {
			url: "/logo.png",
			response,
		};
	});
}
</script>
js
/**
 * 模拟上传文件的函数
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */
function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return new Promise((resolve, reject) => {
		// 模拟上传进度
		let total = 0;
		const interval = setInterval(() => {
			if (total < 100) {
				total += 10;
				onProgress(total);
			} else {
				clearInterval(interval);
				// 模拟随机的成功或失败
				const success = Math.random() > 0.5 ? true : false;
				if (success) {
					// 设置预览地址 url;服务器数据 response
					resolve({
						message: "这是后端返回来的数据",
					});
				} else {
					reject(new Error("Upload failed"));
				}
			}
		}, 500);
	});
}

export default uploadFile;
js
/**
 * axios 插件上传文件的函数示例
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */

import axios from "axios";

function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return axios({
		method: "post",
		url: "你的上传接口URL", // 注意替换成你的上传接口URL
		data: formData,
		headers: { "Content-Type": "multipart/form-data" },
		onUploadProgress: ({ loaded, total }) => {
			const percentCompleted = Math.round((loaded * 100) / total);
			onProgress(percentCompleted);
		},
	})
		.then((response) => {
			if (response && response.data) {
				return response.data;
			} else {
				throw new Error("Upload failed");
			}
		})
		.catch((error) => {
			throw error;
		});
}

export default uploadFile;

设置禁用

在禁用状态下,上传按钮禁用,没有删除按钮。

查看代码
vue
<template>
	<demo-container>
		<gov-upload v-model="value" disabled tip="上传文件最大 500KB" />
	</demo-container>
</template>

<script setup>
import { ref } from "vue";

const value = ref([
	{
		name: "GovUi",
		url: "/logo.png",
	},
]);
</script>

自定义提示

设置 props 或者 <slot /> 来定义提示信息。

查看代码

示例采用模拟 simulateUpload.js,实际项目可参考 axiosUpload.js

vue
<template>
	<demo-container>
		<gov-upload
			v-model="value"
			:uploadRequest="simulateUpload"
			tip="上传文件最大 500KB"
		/>
		<hr />
		<gov-upload v-model="value" :uploadRequest="simulateUpload">
			<template #tip>
				自定义提示:<i>上传文件最大 <b>500KB</b></i>
			</template>
		</gov-upload>
		<hr />
		<gov-upload
			v-model="value"
			:uploadRequest="simulateUpload"
			append="上传文件最大 500KB"
		/>
		<hr />
		<gov-upload v-model="value" :uploadRequest="simulateUpload">
			<template #append>
				自定义提示:<i>上传文件最大 <b>500KB</b></i>
			</template>
		</gov-upload>
	</demo-container>
</template>

<script setup>
import { ref } from "vue";
// import uploadFile from "./js/axiosUpload.js";
import uploadFile from "./js/simulateUpload.js";

const value = ref([]);

function simulateUpload(file, fileId, onProgress) {
	return uploadFile({ myfile: file }, onProgress).then((response) => {
		// 返回 url 预览图片;返回 response 后端数据。
		return {
			url: "/logo.png",
			response,
		};
	});
}
</script>
js
/**
 * 模拟上传文件的函数
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */
function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return new Promise((resolve, reject) => {
		// 模拟上传进度
		let total = 0;
		const interval = setInterval(() => {
			if (total < 100) {
				total += 10;
				onProgress(total);
			} else {
				clearInterval(interval);
				// 模拟随机的成功或失败
				const success = Math.random() > 0.5 ? true : false;
				if (success) {
					// 设置预览地址 url;服务器数据 response
					resolve({
						message: "这是后端返回来的数据",
					});
				} else {
					reject(new Error("Upload failed"));
				}
			}
		}, 500);
	});
}

export default uploadFile;
js
/**
 * axios 插件上传文件的函数示例
 * @param {Object} files - 文件对象,键为字段名,值为文件(File)对象
 * @param {Function} onProgress - 进度回调函数
 * @returns {Promise}
 */

import axios from "axios";

function uploadFile(files, onProgress) {
	const formData = new FormData();

	// 循环遍历文件对象,并将文件添加到FormData中
	Object.keys(files).forEach((key) => {
		formData.append(key, files[key]);
	});

	return axios({
		method: "post",
		url: "你的上传接口URL", // 注意替换成你的上传接口URL
		data: formData,
		headers: { "Content-Type": "multipart/form-data" },
		onUploadProgress: ({ loaded, total }) => {
			const percentCompleted = Math.round((loaded * 100) / total);
			onProgress(percentCompleted);
		},
	})
		.then((response) => {
			if (response && response.data) {
				return response.data;
			} else {
				throw new Error("Upload failed");
			}
		})
		.catch((error) => {
			throw error;
		});
}

export default uploadFile;

Attributes

属性名说明类型可选值默认值
modelValue绑定的值,表示已上传的文件列表Array[]
size上传按钮的尺寸String
disabled是否禁用上传功能Booleantrue, falsefalse
buttonText上传按钮的文本String"上传文件"
buttonType上传按钮的类型String"default"
tip上传组件的提示文本String""
append附加在上传按钮后的文本或元素String""
uploadRequest上传文件的请求函数Functionnull
multiple是否允许多文件上传Booleantrue, falsefalse
triggerForm是否触发表单验证Booleantrue, falsetrue

Events

事件名说明回调参数
update:modelValue绑定值更新时触发新的文件列表
change文件列表变化时触发新的文件列表
delete删除文件时触发被删除文件的ID
focus上传组件获得焦点时触发
blur上传组件失去焦点时触发

Slots

插槽名说明作用域插槽内容
append上传按钮后的附加内容可以放置自定义的内容,如文本或图标
tip上传组件的提示内容可以放置自定义的提示内容

Released under the MIT License.