• 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 代码
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • h5 保存文件

    这个主要是使用fetchAPI 进行文件下载,然后使用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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 微信小程序保存文件

    这个主要是使用微信小程序wx.getFileSystemManagerAPI 来获取文件管理器接口,然后进行下载保存文件。

    // #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    获取文件管理

    下面的 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    文件列表

    这个支持传入文件路径,获取特定文件信息。

    // 保存文件列表
    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,
        };
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    查看文件

    // 打开文件
    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,
        };
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    删除文件

    // 删除文件
    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,
        };
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    写好以后记得导出方法。

    实战演练

    模板内容

    • 保存文件
    <button type="primary" size="mini" @click="saveFile('file')" v-if="httpInfo.uploadFileUrl">
      保存文件
    button>
    
    • 1
    • 2
    • 3
    • 文件列表
    
    <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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    脚本方法

    • 定义数据
    let httpInfo = reactive({
      fileList: [],
    });
    
    • 1
    • 2
    • 3
    • 保存文件
    // 保存文件
    function saveFile(type = "img") {
      let url = httpInfo[type == "img" ? "uploadImgUrl" : "uploadFileUrl"];
      if (url) {
        console.log("要保存的文件:", url);
        proxy.$http.saveFile({
          url,
          name: httpInfo.fileName,
        });
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 文件列表
    // #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 查看文件
    // #ifdef APP-PLUS
    // 查看文件
    async function openFile(item) {
      let data = await proxy.$http.openFile(item.filePath);
      console.log("查看文件结果:", data);
    }
    
    // #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 删除文件
    // #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    案例展示

    • 查看文件
      在这里插入图片描述

    • 删除文件
      在这里插入图片描述

    最后

    以上就是封装文件操作方法的主要内容,有不足之处,请多多指正。

  • 相关阅读:
    JavaScript基础
    杜教筛练习题
    k8s-helm部署应用 19
    PHP代码审计12—反序列化漏洞
    【Spring Security 系列】(四)高层级组件
    Android 内存优化&内存泄漏处理
    【计算机视觉 | 目标检测】目标检测常用数据集及其介绍(十六)
    (一)Jmeter安装与简单使用 #1024程序员节|用代码,改变世界#
    AcrelEMS能效管理平台为高层小区用电安全保驾护航
    MacOS升级后命令行出现xcrun: error: invalid active developer path报错信息
  • 原文地址:https://blog.csdn.net/fed_guanqi/article/details/132767265