瀏覽代碼

feat: 上传+请求状态

菲鸽 2 年之前
父節點
當前提交
ae24b9d598
共有 5 個文件被更改,包括 122 次插入1 次删除
  1. 2 1
      .eslintrc-auto-import.json
  2. 81 0
      src/hooks/useUpload.ts
  3. 8 0
      src/pages.json
  4. 1 0
      src/pages/index/about.vue
  5. 30 0
      src/pages/index/upload2.vue

+ 2 - 1
.eslintrc-auto-import.json

@@ -87,6 +87,7 @@
     "watchEffect": true,
     "watchPostEffect": true,
     "watchSyncEffect": true,
-    "useRequest": true
+    "useRequest": true,
+    "useUpload": true
   }
 }

+ 81 - 0
src/hooks/useUpload.ts

@@ -0,0 +1,81 @@
+/**
+ * useUpload 是一个定制化的请求钩子,用于处理异步请求和响应。
+ * @param url 上传图片的后台地址,如 https://ukw0y1.laf.run/upload。
+ * @param formData 额外传递给后台的数据,如{name: '菲鸽'}。
+ * @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
+ */
+export default function useUpload<T>(url: string, formData: Record<string, any> = {}) {
+  const loading = ref(false)
+  const error = ref(false)
+  const data = ref<T>()
+
+  const run = () => {
+    // #ifdef MP-WEIXIN
+    // 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
+    // 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
+    uni.chooseMedia({
+      count: 1,
+      mediaType: ['image'],
+      success: (res) => {
+        console.log(res)
+        loading.value = true
+        const tempFilePath = res.tempFiles[0].tempFilePath
+        uni.uploadFile({
+          url,
+          filePath: tempFilePath,
+          name: 'file',
+          formData,
+          success: (uploadFileRes) => {
+            console.log(uploadFileRes.data)
+            data.value = uploadFileRes.data as T
+          },
+          fail: (err) => {
+            console.log('uni.uploadFile err->', err)
+            error.value = true
+          },
+          complete: () => {
+            loading.value = false
+          },
+        })
+      },
+      fail: (err) => {
+        console.log('uni.chooseMedia err->', err)
+        error.value = true
+      },
+    })
+    // #endif
+    // #ifndef MP-WEIXIN
+    uni.chooseImage({
+      count: 1,
+      success: (res) => {
+        console.log(res)
+        loading.value = true
+        const tempFilePath = res.tempFilePaths[0]
+        uni.uploadFile({
+          url,
+          filePath: tempFilePath,
+          name: 'file',
+          formData,
+          success: (uploadFileRes) => {
+            console.log(uploadFileRes.data)
+            data.value = uploadFileRes.data as T
+          },
+          fail: (err) => {
+            console.log('uni.uploadFile err->', err)
+            error.value = true
+          },
+          complete: () => {
+            loading.value = false
+          },
+        })
+      },
+      fail: (err) => {
+        console.log('uni.chooseImage err->', err)
+        error.value = true
+      },
+    })
+    // #endif
+  }
+
+  return { loading, error, data, run }
+}

+ 8 - 0
src/pages.json

@@ -75,6 +75,14 @@
       "style": {
         "navigationBarTitleText": "上传"
       }
+    },
+    {
+      "path": "pages/index/upload2",
+      "type": "page",
+      "layout": "default",
+      "style": {
+        "navigationBarTitleText": "上传"
+      }
     }
   ],
   "subPackages": []

+ 1 - 0
src/pages/index/about.vue

@@ -24,6 +24,7 @@
     </view>
     <view class="text-center mt-8 text-#fff">
       <wd-button type="primary" @click="gotoPage('upload')">上传demo</wd-button>
+      <wd-button type="primary" @click="gotoPage('upload2')">上传demo2(请求状态一体化)</wd-button>
     </view>
   </view>
 </template>

+ 30 - 0
src/pages/index/upload2.vue

@@ -0,0 +1,30 @@
+<route lang="json5" type="page">
+{
+  layout: 'default',
+  style: {
+    navigationBarTitleText: '上传',
+  },
+}
+</route>
+
+<template>
+  <view class="p-4 text-center">
+    <wd-button @click="run">选择图片并上传</wd-button>
+    <view v-if="loading" class="text-blue h-10">上传...</view>
+    <template v-else>
+      <view class="m-2">上传后返回的图片地址:</view>
+      <view class="m-2">{{ data }}</view>
+      <view class="h-80 w-full">
+        <image v-if="data" :src="data" mode="scaleToFill" />
+      </view>
+    </template>
+  </view>
+</template>
+
+<script lang="ts" setup>
+const { loading, data, run } = useUpload<string>('https://ukw0y1.laf.run/upload', { user: '菲鸽' })
+</script>
+
+<style lang="scss" scoped>
+//
+</style>