首页 > 其他分享 >vue3+ts 上传组件

vue3+ts 上传组件

时间:2024-03-16 11:15:58浏览次数:18  
标签:const color ts fileList height width vue3 console 上传

本来是用的jeecg-vue3中的上传组件,如下图:

 功能上还是蛮全的,就是上图中这个链接的代码死活找不到,查了下,是基于antv的a-upload实现的。但是antv中也没找到,上图这个只有移入删除的功能

但是我这边的需求是点击链接可以直接在网页预览,而不是下载,移入后有个删除和下载的功能按钮。

预览这个跟后端同事搞定了,通过点击文件名直接预览,但是!!!下载的按钮想加到文件名后面是死活加不上去了,真心找不到代码,无奈只能自己写一个了

先看效果图:

样式就是根据jeecg的上传组件样式模仿的,但是,我的移入比它的多了一个下载的按钮,哈哈哈哈

 

由于项目是基于jeecg开发的,所以如过有人用的话,大概只能作为参考

这个组件并没写的特别完善,只是针对我当前的项目需求进行了开发props

目前开放的属性有:

 大家可以根据自己情况进行改造

emit('success'), 是将当前操作的fileList数据返回到父页面好进行操作处理

 

引用案例:

 

上代码:

放到了components中

 wjUpload.vue:

<template>
  <div class="wjUpload">
    <input type="file" ref="fileInput" style="display: none" @change="handleFileChange" />
    <div class="tops">
      <div class="labels">
        <label class="upSpan" :class="isDisabled == true ? 'noSpan' : ''">{{ fileLabel }}:</label>
      </div>
      <button class="upBtn" :disabled="isDisabled" @click="triggerFileSelectAndUpload">
        <Icon icon="ant-design:upload-outlined" />
        <span class="upBtnText">上传</span>
      </button>
    </div>
    <div class="bottoms" v-if="fileList.length > 0">
      <div class="b_items" v-for="(item, index) in fileList" :key="index">
        <div class="b_i_item" @mouseover="currentIndex = index" @mouseout="currentIndex = -1">
          <Icon style="margin-left: 4px" icon="ant-design:link-outlined" />
          <div class="b_i_i_a" @click="ylClick(item)">
            <a>{{ setNewItem(item) }}</a>
          </div>
          <div class="downs" v-show="currentIndex == index" @click.stop="downClick(item)">
            <Icon icon="ant-design:download-outlined" />
          </div>
          <div class="deletes" v-show="currentIndex == index && isDisabled == false" @click.stop="deleteFileClick(item, index)">
            <Icon icon="ant-design:rest-outlined" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import { computed, ref, unref, onMounted, watch } from 'vue';
  import { Icon } from '/@/components/Icon';
  import { setUploads, getDownFile } from './wjUp.ts';
  import { getToken } from '/@/utils/auth';
  import { getJiaMi } from '/@/api/common/api';
  import { Bus, getYLurl, getYLurl2 } from '/@/utils/bus.js';
  // 获取emit
  const emit = defineEmits(['success']);
  const fileInput = ref(null);
  // 存放数据地址列表
  const fileList = ref<Array>([]);
  // 是否显示操作按钮--根据下标进行控制
  const currentIndex = ref<number>(-1);
  // 父页面传递的参数
  const props = defineProps({
    // label展示名称
    fileLabel: { type: String, default: () => '文件上传' },
    // 下方链接列表展示
    newFileList: { type: Array, default: () => [] },
    // 控制是否可以操作
    isDisabled: { type: Boolean, default: () => false },
  });
  onMounted(() => {
    watch(
      () => props.newFileList,
      async () => {
        console.log(props.newFileList, '----------aaaaaaaaaaaa------------sssssssssss');
        if (props.newFileList) {
          const newArr = props.newFileList;
          if (typeof newArr === 'string') {
            const fileArray = newArr.split(','); // 假设你想根据逗号来分割字符串
            fileList.value = fileArray;
            console.log('--------');
          } else {
            // 处理不是字符串的情况
            console.log('props.newFileList 不是一个字符串');
          }
        } else {
          fileList.value = [];
        }
      },
      { deep: true, immediate: true }
    );
    watch(fileList, () => {
      // 每当fileList发生变化,就将数据返回到父页面中
      emit('success', fileList.value);
    });
  });

  // 处理文件选择变化
  const handleFileChange = (event) => {
    const file = event.target.files[0];
    if (file) {
      uploadFile(file);
    }
  };

  // 上传文件
  const uploadFile = async (file) => {
    console.log(file, '二进制');
    const formData = new FormData();
    formData.append('file', file);
    const res = await setUploads({ file });
    if (res.code == 200) {
      fileList.value.push(res.result);
      emit('success', fileList.value);
    }
  };
  // 对文件路径进行处理返回文件名
  const setNewItem = (item) => {
    let str = item.slice(item.lastIndexOf('/') + 1);
    return str;
  };

  // 触发文件选择并上传
  const triggerFileSelectAndUpload = () => {
    fileInput.value.click(); // 模拟点击文件选择按钮
  };
  // 监听点击文件预览
  const ylClick = async (e) => {
    console.log(e, '------------>');
    let str = e.slice(e.lastIndexOf('/') + 1);
    let token = getToken();
    let ylUrl = getYLurl();
    let ylUrl2 = getYLurl2();
    var url = ylUrl2 + 'bcCommon/getFileStreamByLocalPath?filePath=' + e + '&fullfilename=' + str + '&XSSTOKEN=' + token; //要预览文件的访问地址
    let cs_base = window.btoa(unescape(encodeURIComponent(url)));
    const newUrls = await getJiaMi({ jiaMiCode: encodeURIComponent(cs_base) });
    window.open(ylUrl + 'onlinePreview?url=' + newUrls);
  };
  // 监听点击下载按钮
  const downClick = async (e) => {
    console.log(e, '=========================');
    // const res = await getDownFile({ filePath: e });
    // console.log(res, '=->++++++++++++>');
    let str = e.slice(e.lastIndexOf('/') + 1);
    getDownFile({ filePath: e }).then((res) => {
      console.log('res-----------', res);
      let url = window.URL.createObjectURL(new Blob([res.data]));
      let link = document.createElement('a');
      link.style.display = 'none';
      link.href = url;
      link.setAttribute('download', str);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link); //下载完成移除元素
      window.URL.revokeObjectURL(url); //释放掉blob对象
    });
  };
  // 监听点击删除按钮
  const deleteFileClick = (item, index) => {
    console.log(item, index);
    fileList.value.splice(index, 1);
    console.log('===============>', fileList.value);
    emit('success', fileList.value);
  };
</script>

<style lang="less" scoped>
  .wjUpload {
    width: 360px;
    min-height: 60px;
    margin: 10px;
    .tops {
      width: 100%;
      height: 40px;
      display: flex;
      align-items: center;
      .labels {
        width: 130px;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: flex-end;
        .upSpan {
          position: relative;
          display: inline-flex;
          align-items: center;
          max-width: 100%;
          height: 32px;
          color: rgba(0, 0, 0, 0.85);
          font-size: 13px;
          margin-left: 26px;
        }
      }
      .upBtn {
        width: 84px;
        height: 32px;
        border: 1px solid #e5e7eb;
        background-color: #fff;
        .upBtnText {
          font-size: 14px;
          color: rgba(0, 0, 0, 0.85);
          margin-left: 8px;
        }
      }
      .upBtn:hover {
        color: #40a9ff;
        border-color: #40a9ff;
        background: #fff;
        .upBtnText {
          color: #40a9ff;
        }
      }
      .upBtn[disabled],
      .upBtn[disabled]:hover,
      .upBtn[disabled]:focus,
      .upBtn[disabled]:active {
        color: rgba(0, 0, 0, 0.25);
        border-color: #d9d9d9;
        background: #f5f5f5;
        text-shadow: none;
        box-shadow: none;
        .upBtnText {
          color: rgba(0, 0, 0, 0.25);
        }
      }
    }
    .bottoms {
      width: 100%;
      min-height: 20px;
      .b_items {
        width: 100%;
        height: 30px;
        margin: 5 0 5px 0;
        display: flex;
        align-items: center;
        .b_i_item {
          width: 240px;
          height: 22px;
          margin-left: 130px;
          display: flex;
          align-items: center;
          transition: background-color 0.3s;
          position: relative;
          .b_i_i_a {
            width: 144px;
            height: 100%;
            margin: 0 8px;
            white-space: nowrap; /* 防止文本换行 */
            overflow: hidden; /* 隐藏超出div的内容 */
            text-overflow: ellipsis; /* 超出部分显示为省略号 */
            color: #1890ff;
          }
          .downs {
            width: 22px;
            height: 22px;
            position: absolute;
            right: 4px;
            display: flex;
            align-items: center;
            justify-content: center;
          }
          .deletes {
            width: 22px;
            height: 22px;
            position: absolute;
            right: 26px;
            display: flex;
            align-items: center;
            justify-content: center;
          }
        }

        .b_i_item:hover {
          background-color: #f5f5f5;
        }
      }
    }
  }
</style>

wjUp.ts:

import { defHttp } from '/@/utils/http/axios';
enum Api {
  setUpload = '/bcCommon/upload',
  getDownFile = '/bcCommon/getFileStream',
}
// 文件上传
export const setUploads = (params) => defHttp.uploadFile({ url: Api.setUpload }, params, { isReturnResponse: true });
// 文件下载
export const getDownFile = (params?) => defHttp.get({ url: Api.getDownFile, params, responseType: 'blob' });

 

标签:const,color,ts,fileList,height,width,vue3,console,上传
From: https://www.cnblogs.com/a973692898/p/18076801

相关文章

  • Spring框架与其他框架(如Struts、Hibernate等)相比有何独特之处?Spring框架的主要优点有
    Spring框架与其他框架(如Struts、Hibernate等)相比有何独特之处?在Spring框架的面试中,可能会被问到的问题涵盖多个方面,包括但不限于以下几个方面:Spring框架的基本理解:请简述一下你对Spring框架的理解。Spring框架的主要优点有哪些?Spring框架与其他框架(如Struts、Hibernate......
  • Delphi提高开发效率之GExperts专家的使用说明
    GExperts是一组通过扩展集成开发环境(IDE)来提高Delphi和C++Builer程序员工作效率的工具。是一款开源的IDE扩展专家,由于去外网下载GExperts非常的麻烦,这里直接提供了Delphi7和Delphi11.1下的GExperts安装包,并连带最新源码一起打包,方便大家使用学习。下面直接看他具有哪些功能,留下实......
  • vite中配置less,vue3中配置less
    前言如果赶时间请直接使用目录跳到解决问题的部分。使用的项目使用vue脚手架生成。npminitvue@latest版本如下"@vitejs/plugin-vue":"^5.0.4","vue":"^3.4.21"由于近期在学less,心想如果不能将其应用到vue项目中,无异于纸上谈兵。于是立即用vue脚手架......
  • 一种奇怪的方式(.gitignore模版问题)导致部署在CentOS服务器上采用Nginx和uWSGI的Django
    如图所示,在本地测试时好好的页面部署在CentOS服务器上用了Nginx和uWSGI就显示不了CSS样式。并且控制台上显示这一部分样式404Notfund于是我就开始各种查找技术贴学习,有说权限没开要修改nginx.conf配置中usernginx;为userroot;的,有说location结尾要加/的,有说DEBUG=True的,有说要......
  • pytorch使用pytorch_wavelets包错误:ValueError: step must be greater than zero 错误
    错误描述在使用pytorch_wavelets包的DWT1DInverse时,发现报错信息如下:Traceback(mostrecentcalllast):File"/work/GDN/test/test_DWT.py",line24,inx_=idwt((YL,YH))File"/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py",line550......
  • Qt QtCharts给QChartView换肤,换背景色添加背景图片
    换色setBackgroundBrush这种接口可以设置QChartView背景色首先,给QChart类去掉背景渲染:换肤1QChart*chart=newQChart();2chart->setTheme(QChart::ChartThemeLight);这里chart是你自检的chart进入枚举一共有多个,可以自己看下,那个更适合。换背景下面展示一些内联......
  • Qt Charts 自定义样式
    QtCharts是Qt框架中用于创建图表和图形可视化的模块,它提供了一些内置的图表类型,如折线图、柱状图、饼图等。如果你想要自定义QtCharts中图表的样式,你可以使用一些方法来实现。以下是一些自定义QtCharts样式的方法:1、使用QChart的样式属性: QtCharts中的QChart类具有许多属性......
  • 【Nut3】nuxt.config.ts项目nuxt配置文件介绍
    简言记录下nuxt3的nuxt.config.ts文件的介绍和使用。NuxtConfigurationnuxt.config.tsNuxt可以通过一个单独的nuxt.config文件进行简单配置。配置文件创建nuxt.config文件的扩展名可以是.js、.ts或.mjs。然后默认导出全局函数defineNuxtConfig的返回值,defineNuxtCo......
  • TSINGSEE青犀AI智能分析网关V4酿酒厂安全挂网AI检测算法
    在酿酒行业中,安全生产一直是企业经营中至关重要的一环。为了确保酒厂生产过程中的安全,TSINGSEE青犀AI智能分析网关V4的安全挂网AI检测算法发挥了重要作用。TSINGSEE青犀AI智能分析网关V4的安全挂网检测算法是针对酒厂里酒窖挂网行为进行智能检测与识别的算法。通过划定检测区域,对......
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:RelativeContainer)
    相对布局组件,用于复杂场景中元素对齐的布局。说明:该组件从APIVersion9开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。规则说明容器内子组件区分水平方向,垂直方向:水平方向为left,middle,right,对应容器的HorizontalAlign.Start,HorizontalAl......