在 ASP.NET Core 3.1 MVC 中集成 Vue.js V4 和使用 Dropzone 进行文件上传






4.91/5 (10投票s)
在 ASP.NET Core 3.1 MVC 中配置 Vue.js v4。介绍 Node.js、NPM、WebPack 和 DropZone。使用 NPM 和 WebPack 的任务运行器进行编译和打包。
引言
我们习惯于通过浏览器将文件从用户计算机/系统传输到网站上的不同服务器。这个过程称为文件上传。我们知道在单页应用程序(Single-Page-Application)中,整个页面在初始请求期间加载到浏览器中,之后,它可以更新已更改的特定部分/页面。这样我们就不需要为每次更新重新加载整个页面。无论如何,为了完成文件上传,我们可以将其分为两个部分。文件上传的前端/UI 部分将使用 Vue.js 处理,逻辑文件保存部分/后端将使用 ASP.NET Core 3.1 MVC 处理。单个文件将使用 IFormFile
缓冲在内存中,文件内容将以流的形式访问。
涵盖主题
- Node.js 和 NPM 的介绍与安装
- Vue.js V4 的介绍与安装
- 用于 .NET Core 3.1 的 VS 2019 的介绍与安装
- NPM 和 WebPack 任务运行器的介绍与运行说明
- 将 Vue.js 与 ASP.NET Core 3.1 MVC 集成/配置
- 使用 Vue.js 和 ASP.NET Core MVC 配置/设置 DropZone
必备组件
- 用于 .NET Core 3.1 的 Visual Studio 2019
- 安装 Node.js、NPM 和 Vue.js
- WebPack 任务运行器以可视化方式编译 JS 文件
- NPM 任务运行器以可视化方式安装/更新包
你不喜欢学习但喜欢学东西吗?好的!这里有一些问题给你!
- 为什么选择 Vue.js? - 你可以选择 JS 框架吗(例如 Angular/React/Vue.js 等)?如果可以,那么哪个对你来说是好的,为什么?或者你没有选择权,你的团队已经为你选择了 JS 框架(例如 Vue.js)?如果是这样,那么他们为什么选择它,因为有替代品?
- 为什么选择 NPM? - 你可以选择 Bower、Yarn 或 NPM,那么为什么选择 NPM?
- 为什么选择 WebPack? - 你可以选择 Grunt、Gulp 或 WebPack,那么为什么选择 WebPack?
Node.js 介绍
- Node.js 是开源命令行工具。它使用 Google V8 JavaScript 引擎执行代码。
- Node.js/NPM 的安装 - 要下载 Node.js,请单击链接(https://node.org.cn/en/download/)
- 为什么需要 Node.js/NPM - 简而言之,你可能需要在应用程序中安装第三方包。NPM 是命令行实用程序,可帮助你安装所需的包。但没有 Node.js,你无法安装 NPM。系统会要求你在安装 Node.js 时安装 NPM。因此,安装 Node.js 以运行 NPM。
你是否已安装 Node.js/NPM?
打开命令行,键入:node -v
并按 Enter。如果获得版本号,则表示你的机器上已经安装了它。
- 要检查 npm 版本,请使用以下命令:
npm -v
- 要升级 npm 版本,请使用以下命令:
npm i -g npm
Node/NPM 版本相关常见错误
假设你的系统中有旧版本,并且已升级到最新版本。现在,如果在使用以下命令:npm -v
检查版本时遇到任何错误(例如,“TypeError: log.gauge.isEnabled
”),那么这是 npm 包依赖问题。从以下路径删除所有目录/文件,然后重新安装/修复 Node.js
- C:\Users\[User-Name]\AppData\Roaming\npm-cache
- C:\Users\[User-Name]\AppData\Roaming\npm
Vue.js 介绍
Vue.js 是一个用于单页应用程序(SPA)开发的 JavaScript 框架。它类似于 Angular、React.js 或 Knockout,并避免页面重新加载。它们各自有不同的侧重点,你需要根据自己的情况决定哪个适合你。如果你需要进行动态 DOM 操作,那么 React.js 很好。如果你需要数据驱动的 CRUD 操作,那么 Angular 很好。Vue.Js 的位置介于这些情况之间;但它仍然喜欢处理动态 DOM 操作。但是,这是我的个人看法!
Vue.js V4 的安装
使用以下命令全局安装新版本:npm install -g @vue/cli
。
为什么需要卸载以前版本的 vue-cli? - 如果你已全局安装 vue-cli 包(版本:1.0/2.0)并想使用新的 v4,那么你必须卸载以前的版本。新版本 v4 已从 vue-cli 更改为 @vue/cli。
- 要检查版本,请使用以下命令:
vue --version
- 要使用 NPM 全局卸载它,请使用命令:
npm uninstall vue-cli -g
- 要使用 NPM 全局安装它,请使用命令:
npm install -g @vue/cli
.NET Core 介绍
我不需要介绍 .NET Framework。但是,如果你打算在 Windows、Mac 和/或 Linux 等多个平台上运行应用程序,那么 .NET Core 是完美的,因为它专注于微服务。另一个考虑因素是,如果你需要 Docker 容器,那么你知道容器比虚拟机 (VM) 更轻量。
Visual Studio 2019 的安装
WebPack/NPM 任务运行器资源管理器介绍
Web-pack 任务运行器资源管理器用于编译和捆绑 JS 文件;而 NPM 任务运行器资源管理器用于安装/更新依赖包。
适用于 VS 2019 的 NPM/WebPack 任务运行器的下载和运行说明
为什么需要 NPM 任务运行器?
当你希望在应用程序中手动安装/更新第三方包时,这是必需的。“package.json”文件用于保存包列表并与 Node.js 和 NPM 一起工作。在此文件中,你可以添加依赖项,其中包名称和版本如下所示:
“devDependencies
”: {“PackageName
”: “VersionNumber
”}
Web-Pack 如何工作
让我们看看以下情况
- 最终用户:Eva,我喜欢你的 T 恤。你从哪里买的?我想买一件。
- Eva.js:John 送我的。
- 最终用户:好的,和 John 谈谈,问他从哪里买的。
- Eva.js:嘿 John,去年圣诞节,你送我的 T 恤是从哪里买的?
- John.js:我从印度的 ABC 商店买的。
因此,最终用户发送了一个或多个 Http 请求以获得预期结果。这意味着,存在一个依赖图,其中 Eva.js 调用 John.js。现在,如果你想将这两个 JS 文件合并到一个捆绑包中,那么单个 http 请求即可找到该文件。因此,你需要 Web-Pack 来创建这些捆绑包。你可以使用 Web-Pack 连接、缩小和/或丑化你的 JS 文件。(连接是将所有文件附加到一个大文件中;缩小是删除不必要的空白和字符而不改变功能;丑化是将代码转换为难以理解的格式。)
为什么需要 Web-Pack 任务运行器?
简而言之,考虑到上述情况,我们可以说你需要 Web-Pack 任务运行器来编译和捆绑 JS 文件。
“webpack.config.js”文件拉取所有配置,它有一个入口点来引入所有 JS 文件配置,其中捆绑器开始,然后它使用输出获取路径和文件名配置以生成捆绑包。
module.exports = {
entry: { app: './wwwroot/js/app.js' },
output: {
publicPath: "/dest/js/",
path: path.join(__dirname, '/wwwroot/dest/js/'),
filename: '[name].bundle.js'
}
}
将 Vue.JS 与 ASP.NET Core MVC Web 应用程序集成
项目创建
假设你可以创建一个新项目“ASP.NET Core Web Application>Web Application (Model-View-Controller)”。现在,如果你不想使用默认的 jQuery 库,那么你可以从“wwwroot>lib”中删除文件和文件夹。但是,这是可选的。
模板设计
你可以根据自己的要求修改默认的 site.css 和 site.js 文件。
在项目的 App.js 文件中添加 Bootstrap
在“wwwroot/css”目录中,我添加了用于 CSS 的 app.css 文件,并在“wwwroot/js”目录中,我添加了 app.js 文件,并注册了“Bootstrap
”插件以使用材料图标,最终结果如下:
import $ from 'jquery';
//// Import the Bootstrap Material Design Theme
import 'bootstrap-material-design/dist/css/bootstrap-material-design.min.css';
import 'bootstrap-material-design/dist/js/bootstrap-material-design.min.js';
import 'material-design-colors/dist/material-design.min.css';
//// Import the App Styles
import '../css/app.css';
//// Initialize the Material Design elements when the page loads
$(document).ready(function () {
$('body').bootstrapMaterialDesign
$('[data-toggle="popover"]').popover
注意:我添加此文件仅作为示例。在此项目中,我避免了设计/材料图标,而专注于配置。
将 NPM 包添加到 package.json 中
你可能需要 Vue、babel、WebPack、bootstrap 等包。Babel 是一个 JavaScript 转译器,它编译和转换旧的 ES5 JavaScript 以使其与浏览器兼容。所有包都保存在“package.json”文件中。现在你可以使用 Package-Manager-Console 或 Task Runner Explorer 安装/更新这些包。例如,我添加了一些包,最终结果如下:
{
"name": "HR.App.Web",
"version": "1.1.1",
"private": true,
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"babel-preset-es2017": "^6.24.1",
"bootstrap": "^4.1.3",
"bootstrap-material-design": "^4.1.1",
"css-loader": "^1.0.0",
"fuse.js": "^3.2.1",
"jquery": "^3.3.1",
"material-design-colors": "^1.0.2",
"style-loader": "^0.19.0",
"uglifyjs-webpack-plugin": "^1.3.0",
"url-loader": "^0.6.2",
"vue": "^2.6.10",
"vue-loader": "^15.4.2",
"vue-template-compiler": "^2.5.17",
"webpack": "^4.20.2",
"webpack-cli": "^3.1.1",
"webpack-dev-server": "^3.1.9"
},
"dependencies": {}
}
如果你想使用 NPM 任务运行器资源管理器从 package.json 文件安装/更新包,请确保你已安装 NPM 任务运行器资源管理器。如果你没有看到任务运行器资源管理器,请选择 Package.json 并单击鼠标右键。现在,从任务运行器资源管理器中,从 package.json 中选择安装并单击鼠标右键,如下图所示。结果,所有包都将被安装。
WebPack 配置和捆绑 JS 文件
当 Web-Pack 任务运行器找到 webpack.config.js 文件时,它会自动触发。该文件最终结果如下:
"use strict";
const { VueLoaderPlugin } = require('vue-loader');
const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: {
app: './wwwroot/js/app.js',
home: './Views/Home/Index.cshtml.js',
errorDetail: './Views/Home/ErrorDetail.cshtml.js'
},
plugins: [
new webpack.ProvidePlugin({
'$': 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
}),
new VueLoaderPlugin()
],
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: false,
ecma: 6,
mangle: true
},
sourceMap: true
})
]
},
output: {
publicPath: "/dest/js/",
path: path.join(__dirname, '/wwwroot/dest/js/'),
filename: '[name].bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /(node_modules)/,
query: {
presets: ['es2017']
}
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
},
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 8192
}
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
resolve: {
alias: {
vue: 'vue/dist/vue.js'
},
extensions: ['.js', '.vue']
}
};
我已经在上面解释过,我们需要“Entry
”来配置带有路径的 js 文件源,以便以后获得捆绑包。
entry: { app: './wwwroot/js/app.js', home: './Views/Home/Index.cshtml.js'}
Output:这是已编译 JavaScript 文件的输出路径和捆绑包名称的配置。
output: { publicPath: "/dest/js/", path: path.join(__dirname, '/wwwroot/dest/js/'),
filename: '[name].bundle.js'}
如果你想使用 web-pack Task Runner Explorer 编译和捆绑 JS 文件,请确保你已安装 Web-Pack Task Runner Explorer。如果你没有看到任务运行器资源管理器,请选择 webpack.config.js 并单击鼠标右键。现在,从任务运行器资源管理器中,选择 webpack.config.js 中的“运行”并单击鼠标右键,如下图所示。结果,所有 JS 文件都将构建到输出目录(wwwroot\dest\js)中。
为什么选择 Drop-Zone?
它可以轻松地将文件拖放到其中,并将文件上传到服务器;轻量级 JavaScript 库,使用它所需的代码量最少。
在 JS 和视图文件中添加 Drop-Zone 并进行配置
- 要安装 dropzone 包,请将 dropzone 添加到 package.json 文件的 devDependencies 中。
"devDependencies": {vue2-dropzone": "2.0.0" }
- 如果你打开 webpack.config.js 文件,你会发现我已经将 JavaScript 源文件和路径添加到入口中。入口:
{home: './Views/Home/Index.cshtml.js'}
- 在此项目中,在 View>Home 目录中找到“Index.cshtml”视图页面和“Index.cshtml.js”文件。打开 Index.cshtml 并添加 dropzone 和 JavaScript 捆绑文件。添加它们后,结果如下:
在 dropzone 中
url:
用于发送上传的文件,它需要控制器路径和操作方法(“/Home/SubmitFile”)。use-custom-dropzone-options
:如果你想自定义选项,则为 true;(我在 Index.cshtml.js 文件中添加了“useUploadOptions
”变量。)dropzone-options
:你可以在此处自定义maxfiles
、maxFileSizeInMB
、acceptedFiles
、dictDefaultMessage
。(在 Index.cshtml.js 中找到“uploadOptions
”)v-on:vdropzone-success
:此方法在成功上传文件后使用。v-on:vdropzone-error
:如果上传失败,则使用此方法。
- Index.cshtml.js 文件在 Index.cshtml 中使用,捆绑包名为 home.bundle.js,最终结果如下:
import Vue from 'vue'; import Dropzone from 'vue2-dropzone'; document.addEventListener('DOMContentLoaded', function (event) { let view = new Vue({ el: document.getElementById('view'), components: { "dropzone": Dropzone }, data: { message: 'This is the index page', useUploadOptions: true, uploadOptions: { acceptedFiles: '.png,.jpg,.pdf', dictDefaultMessage: 'To upload the file click here. Or, drop a file here.', maxFiles: 1, maxFileSizeInMB: 20, addRemoveLinks: true } }, methods: { onUploaded: function (file, response) { if (response.status === "OK" || response.status === "200") { console.log('Successfully uploaded!'); } else { this.isVisible = false; console.log(response.message); } }, onUploadError: function (file, message, xhr) { console.log("Message ====> " + JSON.stringify(message)); } } }); });
- 转到 home 控制器文件并添加以下代码:
[HttpPost("/Home/SubmitFile")] public async Task<ActionResult> SubmitFile(IFormFile file) { try { //// To do: Validation //// To do: check file-content string webRootPath = hostingEnvironment.WebRootPath; string fileLandingPath = Path.Combine(webRootPath, folderName); StreamReader stream = new StreamReader(file.OpenReadStream()); if (!Directory.Exists(fileLandingPath)) { Directory.CreateDirectory(fileLandingPath); } string filePath = string.Format("{0}\\{1}{2}", fileLandingPath, Path.GetFileNameWithoutExtension(file.FileName), Path.GetExtension(file.FileName)); using (var fileStream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(fileStream); } var jsonResult = Json(new { status = "OK" }); return jsonResult; } catch (Exception ex) { return Json(new { status = "Error", message = ex.Message }); } }
- 现在选择 Web-pack 任务运行器来编译和捆绑 js 文件。选择“运行”并单击鼠标右键,然后你会找到“运行”和“绑定”选项。单击“运行”。等待几秒钟,你将在“wwwroot\dest\js”目录中获得结果。
- 现在准备运行应用程序,运行后,你将找到以下上传控件:
注意:在本文中,我主要关注配置和设置。因此,我没有关注包的最新版本。你应该使用最新版本的包。
历史
- 2020年2月15日:初始版本