vue 文件下载 文件上传

3 篇文章 0 订阅

页面使用:

 <template>
<div>
    <a-form-item :field="item.value" :label="item.label" :rules="item.rules">
        <uploadFiles :limit="5" @onsuccess="storePhotosUploadOnsuccess" :fileList="storePhotosList"> </uploadFiles>
    </a-form-item>
</div>
</template>
<script setup lang="ts">
  import { ref, reactive, watch, computed, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
  import uploadFiles from '@/components/uploadFile/index.vue'
  const storePhotosList = ref([])
  const storePhotosUploadOnsuccess = (files, filesStr) => {
    storePhotosList.value = files
    formData.form.storePhotos = filesStr
  }
</script>

组件:

<template>
  <div ref="downloadDom">
    <a-upload
      v-if="type == 'add' || type == 'edit'"
      :action="uploadUrl"
      :headers="headers"
      @success="uploadSuccess"
      :on-before-remove="beforeRemove"
      name="files"
      :image-preview="imagePreview"
      @before-upload="beforeUpload"
      :limit="limit"
      :accept="accept"
      :file-list="reactiveData.fileList"
      :default-file-list="reactiveData.fileList"
      :show-upload-button="showUploadBtn"
      :show-remove-button="showRemoveBtn"
      :download="true"
      :showFileList="showFileList"
      :fileSize="fileSize"
      :list-type="listType"
    >
      <template #upload-button v-if="custom">
        <slot name="button"></slot>
      </template>
    </a-upload>
  
    <div v-else>
      <template v-if="reactiveData.fileList && reactiveData.fileList.length > 0">
        <a-link
          style="display: block"
          v-for="(file, index) in reactiveData.fileList"
          :download="file.name.substring(file.name.lastIndexOf('/') + 1)"
          :key="index"
          :href="file.url"
          :hoverable="false"
        >
          <a-space>
            <icon-file />
            {{ file.name.substring(file.name.lastIndexOf('/') + 1) }}
          </a-space>
        </a-link>
      </template>

      <template v-else> 暂无 </template>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, reactive, computed, defineEmits, defineProps, defineExpose, watch, toRaw, getCurrentInstance, onMounted, nextTick } from 'vue'
  import { Message, Modal } from '@arco-design/web-vue'
  import useLoading from '@/hooks/loading'
  const { loading, setLoading } = useLoading()
  import { getToken } from '@/utils/auth'
  const emit = defineEmits(['onsuccess', 'beforeUpload'])
 
  const uploadUrl = ref("");
  uploadUrl.value=import.meta.env.VITE_DOWNLOAD_HOST+'/file/upload';
  const props = defineProps({
    /**
     * @params 文件列表数据
     */
    fileList: {
      type: Array,

      default: [],
    },
    /**
     * @params 接收的上传文件类型
     */
    accept: {
      type: String,
      default: '.png,.jpg,.jpeg',
    },
    /**
     * @params 上传文件个数
     */
    limit: {
      type: Number,
      default: 1,
    },
    /**
     * @params 图片预览功能是否展示
     */
    imagePreview: {
      type: Boolean,
      default: true,
    },
    /**
     * @params 上传图标是否展示
     */
    showUploadBtn: {
      type: Boolean,

      default: true,
    },
    /**
     * @params 删除图标是否展示
     */
    showRemoveBtn: {
      type: Boolean,

      default: true,
    },
    /**
     * @params edit add新增编辑可以上传  view只是查看
     */
    type: {
      type: String,
      default: 'add',
    },
    /**
     * @params 上传图片大小最大多少M
     */
    fileSize: {
      type: Number,

      default: 5,
    },
    /**
     * @params 图片列表类型
     */
    listType: {
      type: String,
      default: 'picture-card',
    },
    /**
     * @params 自定义上传图标的插槽名
     */
    slotName: String,
    custom: {
      type: Boolean,
      default: false,
    },
    /**
     * @params 是否显示文件列表
     */
    showFileList: {
      type: Boolean,

      default: true,
    },
  })
  const reactiveData = reactive({
    fileList: [],
  })
  //监听
  watch(
    () => props.fileList,
    (val) => {
      reactiveData.fileList = props.fileList

      nextTick(() => {
        addClickEvent()
      })
    },

    { deep: true, immediate: true }
  )

  /*******upload Header********/

  const headers = computed(() => {
    const token = getToken()
    return {
      client: '1', // 客户端类型 1 web端 2 移动端
      Authorization: `${token}`,
    }
  })

  /* 删除 */
  const beforeRemove = (file) => {
    let index = reactiveData.fileList.findIndex((item) => item.id === file.id)

    reactiveData.fileList.splice(index, 1)

    emit('onsuccess', reactiveData.fileList)
  }
  /* 上传前文件大小限制提醒 */
  const beforeUpload = (file) => {
    const isLtM = file.size / 1024 / 1024 < props.fileSize

    if (!isLtM) {
      Message.error('文件不能超过M' + props.fileSize + 'M')
    }
    emit('beforeUpload')

    return isLtM
  }

  /* 上传成功 */

  const uploadSuccess = (file) => {
    const res = file.response
    if (res?.data) {
      let data = res.data
      let imgPath = data[0] ? data[0].filePath : ''
      let fileId = data[0] ? data[0].fileId : ''

      const obj = {
        name: file.name,
        id: fileId,
        url: 'http://10.60.0.44:8950' + imgPath,
        imgPath: imgPath,
      }
      reactiveData.fileList.push(obj)
      let filesStr = ''
      if (reactiveData.fileList && reactiveData.fileList.length) {
        const imgpathArr = reactiveData.fileList.map((item) => {
          return item.imgPath
        })
        filesStr=imgpathArr.join(',')
        console.log(filesStr);
      }
      emit('onsuccess', reactiveData.fileList,filesStr)
    }
  }

  const { proxy } = getCurrentInstance()
  const addClickEvent = () => {
    if (!proxy.$refs['downloadDom']) {
      return
    }
    let downloadDom = proxy.$refs['downloadDom'].getElementsByTagName('a')
    let links = Object.values(downloadDom)
    links.forEach((link) => {
      link.onclick = (e) => {
        e.preventDefault()
        downloadFile(link.href + '?secret=' + keyId.value, link.download)
      }
    })
  }
  //文件下载
  const downloadFile = (url: any, fileName: any) => {
    fetch(url).then((res) => {
      res.blob().then((blob) => {
        const blobUrl = window.URL.createObjectURL(blob)

        // 这里的文件名根据实际情况从响应头或者url里获取

        const filename = fileName

        const a = document.createElement('a')

        a.href = blobUrl

        a.download = filename

        a.click()

        window.URL.revokeObjectURL(blobUrl)
      })
    })
  }
</script>
<style lang="less" scoped></style>

/*文件下载方法*/

 const downloadFile = (url: any, fileName: any) => {
    fetch(url).then((res) => {
      res.blob().then((blob) => {
        const blobUrl = window.URL.createObjectURL(blob)

        // 这里的文件名根据实际情况从响应头或者url里获取

        const filename = fileName

        const a = document.createElement('a')

        a.href = blobUrl

        a.download = filename

        a.click()

        window.URL.revokeObjectURL(blobUrl)
      })
    })
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值