vue 文件上传组件vue-simple-upload 基本使用与源码剖析,前后端分离实现上传,分片上传等流程

【uploader】表格化自整理vue-simple-uploader的文档(超详细) vue-simple-uploader是很强大的uploader组件。 但是其文档内容过于混乱,在此表格化所有文档内容 并进行组件测试与demo编写。 阅读详情
网页右边,向下滑有目录索引,可以根据标题跳转到你想看的内容
如果右边没有就找找左边
运行效果:分片上传,已经上传过,如果丢失某些分片,会自动续传,已经上传完成,会直接跳过,完成秒传

请添加图片描述

本文适合做过全栈开发的同学,最起码需要会vue+spring boot的前后端环境搭建,以及基本的前后端交互逻辑,否则你是听不懂的,最起码是做不了测试的
如果你只是前端工程师,那么自己mock模拟响应就可以了
此博客是学习b站up全栈东的源码笔记,视频链接:https://www.bilibili.com/video/BV1df4y1E77G?p=8&spm_id_from=pageDriver
  1. 希望大家多多支持这位up,讲的真的很好

在这里插入图片描述

一、helloworld环境搭建

1. 前端环境搭建

  1. 下载vue-simple-upload源码https://github.com/simple-uploader/vue-uploader
    在这里插入图片描述
  2. 将项目导入开发工具中,然后进入example文件夹中App.vue文件,指定后端上传文件接口(这个接口路径使我们自己规定,如果你不理解,直接和我写成一样的)
    在这里插入图片描述
  3. 解决跨域问题
    在这里插入图片描述
'/ffmpeg-video':{
 target:'http://localhost:3000',
  changeOrigin:true,
  pathRewrite:{
    '^/ffmpeg-video':'/ffmpeg-video'
  }
}
  1. npm install 安装所有依赖
    在这里插入图片描述
  2. npm run dev 启动项目
    在这里插入图片描述
    在这里插入图片描述

2. 后端环境

  1. 创建一个基本的spring boot项目,保证有spring-boot-starter-web依赖
  2. 配置文件,配置上传路径和端口号(端口号需要和你前端指定的一致)
    在这里插入图片描述
  3. 实体类
    在这里插入图片描述
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;

@Data
public class MultipartFileParams {
    //分片编号
    private int chunkNumber;
    //分片大小
    private long chunkSize;
    //当前分片大小
    private long currentChunkSize;
    //文件总大小
    private long totalSize;
    //分片id
    private String identifier;
    //文件名
    private String filename;
    //相对路径
    private String relativePath;
    //总分片数
    private int totalChunks;
    //spring 接收前端传输来的文件对象
    private MultipartFile file;
}
  1. service层
    在这里插入图片描述
    在这里插入图片描述
import com.yzpnb.entity.MultipartFileParams;
import com.yzpnb.service.FileUploadService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@Service
public class FileUploadServiceImpl implements FileUploadService {
    @Value("${upload.file.path}")
    private String uploadFilePath;

    @Override
    public ResponseEntity<String> upload(MultipartFileParams fileParams) {
        String filePath = uploadFilePath + fileParams.getFilename();

        File fileTemp = new File(filePath);

        File parentFile = fileTemp.getParentFile();

        if(!parentFile.exists()){
            parentFile.mkdirs();
        }
        try {
            MultipartFile file = fileParams.getFile();
            //使用transferTo(dest)方法将上传文件写到服务器上指定的文件;
            //只能使用一次,原因是文件流只可以接收读取一次,传输完毕则关闭流;
            file.transferTo(fileTemp);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok("SUCCESS");
    }
}
  1. controller
    在这里插入图片描述
import com.yzpnb.entity.MultipartFileParams;
import com.yzpnb.service.FileUploadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/ffmpeg-video",produces = "application/json; charset=UTF-8")
@Slf4j
public class UploadController {

    @Autowired
    private FileUploadService fileUploadService;


    @PostMapping("/upload")
    public ResponseEntity<String> upload(MultipartFileParams file){
   		log.info("file: ",file);//打印日志
        return fileUploadService.upload(file);
    }
}

3. 上传文件测试

  1. debug启动后端
  2. 去掉自带的debugger,然后启动前端
    在这里插入图片描述
  3. 上传文件
    在这里插入图片描述

二、源码分析

看源码前,我们先了解几个知识
  1. directive 可以让你自己造一个指令,并封装相应逻辑
  2. mixins 可以让你将封装好的data,mounted等混入你需要的,就相当于复制一份,比如好几个组件都有相同的data和mounted,那么我们不用每个文件都写一遍,直接混入即可
  3. extends 作用不是复制,而是继承,扩展的意思
  4. provide 可以做到伪响应式,大范围的 data 和 menthod 等共用,当我们用provide将一些东西暴露出去后,就可以在其它组件用inject注入进来,但必须有血缘关系
    在这里插入图片描述
  5. 父组件可以使用 props 把数据传给子组件。
  6. 子组件可以使用 $emit,让父组件监听到自定义事件 。
  1. vm.$emit( 事件名, 传递的参数) //触发当前实例上的事件
  2. vm.$on(事件名,function函数);//监听event事件后运行 fn
  3. 比如子组件定义vm.$emit(“show”,data),那么父组件,使用子组件时,就可以通过@show=""来引用事件,子组件每执行一次vm. $emit(“show”,data),父组件就触发一次@show
  1. 因为vue-simple-upload是封装的 simple-uploader.js,所以常用的属性和事件你得知道
  1. 常用属性
    在这里插入图片描述
  2. 常用事件在这里插入图片描述> 8. simple-uploader.js更多的事件,请参考官方文档https://github.com/simple-uploader/Uploader/blob/develop/README_zh-CN.md
上面的东西没看到,看源码是很费劲的哟,或者看源码时有不知道的,可以回头来查

1. mixins.js文件

  1. 首先 uploader.vue文件,暴露提供了一个uploader
    在这里插入图片描述
mixins.js此文件是专门提供给组件混入的,通过minxins指令

在这里插入图片描述

  1. 这个文件,向外暴露了support变量,并通过inject注入了uploader

2. uploader-btn

在这里插入图片描述
在这里插入图片描述

  1. 上面的assignBrowse方法是simple-uploader.js的,具体为什么,在uploader.vue中讲解
  2. 这个方法除了传输3个props变量,还将自己传输了进去,通过$refs的方式(this. $refs.名字这种方式获取dom结点)
  3. 这个方法主要就是,点击选择文件时,弹出选择文件窗口,

3. uploader-unsupport

这个文件是处理用户不支持HTML5是提示用的

当你的浏览器不支持Uploader.js时会提示,这个库需要支持HTML5 File API以及文件切片。
在这里插入图片描述

4. uploader-drop

这个文件是拖动文件到指定位置,也就是选择文件的一个东西,可以拖动文件到这里,但没有上传逻辑,只是将文件选择好

在这里插入图片描述
在这里插入图片描述

5. uploader-list

这个文件主要负责上传文件后的列表显示(由 Uploader.File 文件、文件夹对象组成的数组,文件和文件夹共存)

在这里插入图片描述

  1. 上图中,我们可以看到fileList变量是定义在computed中而不是data域中,作用是,当uploader.fileList中的值发生变化,会立即展示结果,比如我们上传一个文件,这时fileList就会加入一个文件对象,那么就会立即双向绑定渲染出来
  1. computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理
  2. computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化,举例:购物车里面的商品列表和总金额之间的关系,只要商品列表里面的商品数量发生变化,或减少或增多或删除商品,总金额都应该发生变化。这里的这个总金额使用computed属性来进行计算是最好的选择

6. uploader-files

和上面uploader-list基本相同,唯一不同点就是引用的对象不一样(文件对象组成的数组,纯文件列表,没有文件夹)

在这里插入图片描述

7. uploader-file

文件、文件夹单个组件,就是在列表中显示的单个文件,这个组件相对代码较多,我将文档的内容直接搬过来,一个个介绍太浪费时间了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8. uploader

源码位置:vue-upload-master文件夹->src文件夹->components文件夹->uploader.vue文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、分片上传

1. 后端

  1. 实体类
    在这里插入图片描述
import lombok.Data;

@Data
public class FileInfo {
    private String uniqueIdentifier;//文件唯一id
    private String name;//文件名
}

  1. controller
    在这里插入图片描述
import com.yzpnb.entity.FileInfo;
import com.yzpnb.entity.MultipartFileParams;
import com.yzpnb.service.FileUploadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;


/**
 * @author luoliang
 * @date 2018/6/19
 */
@RestController
@RequestMapping(value = "/ffmpeg-video",produces = "application/json; charset=UTF-8")
@Slf4j
public class UploadController {

    @Autowired
    private FileUploadService fileUploadService;

    /**
     * 上传前调用(只调一次),判断文件是否已经被上传完成,如果是,跳过,
     * 如果不是,判断是否传了一半,如果是,将缺失的分片编号返回,让前端传输缺失的分片即可
     * @param file 文件参数
     * @return
     */
    @GetMapping("/upload")
    public ResponseEntity<Map<String,Object>> uploadCheck(MultipartFileParams file){
        log.info("file: "+file);//打印日志
        return fileUploadService.uploadCheck(file);
    }
    /**
     * 上传调用
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public ResponseEntity<String> upload(MultipartFileParams file){
        log.info("file: "+file);//打印日志
        return fileUploadService.upload(file);
    }

    /**
     * 上传完成调用,进行分片文件合并
     */
    @PostMapping("/upload-success")
    public ResponseEntity<String> uploadSuccess(@RequestBody FileInfo file){
        return fileUploadService.uploadSuccess(file);
    }
}
  1. service
    在这里插入图片描述
    在这里插入图片描述
import com.yzpnb.entity.FileInfo;
import com.yzpnb.entity.MultipartFileParams;
import com.yzpnb.service.FileUploadService;
import com.yzpnb.utils.MergeFileUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Log4j2
public class FileUploadServiceImpl implements FileUploadService {
    @Value("${upload.file.path}")
    private String uploadFilePath;

    /**
     * 判断文件是否已经被上传完成,如果是,跳过,
     * 如果不是,判断是否传了一半,如果是,将缺失的分片编号返回,让前端传输缺失的分片即可
     * @param fileParams
     * @return
     */
    @Override
    public ResponseEntity<Map<String,Object>> uploadCheck(MultipartFileParams fileParams) {
        //获取文件唯一id
        String fileDir = fileParams.getIdentifier();
        String filename = fileParams.getFilename();
        //分片目录
        String chunkPath = uploadFilePath + fileDir+"/chunk/";
        //分片目录对象
        File file = new File(chunkPath);
        //获取分片集合
        List<File> chunkFileList = MergeFileUtil.chunkFileList(file);

        //合并后文件路径
        //合并文件路径,D:/develop/video/文件唯一id/merge/filename
        String filePath = uploadFilePath + fileDir+"/merge/"+filename;
        File fileMergeExist = new File(filePath);

        String [] temp;//保存已存在文件列表
        boolean isExists = fileMergeExist.exists();//是否已经纯在合并完成的文件
        if(chunkFileList == null){
            temp= new String[0];
        }else{
            temp = new String[chunkFileList.size()];
            //如果没有合并后文件,代表没有上传完成
            //没上传完,如果有切片,保存已存在切片列表,否则不保存
            if(!isExists && chunkFileList.size()>0){
                for(int i = 0;i<chunkFileList.size();i++){
                    temp[i] = chunkFileList.get(i).getName();//保存已存在文件列表
                }
            }
        }

        //返回结果集
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("code",1);
        hashMap.put("message","Success");
        hashMap.put("needSkiped",isExists);
        hashMap.put("uploadList",temp);

        return ResponseEntity.ok(hashMap);
    }

    /**D:/develop/video/文件唯一id/chunk/分片编号
     * 分片上传文件
     * @param fileParams 文件参数
     * @return
     */
    @Override
    public ResponseEntity<String> upload(MultipartFileParams fileParams) {

        //获取文件唯一id
        String fileDir = fileParams.getIdentifier();
        //分片编号
        int chunkNumber = fileParams.getChunkNumber();
        //文件路径,文件具体路径,D:/develop/video/文件唯一id/chunk/1
        String filePath = uploadFilePath + fileDir+"/chunk/"+chunkNumber;

        File fileTemp = new File(filePath);

        File parentFile = fileTemp.getParentFile();

        if(!parentFile.exists()){
            parentFile.mkdirs();
        }
        try {
            MultipartFile file = fileParams.getFile();
            //使用file.transferTo(dest)方法将上传文件file写到服务器上指定的dest文件;
            //只能使用一次,原因是文件流只可以接收读取一次,传输完毕则关闭流;
            file.transferTo(fileTemp);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok("SUCCESS");
    }

    @Override
    public ResponseEntity<String> uploadSuccess(FileInfo fileInfo) {
        log.info("filename: "+fileInfo.getName());
        log.info("UniqueIdentifier: "+fileInfo.getUniqueIdentifier());
        //分片目录路径
        String chunkPath = uploadFilePath + fileInfo.getUniqueIdentifier()+"/chunk/";
        //合并目录路径
        String mergePath = uploadFilePath + fileInfo.getUniqueIdentifier()+"/merge/";
        //合并文件,D:/develop/video/文件唯一id/merge/filename
        File file = MergeFileUtil.mergeFile(uploadFilePath,chunkPath, mergePath,fileInfo.getName());
        if(file == null){
            return ResponseEntity.ok("ERROR:文件合并失败");
        }
        return ResponseEntity.ok("SUCCESS");
    }
}
  1. 工具类
    在这里插入图片描述
package com.yzpnb.utils;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.*;

public class MergeFileUtil {
    /**
     * 判断要上传分片的目录路径存不存在,不存在就创建,
     * @param filePath 分片路径
     * @return File对象
     */
    public static File isUploadChunkParentPath(String filePath){

        File fileTemp = new File(filePath);

        File parentFile = fileTemp.getParentFile();

        if(!parentFile.exists()){
            parentFile.mkdirs();
        }
        return fileTemp;
    }

    /**
     * 合并文件,D:/develop/video/文件唯一id/merge/filename
     * @param uploadPath 上传路径 D:/develop/video/
     * @param chunkPath 分片文件目录路径
     * @param mergePath 合并文件目录D:/develop/video/文件唯一id/merge/
     * @param fileName 文件名
     * @return
     */
    public static File mergeFile(String uploadPath,String chunkPath,String mergePath,String fileName){
        //得到块文件所在目录
        File file = new File(chunkPath);

        List<File> chunkFileList = chunkFileList(file);

        //合并文件前,先判断是否有合并目录,没有创建
        File fileTemp = new File(mergePath);

        if(!fileTemp.exists()){
            fileTemp.mkdirs();
        }

        //合并文件路径
        File mergeFile = new File(mergePath + fileName);
        // 合并文件存在先删除再创建
        if(mergeFile.exists()){
            mergeFile.delete();
        }
        boolean newFile = false;
        try {
            newFile = mergeFile.createNewFile();//创建文件,已存在返回false,不存在创建文件,目录不存在直接抛异常
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(!newFile){//如果newFile=false,表示文件存在
            return null;
        }
        try {
            //创建写文件对象
            RandomAccessFile raf_write = new RandomAccessFile(mergeFile,"rw");
            //遍历分块文件开始合并
            // 读取文件缓冲区
            byte[] b = new byte[1024];
            for(File chunkFile:chunkFileList){
                RandomAccessFile raf_read = new RandomAccessFile(chunkFile,"r");
                int len =-1;
                //读取分块文件
                while((len = raf_read.read(b))!=-1){
                    //向合并文件中写数据
                    raf_write.write(b,0,len);
                }
                raf_read.close();
            }
            raf_write.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return mergeFile;
    }

    /**
     * 获取指定块文件目录所有文件
     * @param file 块目录
     * @return 文件list
     */
    public static List<File> chunkFileList(File file){
        //获取目录所有文件
        File[] files = file.listFiles();
        if(files == null){
            return null;
        }
        //转换为list,方便排序
        List<File> chunkFileList = new ArrayList<>();
        chunkFileList.addAll(Arrays.asList(files));
        //排序
        Collections.sort(chunkFileList, new Comparator<File>() {
            @Override public int compare(File o1, File o2) {
                if(Integer.parseInt(o1.getName())>Integer.parseInt(o2.getName())){
                    return 1;
                }
                return -1;
            }
        });
        return chunkFileList;
    }
}

2. 前端

  1. 引入axios
    在这里插入图片描述
    在这里插入图片描述
  2. 上传前的判断,实现上传文件前,先判断是否已经存在文件等操作(代码统一放在最后)
    在这里插入图片描述
  3. 上传成功后的回调,请求后端上传成功接口,然后合并分片
    在这里插入图片描述在这里插入图片描述
<template>
  <uploader
  :options="options"
  :file-status-text="statusText"
  class="uploader-example"
  ref="uploader"
  @file-complete="fileComplete"
  @complete="complete"
  @file-success="fileSuccess"
  ></uploader>
</template>

<script>
  export default {
    data () {
      return {
        options: {
          target: '/ffmpeg-video/upload', // '//jsonplaceholder.typicode.com/posts/',
          testChunks: true,//开启分片测试,存在不上传,不存在才上传
          //会在整个文件上传开始前,发送一次'/ffmpeg-video/upload'同名的get请求,并将响应体就是message,传入下面函数中
          //只请求一次后端,但是下面函数是每次发送分片都自动调用一次
          checkChunkUploadedByResponse:function(chunk,message){//每上传一个分片调用一次函数
            let messageObj = JSON.parse(message)
            if(messageObj.needSkiped){
              return true//如果已经上传完成,直接跳过
            }else{//否则根据
              return (messageObj.uploadList || []).indexOf(chunk.offset+1+"")>=0
            }
            return true

          }
        },
        attrs: {
          accept: 'image/*'
        },
        statusText: {
          success: '成功了',
          error: '出错了',
          uploading: '上传中',
          paused: '暂停中',
          waiting: '等待中'
        }
      }
    },
    methods: {
      complete () {
        // debugger
        console.log('complete', arguments)
      },
      fileComplete () {
        console.log('file complete', arguments)
      },
      fileSuccess(){
        this.$axios({
          method:'post',
          url:'/ffmpeg-video/upload-success',
          data: arguments[1]//这个是fileSuccess的回调值,可以直接拿来用
        }).then(response =>{
          console.log("fileSuccess")
        },error =>{

        })
      }
    },
    mounted () {
      console.log( localStorage.getItem("Access-Token"))
      this.$nextTick(() => {
        window.uploader = this.$refs.uploader.uploader
      })
    }
  }
</script>

<style>
  .uploader-example {
    width: 880px;
    padding: 15px;
    margin: 40px auto 0;
    font-size: 12px;
    box-shadow: 0 0 10px rgba(0, 0, 0, .4);
  }
  .uploader-example .uploader-btn {
    margin-right: 4px;
  }
  .uploader-example .uploader-list {
    max-height: 440px;
    overflow: auto;
    overflow-x: hidden;
    overflow-y: auto;
  }
</style>

3. 运行结果

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、实战开发

大家可以参考这篇实战(如果后面链接找不到网页,说明我还没写完)https://blog.youkuaiyun.com/grd_java/article/details/121679400
探索Vue.js中的文件夹上传解决方案:vue-simple-uploader vue-simple-uploader是一个基于Vue.js的组件,它不仅支持文件、多文件、文件夹上传,还具备拖拽上传、错误处理、秒传、分块上传等功能。本文详细介绍了vue-simple-uploader的安装、配置、常用方法与事件,并提供了完整的代码实现及注释,帮助开发者快速掌握并应用这一高效的文件夹上传解决方案。 阅读详情

相关推荐

在vue3项目中实现文件分片上传vue-simple-uploader

vue-simple-uploader 是一个基于 Vue.js 的简单文件上传插件,有以下几个特点:1、简单易用:只需在 Vue 组件中使用该插件,并设置相应的配置选项即可实现文件上传功能。 2、多文件上传:插件支持同时上传多个文件,可以选择并一次性上传多个文件。 3、进度条显示:该插件提供了进度条显示上传进度,让用户清楚地知道文件上传的状态和进度。 4、上传前验证:可以通过设置验证规则,对上传的文件进行前端验证。例如,限制文件类型、大小等,以确保只上传符合要求的文件。

weixin_59423799的博客 8589

基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传

基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传

Guoxuxinwen的博客 9387

vue-simple-uploader实现多文件/文件夹以及可拖拽上传

vue-simple-uploader实现多文件/文件夹以及可拖拽上传

可可爱爱的你吖的博客 8287

vue-simple-uploader 的使用(学习笔记)

Vue uploader

weixin_45608414的博客 6626

PHP大文件上传(切片)分享

前端:vue2,vue3,vue-cli,html5,jquery,webuploader后端:php服务器:linux,centos,Windows,数据库:MySQL,达梦数据库,人大金仓平台:Windows,macOS,Linux,Ubuntu,RedHat,中标麒麟,银河麒麟,统信UOS,信创国产化CPU:x86(Intel,AMD,兆芯,海光),arm(鲲鹏,飞腾),龙芯(mips),龙芯(LoongArch)场景:内网,外网,政府,涉密环境,信创国产化项目。

weixin_52041354的博客 1138

Vue.js轻量级文件上传组件:vue-simple-uploader

随着Web应用程序功能的不断丰富,文件上传已成为很多应用场景中不可或缺的功能。Vue.js,作为一种流行的JavaScript框架,提供了丰富的组件来简化开发流程,其中包括用于实现文件上传功能的组件。在现代Web应用中,文件上传组件是用户与系统进行数据交互的重要接口。通过Vue.js框架,我们可以轻松集成文件上传组件,并根据项目需求进行定制化改造。本章节将从组件集成的流程与关键点、自定义API接口的实现,以及组件的灵活配置与扩展三个方面,深入分析如何在Vue.js项目中实现这一过程。

weixin_35797963的博客 1502

基于vue-simple-uploader封装文件分片上传组件

基于vue-simple-uploader封装文件分片上传组件

qq_41833439的博客 2983

告别手动连接!一键搞定Mumu模拟器与Android Studio的ADB配置

本文详细介绍了如何通过编写自动化脚本,一键完成Mumu模拟器与Android Studio的ADB连接配置。告别繁琐的手动命令输入,该脚本能智能检查环境、判断连接状态并自动处理端口转发,显著提升Android开发者的调试与测试效率。

yog99的博客 495

一二三应用开发平台文件处理设计与实现系列之2——前端集成vue-simple-uploader

文件的上传是系统的必备功能,Element提供了上传组件upload,也基本能满足常见常用的文件上传功能,特别是应对小型文件(10M以下)的处理。但如果是遇到要求更多更高的场景,上传几百兆甚至上G的视频文件,要求分块上传,能断点续传,显示进度,能暂停,能重试……这时候就显得乏力了。如果基于upload实现,需要附加大量的二次开发,这未必是一种最佳实现方案。 这时候,就需要找一找看一看,市面上是否有现成的“轮子”可用了。 接下来,分两篇,分别介绍下前端实现和后端实现,今天首先来说下前端那些事儿。

学海无涯,行者无疆 6574

用Multisim仿真AD630锁定放大器:从2012年电赛A题实战到避坑指南

本文详细介绍了如何使用Multisim仿真AD630锁定放大器,从2012年电赛A题实战出发,提供完整的电路搭建、参数优化及避坑指南。重点解析AD630的开关调制架构和双相位检测的工程实现,帮助读者在强噪声背景下有效提取微弱信号,提升电子设计竞赛和工程实践中的信号处理能力。

weixin_42549451的博客 203

Matt Pocock Skills — AI 编码代理技能包介绍与使用指南

《Matt Pocock Skills:AI编码代理技能包指南》 摘要: Matt Pocock Skills是一套开源AI编码代理技能包,旨在解决AI辅助开发中的四大痛点:需求理解偏差、token浪费、代码质量差和架构腐化。该技能包包含多种实用工具:/grill-with-docs用于需求对齐,/tdd实现测试驱动开发,/diagnose提供规范化调试流程,/triage管理issue生命周期。核心思想包括:通过拷问式对齐确保需求理解一致,建立共享领域语言提高沟通效率,快速反馈闭环加速开发,以及持续架构维

qq_45859163的博客 2221

基于vue-simple-uploader实现文件分片上传、秒传、断点续传

4)currentChunkSize:当前块的大小,实际大小。5)totalSize:文件总大小。6)identifier:这个就是MD5值,每个文件的唯一标示。7)filename:文件名。

顺其自然~专栏 6346

抖音Web端私信Protobuf逆向解析实战

本文详细解析了抖音Web端私信通信的逆向过程,发现其核心采用WebSocket传输Protobuf序列化数据。通过抓包获取二进制样本,利用protoc工具进行原始解码,并逐步推导和编写出对应的.proto协议定义文件,最终实现模拟消息的编码与解码,为理解私有协议逆向提供了完整实战案例。

water的专栏 761

vue-simple-uploader

目前在实现文件上传功能,使用vue-simple-uploader,目前初步封装了一个组件,详细内容日后补充: <template> <div id="global-uploader"> <uploader :options="simpleUploader.options" :key="simpleUploader.uploaderKey" @file-success="onFileSuccess" @file-com

東三城的博客 8942

yolov5部署之七步完成tensorRT模型推理加速

目录前言step 1. 下载yolov5源码以及tensorrtx源码,并将yolov5s.pt转为.wts模型step 2. 确定并下载自己准备使用的CUDA版本。step 3. 根据自己的CUDA版本下载对应版本的cuDNN以及TensorRTstep 4. 根据自己使用的VS版本下载对应版本的OpenCVstep 5. 安装CUDAstep 6. 安装cuDNN、TensorRT以及验证TensorRT是否安装成功 前言     前段时间研究了Pytorch的环境配置,之后便从github上下载了yo

Christo的博客 4万+

【气候模式降尺度】分位数增量映射(QDM)原理及MATLAB代码实现

简介QDM原理及其MATLAB代码实现

WW、forever的博客 5861

浅谈Vue-Simple-Upload

Vue-Simple-Upload 第一次写前端的使用笔记,也是因为这个工具没有很正式的官方文档。所以为防止之后还有可能用到,最好是做一次记录! 这是什么 是一个基于Vue的上传文件组件,只需要引入其对应依赖,就可以直接使用 <uploader :options="options" class="uploader-example"> <uploader-unsupport></u

weixin_42454225的博客 5456

Debezium报错处理系列之二十八: Expiring 1 record(s) for test-ts-0:120001 ms has passed since batch creation

Debezium报错处理系列之二十八: Expiring 1 record(s) for test-ts-0:120001 ms has passed since batch creation

zhengzaifeidelushang的博客 3290

一、文件上传系列-vue-simple-uploader

此部分源码; https://gitee.com/shanhubei/vue-file-uploader 使用vue-simple-uploader上传文件和文件夹 文件上传在项目中应用广泛,尤其类似网盘上传文件的应用,需要批量上传文件、文件夹、秒传、断点续传等功能,那么有一款基于vue的前端上传组件可以满足。这是一个非常强大的文件上传组件,...

chenzhao635的专栏 1431

BES 平台 SDK之 美格信Dongle 连接

最近项目到了试产阶段,需要用到美格信的Dongel 来测试ANC 相关功能。在此简单介绍下如何连接Dongel 的操作步骤。

谢文浩博客 925

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能

之前公司要在管理系统中做一个全局上传插件,即切换各个页面的时候,上传界面还在并且上传不会受到影响,这在vue这种spa框架面前并不是什么难题。然而后端大佬说我们要实现分片上传、秒传以及断点续传的功能,听起来头都大了。很久之前我写了一篇webuploader的文章,结果使用起来发现问题很多,且官方团队不再维护这个插件了, 经过多天调研及踩雷,最终决定基于插件实现该功能,在项目中使用起来无痛且稳定。如果你只是想实现基本的(非定制化的)上传功能,直接使用,多读一下它的文档,不需要更多的二次封装。

weixin_42308266的博客 2468

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

vue-simple-uploader上传组件

vue-simple-uploader是基于 simple-uploader.js 封装的vue上传插件。它的优点包括且不限于以下几种:支持文件、多文件、文件夹上传;支持拖拽文件、文件夹上传 可暂停、继续上传 错误处理 支持“秒传”,通过文件判断服务端是否已存在从而实现“秒传” 分块上传 支持进度、预估剩余时间、出错自动重试、重传等操作安装 使用 源码地址:https://github.com/simple-uploader/vue-uploader 案例:https://gitee.com/luck

weixin_45992894的博客 8930

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

vue大文件分片上传vue-simple-uploader使用

vue大文件分片上传vue-simple-uploader使用 自定义组件的封装,默认样式修改 vue 插槽的使用 文件上传介绍 关于小文件上传类似图片之类的,我们可以直接用很多ui框架封装的上传组件,或者自己写一个input 上传,利用FormData 对象提交文件数据, 但是对于比较大的文件,比如我的这个项目就要求在客户端上传2G左右的文件(难受,http那种),就需要将文件分片上传(file...

qq_43594899的博客 1万+

vue-simple-uploader分片上传

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 前言 在vue上面使用vue-simple-uploader实现分片上传 Github地址:https://github.com/shady-xia/Blog/tree/master/vue-simple-uploader 一、安装vue-simple-uploader npm install vue-sim..

qq_39254643的博客 6532

vue文件上传组件

Vue.js 是一个渐进式的 JavaScript 框架,可以帮助您构建用户界面。如果您想在 Vue.js 中构建文件上传组件,可以使用一些第三方库,例如 vue-upload-component 和 vue-simple-upload。 vue-upload-component 是一个基于 Vue.js 的文件上传组件,具有高度可配置性和可扩展性,可以通过简单地使用组件来实现文件上传功能。 vu...

weixin_42601134的博客 1201

Vue-Simple-Upload:轻松实现前端文件上传的利器

Vue-Simple-Upload:轻松实现前端文件上传的利器 是一个轻量级、易于集成的Vue.js组件,专为前端开发者设计,旨在简化文件上传流程。该项目提供了一套简洁且功能强大的API,使得在Vue应用中处理文件上传变得易如反掌。 技术解析 Vue-Simple-Upload依赖于Vue 2.x版本,采用ES6语法编写,具有良好的模块化和可扩展性。它主要通过HTML5的FileReader AP...

gitblog_00020的博客 658
上一篇: java分布式免费开源搜索引擎 Elasticsearch 详细学习笔记
下一篇: Linux虚拟机使用docker 搭建mysql、redis数据库
ydenergy_殷志鹏
博客等级 码龄7年 5885粉丝 543原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值