Vue3: 二次封装Tdesign中的FileUpload组件-hook(更为易用!)

初衷

TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。

当我们使用Tdesign中的FileUpload组件时,我们可能希望对其进行二次封装,以满足特定的需求或增加额外的功能。我们的初衷是让这个组件更加灵活、易用,并且能够适应不同的场景。

通过二次封装,我们可以将其整合到我们的应用程序中,使其更符合我们的设计规范和UI风格。 之前写有一篇关于:

Vue3: 二次封装WangEditor富文本编辑器-hook

也得到了不少的好评,确实在工作中,如果遇到有一些公用的组件,不妨结合它们的官方文档进行一下定制,定制成符合我们业务需求的组件。

后面,我将在图片上传和视频上传,做一下hooks封装, 在开始实战总结之前,先说一下什么是hooks,有什么好处

hooks介绍

Hooks封装是React中一种强大的编程模式 尽管Vue3中没有像React中的Hooks一样的编程模式,但Vue3引入了Composition API,提供了类似于Hooks的功能,具有一些类似的魅力:

  1. 逻辑复用:Composition API允许将逻辑封装到可复用的函数中,称为"composition function"。这样可以将一些常见的逻辑和功能进行封装,并在多个组件中进行复用,从而减少代码的重复。
  2. 更好的组件组合性:通过Composition API的组合函数,我们可以更灵活地组合组件逻辑,并将其粒度化。这使得组件更加可组合,不再受限于单一的渲染函数和生命周期钩子。
  3. 提高代码可读性:使用可重用的composition function,可以将组件的逻辑细分为更小的部分,使得代码更加清晰和易于阅读。同时,通过Composition API的函数式风格,我们可以更好地组织和维护代码。
  4. 更好的测试性:通过将逻辑封装到composition function中,可以更容易地进行单元测试。我们可以针对每个composition function编写独立的测试,并更好地模拟输入和验证输出,提高代码质量和可维护性。
  5. 更好的性能优化:Composition API提供了更多的工具,例如响应式、计算属性和watch等,用于处理和优化应用的状态和数据流。这使得性能优化更加清晰和高效。

虽然Vue3中的Composition API与React Hooks略有不同,但它们都带来了类似的魅力,包括逻辑复用、可读性的提高、更好的组件组合性、更好的测试性和更好的性能优化。通过合理使用Composition API,我们可以更好地开发Vue3应用,提高开发效率和代码质量。

那么接下来,我将通过图片上传和视频上传,封装hooks的全过程做一下总结。

二次封装FileUpload实现图片、视频上传

介绍Tdesign中FileUpload文档属性

在做封装之前,我们需要知道FileUpload提供了哪些属性方法,后面我们需要在此基础上做扩展. 这里只贴出较为关键和需要扩展的几个属性方法:

requestMethod

beforeUpload

该方法可以不用写入hooks中,可以在具体需求的地方,单独编写。因为文件大小、文件类型等相关需求需要按产品的设计而定,所以不适宜写在hooks

至于文件大小限制,upload组件早有提供,可以直接传入相应参数

sizeLimit

如下代码:

html 复制代码
<t-upload
    ref="imageRef"
    v-model="images"
    theme="custom"
    accept="image/jpg,image/jpeg,image/png,image/gif"
    multiple
    allow-upload-duplicate-file
    :max="10"
    :request-method="uploadImage"
    :before-upload="beforeUpload"
    :size-limit="{ size: 1, unit: 'MB', message: '上传的图片不符合要求,请重新上传' }"
    @validate="onUploadValidate"
>
    <t-icon name="add" class="icon" />
</t-upload>
html 复制代码
<t-upload
    ref="imageMultiRef"
    v-model="multiImages"
    theme="custom"
    accept="image/jpg,image/jpeg,image/png,image/gif"
    allow-upload-duplicate-file
    :request-method="uploadMultiImage"
    :before-upload="beforeUpload"
    :size-limit="{ size: 1, unit: 'MB', message: '上传的图片不符合要求,请重新上传' }"
    @validate="onUploadValidate"
>
    <t-icon name="add" size="30" class="icon" />
    <span>上传图片</span>
</t-upload>

我们需要将images、uploadImage, removeImage这些属性封装在hooks中操作,并将这些方法暴露出来 使用的方式,可以参考如下,可以声明不同别名进行多次引用

js 复制代码
// 图片上传
const { images, uploadImage, removeImage } = useImageUpload((res) => {
	// 重置选中图片索引
	currIdx.value = -1;

	updateGif(res.files[0]?.url, TAG_NAME.image);
});

// 多图上传
const {
	images: multiImages,
	uploadImage: uploadMultiImage,
	removeImage: removeMultiImage,
} = useImageUpload((res) => {
	// 重置选中图片索引
	currIdx.value = -1;

	updateGif(res.files[0]?.url, TAG_NAME.imageMulti);
});

// 轮播图上传
const {
	images: swiperImages,
	uploadImage: uploadSwiperImage,
	removeImage: removeSwiperImage,
} = useImageUpload((res) => {
	// 重置选中图片索引
	currIdx.value = -1;

	updateGif(res.files[0]?.url, TAG_NAME.swiper);
});

若是需要上传成功后,将信息回传到自定义的回调方法中,可如上useImageUpload,传入一个成功回调方法做处理。

hooks图片上传

js 复制代码
// 图片上传
export function useImageUpload(uploadSuccess, opts = { rename: true }) {
	const images = ref([]);

	const uploadImage = (file) =>
		new Promise((resolve) => {
			upload(Array.isArray(file) ? file : file.raw, opts)
				.then((res: PutObjectResult[] | PutObjectResult) => {
					const response: { files?: { url: string; name: string }[]; url?: string } = {};
					if (Array.isArray(res)) response.files = res.map((v) => ({ url: v.url, name: v.name }));
					else response.url = res.url;

					uploadSuccess?.(response, images);
					resolve({ status: 'success', response });
				})
				.catch((res) => {
					resolve({ status: 'fail', error: '上传失败', res });
				});
		});

	const removeImage = (index) => {
		images.value.splice(index, 1);
	};

	return {
		images,
		uploadImage,
		removeImage,
	};
}

这段代码定义了一个名为useImageUpload的自定义Vue Composition API hook。该hook接受一个uploadSuccess函数作为参数,以及一个可选的opts对象参数。

代码中的upload为调用上传接口逻辑所封装的方法,可根据各自项目的情况做相应的封装。

useImageUpload函数内部,首先创建一个images响应式引用ref([]),用于存储上传成功的图片列表。

然后定义了uploadImage函数,用于处理图片上传操作。该函数接受一个文件(或文件数组)作为参数,并返回一个Promise对象。在函数内部,调用了一个名为upload的上传函数,传入文件参数和opts选项。该upload函数可能返回一个PutObjectResult对象,或者一个PutObjectResult对象数组。

根据上传结果的不同,构建了一个response对象,该对象包含上传成功的文件的URL和名称。如果上传结果是一个数组,将每个文件的URL和名称保存在response.files属性中,否则将文件的URL保存在response.url属性中。

然后通过调用uploadSuccess函数,将response对象和images列表传递给外部组件进行处理。最后通过Promise对象的resolve方法返回一个包含上传结果的对象,包括状态(successfail)、可能的错误信息和上传结果本身。

最后,定义了removeImage函数,用于从images列表中删除指定索引的图片。

最后,返回一个对象,该对象包含了images列表、uploadImage函数和removeImage函数,供外部组件使用。

相关推荐
undefined&&懒洋洋3 分钟前
Web和UE5像素流送、通信教程
前端·ue5
大前端爱好者2 小时前
React 19 新特性详解
前端
随云6322 小时前
WebGL编程指南之着色器语言GLSL ES(入门GLSL ES这篇就够了)
前端·webgl
随云6322 小时前
WebGL编程指南之进入三维世界
前端·webgl
寻找09之夏3 小时前
【Vue3实战】:用导航守卫拦截未保存的编辑,提升用户体验
前端·vue.js
多多米10054 小时前
初学Vue(2)
前端·javascript·vue.js
柏箱4 小时前
PHP基本语法总结
开发语言·前端·html·php
新缸中之脑4 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8564 小时前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序
看到请催我学习4 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript