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 Autocomplete 结合asp.net使用要点
Oct 29 Javascript
使用javascript获取flash加载的百分比的实现代码
May 25 Javascript
VBS通过WMI监视注册表变动的代码
Oct 27 Javascript
js解析与序列化json数据(一)json.stringify()的基本用法
Feb 01 Javascript
jQuery对Select的操作大集合(收藏)
Dec 28 Javascript
Javascript实现单例模式
Jan 24 Javascript
jQuery+Ajax实现限制查询间隔的方法
Jun 07 Javascript
全面解析jQuery中的$(window)与$(document)的用法区别
Aug 15 jQuery
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
Jun 07 Javascript
node基于async/await对mysql进行封装
Jun 20 Javascript
Vue数据绑定实例写法
Aug 06 Javascript
你不知道的SpringBoot与Vue部署解决方案
Nov 09 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仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
php 强制下载文件实现代码
2013/10/28 PHP
WIFI万能钥匙密码查询接口实例
2015/09/28 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
在网页里看flash的trace数据的js类
2009/01/10 Javascript
jquery 防止表单重复提交代码
2010/01/21 Javascript
JS 使用for循环遍历子节点查找元素
2014/09/06 Javascript
jQuery中on()方法用法实例
2015/01/19 Javascript
JavaScript中的ParseInt(&quot;08&quot;)和“09”返回0的原因分析及解决办法
2016/05/19 Javascript
js+html5实现canvas绘制椭圆形图案的方法
2016/05/21 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
由简入繁实现Jquery树状结构的方法(推荐)
2016/06/10 Javascript
Bootstrap布局之栅格系统学习笔记
2017/05/04 Javascript
js实现文字列表无缝滚动效果
2017/06/23 Javascript
javascript实现QQ空间相册展示源码
2017/12/12 Javascript
Vue.js的动态组件模板的实现
2018/11/26 Javascript
如何自定义微信小程序tabbar上边框的颜色
2019/07/09 Javascript
详解vue+axios给开发环境和生产环境配置不同的接口地址
2019/08/16 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
OpenLayers3实现图层控件功能
2020/09/25 Javascript
Python 返回汉字的汉语拼音
2009/02/27 Python
Anaconda下安装mysql-python的包实例
2018/06/11 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
Python tkinter实现简单加法计算器代码实例
2020/05/13 Python
Django web自定义通用权限控制实现方法
2020/11/24 Python
关于box-sizing的全面理解
2016/07/28 HTML / CSS
Html5 页面适配iPhoneX(就是那么简单)
2019/09/05 HTML / CSS
Habitat家居英国官方网站:沙发、家具、照明、厨房和户外
2019/12/12 全球购物
班班通项目实施方案
2014/02/25 职场文书
大学生实习鉴定评语
2014/04/25 职场文书
选秀节目策划方案
2014/06/06 职场文书
个人自我剖析材料
2014/09/30 职场文书
内乡县衙导游词
2015/02/05 职场文书
食品仓管员岗位职责
2015/04/01 职场文书
总结Python变量的相关知识
2021/06/28 Python
Android Studio实现简易进制转换计算器
2022/05/20 Java/Android