uniapp项目实践总结(十三)封装文件操作方法
导语:在日常 APP 开发过程中,经常要进行文件的保存、读取列表以及查看和删除文件等操作,接下来就看一下具体的方法。
目录
- 原理分析
- 方法实现
- 实战演练
- 案例展示
原理分析
主要是以下 API。
uni.saveFile
:保存文件到本地缓存列表;uni.getSavedFileList
:获取保存文件列表;uni.getSavedFileInfo
:获取文件详细信息;uni.removeSavedFile
:移除保存的文件;uni.openDocument
:打开文档;
以下方法存于根目录下的scripts
文件夹下的http.js
文件中。
方法实现
接下来一一说明如何实现数据请求、文件下载以及文件的上传的方法封装。
保存文件
保存文件这里使用条件编译,分别对 h5、微信小程序、APP 进行了对应方法的封装。
- 总体方法
这里主要是进行参数的处理,包括默认参数,传入参数,合并参数。
// 保存图片 async function saveFile(options) { let isHttp = options.url.indexOf("http") > -1; let url = isHttp ? options.url : `${urls.baseUrl}${options.url}`; let defultOptions = { url, name: options.name || utils.uuid(), extName: options.extName || utils.fileExt(url), filePath: options.filePath, }; let params = { ...options, ...defultOptions }; console.log("保存文件参数:", params); // h5代码 // 微信小程序代码 // APP 代码 }
- h5 保存文件
这个主要是使用fetch
API 进行文件下载,然后使用a
标签进行点击下载。
// #ifdef H5 fetch(url, { mode: "cors", }) .then(async (res) => { const e = await res.blob(); return e; }) .then((blob) => { const fileElem = document.createElement("a"); let fileUrl = URL.createObjectURL(blob); fileElem.style.display = "none"; fileElem.href = fileUrl; fileElem.download = `${params.name}.${params.extName}`; document.body.appendChild(fileElem); fileElem.click(); setTimeout(() => { URL.revokeObjectURL(fileUrl); fileElem.remove(); }, 1000); }); // #endif
- 微信小程序保存文件
这个主要是使用微信小程序的wx.getFileSystemManager
API 来获取文件管理器接口,然后进行下载保存文件。
// #ifdef MP-WEIXIN const fs = wx.getFileSystemManager(), userDataPath = wx.env.USER_DATA_PATH; const filePath = params.filePath || `${userDataPath}/${params.name}.${params.extName}`; wx.showLoading({ title: "文件下载中...", }); wx.downloadFile({ url, success(res) { let tempFile = res.tempFilePath; let img = ["png", "jpg", "gif"]; if (tempFile && img.includes(params.extName)) { wx.saveImageToPhotosAlbum({ filePath: tempFile, success: function () { wx.showToast({ title: "保存成功!", icon: "success", }); }, fail() { wx.showToast({ title: "保存失败!", icon: "error", }); }, }); } else { fs.saveFile({ tempFilePath: tempFile, filePath, success: function () { wx.showToast({ title: "保存成功!", icon: "success", }); }, fail() { wx.showToast({ title: "保存失败!", icon: "error", }); }, }); } }, fail() { wx.showToast({ title: "下载失败!", icon: "error", }); }, complete() { wx.hideLoading(); }, }); // #endif
- APP 保存文件
这里主要是使用uni.saveFile
方法保存文件。
// #ifdef APP-PLUS uni.showLoading({ title: "文件下载中...", }); let opts = { url, }; let data = await download(opts); if (data) { uni.saveFile({ tempFilePath: data, success: function (res) { uni.showToast({ title: "保存成功!", icon: "success", }); }, fail() { uni.showToast({ title: "保存失败!", icon: "error", }); }, complete() { uni.hideLoading(); }, }); } else { uni.showToast({ title: "下载失败!", icon: "error", }); } // #endif
获取文件管理
下面的 getIfs
是封装的一个方法,用于获取特定终端下面的文件管理方法。
// utils.js // 文件操作 function getIfs() { let ifs = { list: null, info: null, delete: null, open: null, }; // #ifdef MP-WEIXIN let fsm = wx.getFileSystemManager(); ifs.list = fsm.getSavedFileList; ifs.info = fsm.getFileInfo; ifs.delete = fsm.unlink; ifs.open = fsm.open; // #endif // #ifdef APP-PLUS ifs.list = uni.getSavedFileList; ifs.info = uni.getSavedFileInfo; ifs.delete = uni.removeSavedFile; ifs.open = uni.openDocument; // #endif return ifs; }
文件列表
这个支持传入文件路径,获取特定文件信息。
// 保存文件列表 async function fileList(filePath) { try { let ifs = utils.getIfs(), list = []; let data = await ifs.list(); if (data.fileList) { list = data.fileList; if (list.length) { for (let item of list) { item.name = utils.fileName(item.filePath); item.id = utils.uuid(); item.sizeText = utils.fileSize(item.size); item.timeText = utils.nowDate(item.createTime).normal; } } if (filePath) { list = list.filter((s) => filePath === s.filePath); } return { code: 1, data: list, }; } else { return { code: 2, data: data.errMsg, }; } } catch (e) { //TODO handle the exception return { code: 2, data: e, }; } }
查看文件
// 打开文件 async function openFile(filePath = "", showMenu = true) { try { if (!filePath) { return { code: 2, data: "文件路径不能为空!", }; } let ifs = utils.getIfs(); let result = await ifs.open({ filePath, showMenu, }); if (result) { return { code: 1, data: "打开成功!", }; } else { return { code: 2, data: "打开失败!", }; } } catch (e) { //TODO handle the exception return { code: 2, data: e, }; } }
删除文件
// 删除文件 async function deleteFile(filePath) { try { if (!filePath) { return { code: 2, data: "文件路径不能为空!", }; } let ifs = utils.getIfs(); let result = await ifs.delete({ filePath, }); if (result) { return { code: 1, data: "删除成功!", }; } else { return { code: 2, data: "删除失败!", }; } } catch (e) { //TODO handle the exception return { code: 2, data: e, }; } }
写好以后记得导出方法。
实战演练
模板内容
- 保存文件
<button type="primary" size="mini" @click="saveFile('file')" v-if="httpInfo.uploadFileUrl"> 保存文件 </button>
- 文件列表
<!-- #ifdef APP-PLUS --> <view class="list-http"> <button @click="getFileList">文件列表</button> <text class="list-http-txt">响应内容:</text> <view class="list-file" v-for="(item, index) in httpInfo.fileList" :key="item.id"> <view class="list-file-item">文件名称:{{ item.name }}</view> <view class="list-file-item">文件大小:{{ item.sizeText }}</view> <view class="list-file-item">文件路径:{{ item.filePath }}</view> <view class="list-file-item">保存时间:{{ item.timeText }}</view> <view class="list-file-item"> <button size="mini" type="primary" @click="openFile(item)">查看文件</button> <button size="mini" type="warn" @click="delFile(item, index)">删除文件</button> </view> </view> </view> <!-- #endif -->
脚本方法
- 定义数据
let httpInfo = reactive({ fileList: [], });
- 保存文件
// 保存文件 function saveFile(type = "img") { let url = httpInfo[type == "img" ? "uploadImgUrl" : "uploadFileUrl"]; if (url) { console.log("要保存的文件:", url); proxy.$http.saveFile({ url, name: httpInfo.fileName, }); } }
- 文件列表
// #ifdef APP-PLUS // 获取文件列表 async function getFileList() { let filePath = "_doc/uniapp_save/16928451309592.srt"; let data = await proxy.$http.fileList(); if (data.code == 1) { httpInfo.fileList = data.data; } } // #endif
- 查看文件
// #ifdef APP-PLUS // 查看文件 async function openFile(item) { let data = await proxy.$http.openFile(item.filePath); console.log("查看文件结果:", data); } // #endif
- 删除文件
// #ifdef APP-PLUS // 删除文件 async function delFile(item, index) { let data = await proxy.$http.deleteFile(item.filePath); if (data.code === 1) { httpInfo.fileList.splice(index, 1); uni.showToast({ title: data.data, icon: "success", }); } else { uni.showToast({ title: data.data, icon: "error", }); } } // #endif
案例展示
-
保存文件
-
查看文件
-
删除文件
最后
以上就是封装文件操作方法的主要内容,有不足之处,请多多指正。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律