NutUI上传组件自定义上传方法并获取结束标志[ps:也是让我改上源码了]Taro+NutUI+Vue3

项目场景:在用户确定上传图片后手动开启上传任务,并在获取上传结束标志进行下一步操作。NutUI提供的上传组件<nut-uploader>支持自定义上传方式,删除已选图片且支持手动执行上传。

开启手动执行上传即可实现确定需要上传的图片后再上传oss服务器的功能,并自定义上传方法添加上传前的逻辑,如获取上传token。接下来需要在用户确认上传后获取上传结束标志并进行下一步操作,以上按官网文档配置上传方法:

<template>
  <nut-uploader 
    :before-xhr-upload="beforeXhrUpload"
    :auto-upload="false"
    ref="uploadRef"
  >
  </nut-uploader>
</template>

<script setup>
import { ref } from 'vue';
    // source file https://github.com/jdf2e/nutui/blob/v4/src/packages/__VUE/uploader/uploader.ts#L6
const beforeXhrUpload = (taroUploadFile, options) => {
      //taroUploadFile  是 Taro.uploadFile , 你也可以自定义设置其它函数
      const uploadTask = taroUploadFile({
        url: options.url,
        filePath: options.taroFilePath,
        fileType: options.fileType,
        header: {
          'Content-Type': 'multipart/form-data',
          ...options.headers
        }, //
        formData: options.formData,
        name: options.name,
        success(response: { errMsg; statusCode; data }) {
          if (options.xhrState == response.statusCode) {
            options.onSuccess?.(response, options);
          } else {
            options.onFailure?.(response, options);
          }
        },
        fail(e) {
          options.onFailure?.(e, options);
        }
      });
      options.onStart?.(options);
      uploadTask.progress((res) => {
        options.onProgress?.(res, options);
        // console.log('上传进度', res.progress);
        // console.log('已经上传的数据长度', res.totalBytesSent);
        // console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend);
      });
      // uploadTask.abort(); // 取消上传任务
    };
const uploadRef = ref(null)
const submitUpload = () => {
  uploadRef.value.submit()
}
</script>

发现uploadRef.value.submit()没有定义回调函数,无法获得结束标志。查看该函数源码:

其中uploadQueuede的赋值代码:

UploaderTaro及其uploadTaro()方法:

不难看出submit()函数通过遍历uploadQueuede中的UploaderTaro对象的uploadTaro()方法依次执行上传任务,其中options.beforeXhrUpload(uploadFile,options)即为自定义的上传方式。

总体思路:由于上传图片不可避免地涉及异步操作,故考虑将submit()及其中所遍历的各个上传任务的改为异步操作,定义回调函数或使用await关键字获取结束标志。

实现细节:源码中使用foreach对上传任务进行遍历,而在 forEach 中使用 async/await 时,异步操作并不会等待前一个操作结束再执行下一个,而是会同时执行多个异步操作。若需要图片依次上传,需要使用for或while执行遍历。

而如果需要等待上传的图片同时上传,为了获取全部图片上传结束标志,需要将源码改为:

(不停摸索后的第一版成功的写法,比较冗杂...)

其他声明异步并等待的操作直接使用async/await关键字即可:

需要注意方法内部执行uploadTask上传的操作需要添加await关键字:

若此处使用自定义上传方法beforeXhrUpload()具体改法根据自定义内容而定,也切记在uploadTask.progress()方法前加await关键字!

Taro + Vue3 + Vite组合是一个现代化的前端开发架构,用于构建跨平台的PWA应用。 NutUI是一个轻量级的移动端UI库,它提供了一套响应式的组件可以方便地在各种设备上使用。 要在这个体系结构中实现NutUI组件的自动按需引入,你需要做以下几个步骤: 1. **安装依赖**: - 首先确保已安装`@tarojs/taro-vue`, `vue`, 和 `vite-plugin-taro`等TaroVue3插件以及`nutui`库本身。 ```bash npm install @tarojs/taro-vue vite vue-router nutui @vue/cli-plugin-vite --save ``` 2. **配置Vite**: 在`.vite.config.js`文件中添加`vite-plugin-taro`插件,配置对Taro支持的处理。 ```javascript import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import Taro from 'vite-plugin-taro' export default defineConfig({ plugins: [vue(), Taro()] }) ``` 3. **使用懒加载(tree-shaking)**: 确保你在Vue组件中导入nutui组件时使用动态导入 (`import()`),这会告诉浏览器只在需要的时候加载组件。 ```html <template> <div> <button @click="loadComponent">加载NutUI组件</button> <component :is="loadedComponentName" /> </div> </template> <script setup> import { ref } from 'vue'; import { onMounted } from 'vue-router'; const loadComponent = async () => { const loadedComponentName = 'nutui-Button'; // 根据实际使用的组件名替换 const Component = await import(`nutui/${loadedComponentName}`); setLoadedComponent(Component.default); }; let loadedComponent; const loadedComponentName = ref(''); onMounted(async () => { loadedComponentName.value = 'nutui-Button'; // 初始加载某个组件 loadComponent(); }); function setLoadedComponent(component) { loadedComponent = component; } </script> ``` 4. **按需引入**: 在Vue组件中,通过判断当前是否显示才导入相应的NutUI组件,这样就不会在所有页面都预先加载整个库。 ```javascript if (process.env.NODE_ENV !== 'production') { // 开发环境,展示所有组件 import('nutui/button').then((Button) => { components.push(Button.default) }) } else { // 生产环境,按需引入 components.push(() => import('nutui/button')) } // ...其他nutui组件按需引入 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值