vue3.0搭配.net core实现文件上传组件


Posted in Javascript onOctober 29, 2020

在开发Web应用程序中,文件上传是经常用到的一个功能。
在Jquery时代,做上传功能,一般找jQuery插件就够了,很少有人去探究上传文件插件到底是怎么做的。
简单列一下我们要做的技术点和功能点

使用技术

客户端使用vue.js 3.0,并使用vue3新增的功能:Composition API ,服务器使用asp.net core

功能点

  1. 标签美化
  2. 文件预览
  3. 文件上传
  4. 服务器接收文件

文件选择美化

在标准的html文件选择标签,是十分不美观的。大概就是下图的样子

vue3.0搭配.net core实现文件上传组件

但是我们的设计师的设计图可不是这样的啊,所以第一步是选择美化一下样式。

标签美化

找遍整个搜索引擎,美化文件选择标签只有两种方法

  1. 设置input标签透明度为0,然后定位一个其他的容易修改样式的标签到透明度度为0的input标签上。
  2. 设置input标签的display为none,然后使用JavaScript来触发当前input的点击事件。

因为笔者最近在做基于vue.js 3.0的项目,需要自己自定义很多UI组件,所以参考了layui element ,它们都是使用第二种方式来美化文件选择标签。

vue3.0搭配.net core实现文件上传组件

假设我们UI设计图是上图的样式,如果需要美化,只需要隐藏文件选择的Input标签。然后放置一个按钮,然后设置按钮的样式为设计图上的样式即可

<div class="uploader">
  <button>选择文件</button>
  <input type="file" placeholder="请选择文件" />
 </div>
.uploader {
 display: inline-block;
 button {
  background: #4e6ef2;
  color: aliceblue;
  padding: 5px;
  outline: none;
  border: none;
  &:hover {
   opacity: 0.8;
  }
  &:active {
   opacity: 1;
  }
 }
 input {
  display: none;
 }
}

美化完成组件后,我们需要用在button点击的时候,使用JavaScript去点击隐藏的input标签

<template>
 <div class="uploader">
  <button @click="btnClick">选择文件</button>
  <input type="file" placeholder="请选择文件" ref="fileSelector" />
 </div>
</template>
 
<script>
import { ref } from "vue";
export default {
 name: "uploader",
 setup() {
  const fileSelector = ref(null);
  const btnClick = () => {
   fileSelector.value.click();
  };
  return {
   fileSelector,
   btnClick,
  };
 },
};
</script>

在Composition api中要获取到标签的ref,不能使用this.$refs来获取。当然,你如果喜欢使用vue2的options api。那依然可以使用this.$refs来获取标签的el
只需要简单的触发input的click事件,就可以使浏览器弹出文件选择框了。

文件预览

基本上所有的文件上传组件,都有预览上传图片的功能。本文所写的上传组件当然也不例外。
监听input标签的change事件,获取到files对象。然后使用FileReader读取文件信息。

const fileChange = (e) => {
   let files = e.target.files;
   console.log(files);
   for (let i = 0; i < files.length; i++) {
    let file = files[i];
    var fileReader = new FileReader();
    fileReader.addEventListener(
     "load",
     (event) => {
      console.log(event);
      data.imgList.push({
       base64: event.target.result,
      });
     },
     false
    );
    fileReader.readAsDataURL(file);
   }
  };

vue3.0搭配.net core实现文件上传组件

在Chromium内核等高版本浏览器中,无法像低版本浏览器一样,能获得文件的具体磁盘路径。如果像以前用文件路径去获取文件。只能获得一个 C:\fakepath"+文件名的路径。无法获取到真实文件路径。据说可以通过某些方法获取真实路径。我试过,没成功。有兴趣的朋友可以试试。

文件上传

选择文件后,我们需要把文件保存到到服务器。在传统的多页面web程序中,只需要设置按钮的type为submit,然后使用form表单直接提交文件和表单信息到服务器去。
但是我们做单页面程序,一般来说是通过JavaScript的ajax去上传文件。

const uploadServer = (file) => {
   var form = new FormData();
   form.append("file", file);
   var xhr = new XMLHttpRequest();
   xhr.open("post", props.server);
   xhr.onreadystatechange = () => {
    if (xhr.readyState == 4 && xhr.status == 200) {
     var res = JSON.parse(xhr.responseText);
     console.log("上传成功");
     data.logs.push({
      log: res,
     });
    }
   };
   xhr.upload.onprogress = (event) => {
    if (event.lengthComputable) {
     var percent = (event.loaded / event.total) * 100;
     console.log("上传进度:" + percent);
    }
   };
   xhr.onerror = () => {
    console.log("上传文件错误");
   };
   xhr.ontimeout = () => {
    console.log("上传超时");
   };
   xhr.send(form);
  };

在页面上新增一个按钮,用来手动触发上传

<div class="uploader">
  <button @click="btnClick">选择文件</button>
  <button @click="uploadClick">立即上传</button>
  <input
   type="file"
   placeholder="请选择文件"
   ref="fileSelector"
   @change="fileChange"
   multiple
  />
  <div class="image-list">
   <img v-for="(item, i) in data.imgList" :key="i" :src="item.base64" />
  </div>
  <div class="log">
   <p v-for="(item, i) in data.logs" :key="i">{{ item.log }}</p>
  </div>
 </div>

点击 立即上传 按钮,触发上传

const uploadClick = () => {
   data.files.forEach((file) => {
    uploadServer(file);
   });
  };

vue3.0搭配.net core实现文件上传组件

服务器接收

在服务器编程中,我们使用C#来接收上传的文件。

/// <summary>
    /// 上传
    /// </summary>
    /// <param name="files"></param>
    /// <returns></returns>
    [HttpPost("/upload")]
    public async Task<IActionResult> Upload([FromServices] IWebHostEnvironment host)
    {
      var files = Request.Form.Files;
      long size = files.Sum(f => f.Length);
      List<string> list = new List<string>();
      foreach (var formFile in files)
      {
        if (formFile.Length > 0)
        {
          var path = Path.Combine(host.WebRootPath, "files");
          
          if (!Directory.Exists(path))
          {
            Directory.CreateDirectory(path);
          }
          string fileName = $"{Guid.NewGuid():N}{Path.GetExtension(formFile.FileName)}";
          path = Path.Combine(path, fileName);
          var filePath = path;
 
          using var stream = System.IO.File.Create(filePath);
          await formFile.CopyToAsync(stream);
          var c = Path.VolumeSeparatorChar;
          list.Add($"{Request.Scheme}://{Request.Host.Value}/{Path.Combine("files", fileName).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)}");
        }
      }
 
      return Ok(new { list = list, size });
    }

使用dotnet run运行asp.net core服务端。然后点击上传,你以为就上传成功了吗?
不!没那么简单。如果如果vue程序和asp.net core程序,不在同一个域名下,你还得处理上传跨域问题。当然这个问题在asp.net core中是非常简单的。只需要简单配置一下即可

如果在IIS或者Nginx下,就需要修改对应站点的配置文件了。当然具体服务器软件的配置不在本篇文章的讨论之下。有需要的同学可以私下交流
asp.net core跨域处理

app.UseCors(options =>
      {
        options.WithOrigins("http://localhost:3000", "http://127.0.0.1", "http://localhost:8080"); // 允许特定ip跨域
        options.AllowAnyHeader();
        options.AllowAnyMethod();
        options.AllowCredentials();
      });

以上配置必须要放在app.UseStaticFiles();之前才会生效。

上传成功后,你就会在服务器的wwwroot的files文件夹中看到上传的图片文件了。

vue3.0搭配.net core实现文件上传组件

本文完成了基本的功能,起一个抛砖引玉的作用。更多功能,如:文件类型限制,文件大小限制等,可以根据使用场景自定义扩展

本篇vue 3.0文件上传组件开发到这里就结束了。

以上就是vue3.0搭配.net core实现文件上传组件的详细内容,更多关于vue3.0 文件上传的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
JavaScript 面向对象的之私有成员和公开成员
May 04 Javascript
javascript检测浏览器flash版本的实现代码
Dec 06 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
Feb 08 Javascript
Javascript核心读书有感之类型、值和变量
Feb 11 Javascript
在Html中使用Requirejs进行模块化开发实例详解
Apr 15 Javascript
Angular2内置指令NgFor和NgIf详解
Aug 03 Javascript
jQuery实现判断控件是否显示的方法
Jan 11 Javascript
js实现显示手机号码效果
Mar 09 Javascript
jquery点赞功能实现代码 点个赞吧!
May 29 jQuery
Angular数据绑定机制原理
Apr 17 Javascript
分享5个顶级的JavaScript Ajax组件库
Sep 16 Javascript
JS桶排序的简单理解与实现方法示例
Nov 25 Javascript
使用jQuery实现购物车
Oct 29 #jQuery
ant design中upload组件上传大文件,显示进度条进度的实例
Oct 29 #Javascript
react使用antd表单赋值,用于修改弹框的操作
Oct 29 #Javascript
node.js爬虫框架node-crawler初体验
Oct 29 #Javascript
JavaScript实现网页计算器功能
Oct 29 #Javascript
Javascript数组及类数组相关原理详解
Oct 29 #Javascript
antd Form组件方法getFieldsValue获取自定义组件的值操作
Oct 29 #Javascript
You might like
解决php使用异步调用获取数据时出现(错误c00ce56e导致此项操作无法完成)
2013/07/03 PHP
详解如何在云服务器上部署Laravel
2017/06/30 PHP
php判断文件上传图片格式的实例详解
2017/09/30 PHP
node.js中的querystring.stringify方法使用说明
2014/12/10 Javascript
基于jQuery实现复选框是否选中进行答题提示
2015/12/10 Javascript
七个不允许错过的jQuery小技巧
2015/12/21 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
AngularJS验证信息框架的封装插件用法【w5cValidator扩展插件】
2016/11/03 Javascript
AngularJS中$apply方法和$watch方法用法总结
2016/12/13 Javascript
详谈Node.js之操作文件系统
2017/08/29 Javascript
实例分析js事件循环机制
2017/12/13 Javascript
vue实现吸顶、锚点和滚动高亮按钮效果
2019/10/21 Javascript
JavaScript 接口原理与用法实例详解
2020/05/12 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
如何使用python爬取csdn博客访问量
2016/02/14 Python
利用Python获取操作系统信息实例
2016/09/02 Python
Python 使用SMTP发送邮件的代码小结
2016/09/21 Python
python使用xlrd与xlwt对excel的读写和格式设定
2017/01/21 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
Python对列表去重的多种方法(四种方法)
2017/12/05 Python
python编写分类决策树的代码
2017/12/21 Python
深入理解Django自定义信号(signals)
2018/10/15 Python
python实现自动解数独小程序
2019/01/21 Python
python调用matlab的m自定义函数方法
2019/02/18 Python
Python Subprocess模块原理及实例
2019/08/26 Python
python实发邮件实例详解
2019/11/11 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
使用python matplotlib 画图导入到word中如何保证分辨率
2020/04/16 Python
找到不普通的东西:Bonanza
2016/10/20 全球购物
巴西食品补充剂在线零售商:Músculos na Web
2017/08/07 全球购物
Move Free官方海外旗舰店:美国骨关节健康专业品牌
2017/12/06 全球购物
Gap英国官网:Gap UK
2018/07/18 全球购物
Scotch Porter官方网站:男士美容产品
2020/08/31 全球购物
幼儿园实习生辞职信
2014/01/20 职场文书
微信小程序实现拍照和相册选取图片
2021/05/09 Javascript
python基础入门之普通操作与函数(三)
2021/06/13 Python