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 相关文章推荐
jquery api参考 visualjquery 中国线路 速度快
Nov 30 Javascript
JavaScript 学习笔记(十一)
Jan 19 Javascript
JS实现横向与竖向两个选项卡Tab联动的方法
Sep 27 Javascript
jQuery获取DOM节点实例分析(2种方式)
Dec 15 Javascript
javascript表单控件实例讲解
Sep 13 Javascript
在一个页面重复使用一个js函数的方法详解
Dec 26 Javascript
使用classList来实现两个按钮样式的切换方法
Jan 24 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
Nov 29 Javascript
解决IOS端微信H5页面软键盘弹起后页面下方留白的问题
Jun 05 Javascript
JavaScript工具库之Lodash详解
Jun 15 Javascript
vue基于better-scroll实现左右联动滑动页面
Jun 30 Javascript
jdk1.8+vue elementui实现多级菜单功能
Sep 24 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 strrpos()与strripos()函数
2013/08/31 PHP
PHP程序员基本要求和必备技能
2014/05/09 PHP
php获取网页上所有链接的方法
2015/04/03 PHP
基于PHP实现假装商品限时抢购繁忙的效果
2015/10/16 PHP
php生成带logo二维码方法小结
2016/04/08 PHP
PHPExcel笔记, mpdf导出
2016/05/03 PHP
PHP网站自动化配置的实现方法(必看)
2017/05/27 PHP
PHP实现简单的计算器
2020/08/28 PHP
PHP7新增函数
2021/03/09 PHP
jquery制作搜狐快站页面效果示例分享
2014/02/21 Javascript
node.js中的fs.closeSync方法使用说明
2014/12/17 Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
2015/03/12 Javascript
javascript制作sql转换为stringBuffer的小工具
2015/04/03 Javascript
JavaScript动态添加css样式和script标签
2016/07/19 Javascript
RequireJS简易绘图程序开发
2016/10/28 Javascript
angularjs过滤器--filter与ng-repeat配合有奇效
2017/04/20 Javascript
js+html5实现侧滑页面效果
2017/07/15 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
2017/09/18 jQuery
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
2018/07/30 Javascript
jquery实现垂直手风琴导航栏
2020/02/18 jQuery
[51:50]完美世界DOTA2联赛 Magma vs GXR 第一场 11.07
2020/11/10 DOTA
python re正则表达式模块(Regular Expression)
2014/07/16 Python
研究Python的ORM框架中的SQLAlchemy库的映射关系
2015/04/25 Python
Python变量作用范围实例分析
2015/07/07 Python
Python生成器generator用法示例
2018/08/10 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
利用Python小工具实现3秒钟将视频转换为音频
2019/10/29 Python
详解如何在PyCharm控制台中输出彩色文字和背景
2020/08/17 Python
python 解决Windows平台上路径有空格的问题
2020/11/10 Python
跨域修改iframe页面内容详解
2019/10/31 HTML / CSS
Kathmandu英国网站:新西兰户外运动品牌
2017/03/27 全球购物
Hotels.com香港酒店网:你的自由行酒店订房专家
2018/01/22 全球购物
世界上最好的足球商店:Unisport
2019/03/02 全球购物
公司门卫岗位职责范本
2014/07/08 职场文书
2016高考感言
2015/08/01 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang