【Vue】Vue与ASP.NET Core WebAPI的集成

SPA单页面应用已经遍地开花,熟知的三大框架,AngularVueReact,其中AngularReact均可集成至ASP.NET Core,且提供了相关了中间件。但是Vue没有:

As far as I’m aware, we don’t have plans to introduce Vue-specific features. This isn’t because we have anything against Vue, but rather just to limit the growth in the number of frameworks that we’re maintaining support for. The dev team only has a finite capacity for handling third-party concepts, and last year we made the strategic choice to focus on only Angular and React.

本篇将介绍如何集成Vue

1.集成的效果

SPAASP.NET Core集成后。根据需求不同,是可以达到两种不同效果。

1.1 一键开启

通过Vistual Studio-->F5,便可以直接启动前端应用开发模式后台api服务,且再用一个端口下。这种方便单人开发运行,调试。

app.UseSpa(spa =>{spa.Options.SourcePath = "ClientApp";if (env.IsDevelopment()){//spa.UseReactDevelopmentServer(npmScript: "start");spa.UseVueCliServer(npmScript: "start");//spa.UseProxyToSpaDevelopmentServer("http://localhost:8080");}});

1.2 独立运行,减轻依赖

另外就是在典型前后端分离的协同开发,常用调试方式启动后端api服务,确定api端口号(假设后端端口为3000),然后去前端配置文件,如vue.config.js修改代理,如下配置:

module.exports = {//omit some config..devServer: {proxy: 'localhost:3000'}
}

然后:

  • 后端启动

  • 前端启动

  • 然后再去访问前端

但是集成后,就不必这样操作,只需要在后端Startup.cs中指定固定的SPA调试服务器地址。

app.UseSpa(spa =>{spa.Options.SourcePath = "ClientApp";if (env.IsDevelopment()){//spa.UseReactDevelopmentServer(npmScript: "start");//spa.UseVueCliServer(npmScript: "start");spa.UseProxyToSpaDevelopmentServer("http://localhost:8080");}});

这样后端开发人员需要再看下前端效果,就不必再去单独看前端,前端一旦启动,端口一般不会变化,做如上配置,便可直接通过Vistual Studio-->F5直接运行。

  • 前端启动

  • 后端启动,直接就反向代理到前端开发服务器,无需再去访问前端。

2.集成的原理

2.1 启动前端

通过中间件调用node进程,执行如下命令:

npm start -- --port {dynamic_port}
  • dynamic_port是在运行过程中随机一个端口。npm 命令已经存在在 package.json 中配置,它将通过 vue-cli-service serve --port 启动开发服务器。

2.2 代理前端调试服务器

前端调试服务器启动成功后,中间件将会创建一个HttpClient代理:将请求一起转发到前端调试服务器 ,然后将响应复制为自己的响应,上面UseProxyToSpaDevelopmentServer没有启动前端的过程(因为前端已启动完成),只是把前端请求静态资源的请求代理到前端调试服务器。

3.集成步骤

3.1 安装nuget包

Install-Package Garfield.SpaServices.Extensions.Vue -Version 1.0.0

这是博主根据官方库改写,正如nuget包的文档写的那样:由于官方没有支持Vue,看后续是否支持,如支持,此包将归档废弃。

3.2 创建Vue项目

在API项目创建ClientApp文件,在此文件夹下创建或复制Vue项目。

保证以下目录结构即可:

ClientApp/package.json

3.3 修改package.json

适配后端这边,package.json要做一些调整,主要是端口由后端启动时随机指定可用的。

"scripts": {"start": "vue-cli-service serve --port", //edit here"build": "vue-cli-service build","lint": "vue-cli-service lint","test:unit": "vue-cli-service test:unit","test:e2e": "vue-cli-service test:e2e"
},

3.4 修改Startup.cs

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{//omit some code..app.UseStaticFiles();//PRODUCTION uses webpack static filesif (!env.IsDevelopment()){app.UseSpaStaticFiles();}app.UseSpa(spa =>{spa.Options.SourcePath = "ClientApp";if (env.IsDevelopment()){spa.UseVueCliServer(npmScript: "start");//spa.UseProxyToSpaDevelopmentServer("http://localhost:8080");}});
}

4.还原构建-Build

在我们调试之前,一定是构建项目,但是我们的项目现在是一个包含前端Vue后端Webapi的前后端分离项目。后端需要还原各种nuget包,在那之前,前端也需要还原npm包,以前博主是执行npm install

这里介绍下使用MSBuild自动执行,修改csproj,增加Target:

<PropertyGroup><!--omit some--><SpaRoot>ClientApp\</SpaRoot>
</PropertyGroup>
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') "><!-- Ensure Node.js is installed --><Exec Command="node --version" ContinueOnError="true"><Output TaskParameter="ExitCode" PropertyName="ErrorCode" /></Exec><Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." /><Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." /><Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>

此时就会在Build ASP.NET WebAPI项目前,自动还原前端项目,执行npm install

5.调试-Debug

从效果上来看,两种集成方式貌似没啥大的差别,但是从开发的调试的角度,有各自运用的场景。

5.1 集成调试

保持上面的配置与代码不变,直接运行ASP.NET Web API

Vue将会自动构建,并与ASP.NET Core WebAPI项目将会集成运行,通过访问localhost:port便可以调试访问应用。

5.2 独立调试

如果后端接口稳定,仅仅是前端问题,那么上面的集成调试是比较方便的。想象一下,每次都要重新启动,执行npm start,还是有点费时间。特别是前端已经足够稳定,后端接口修改频繁,那么这样的方式无疑是太慢了,因为每次都需要重新启动vue项目,失去了集成的优势。所以独立调试后端更符合此类场景。

5.2.1 启动前端

cd ClientApp
npm start 8080

5.2.2 修改后端

// spa.UseVueCliServer(npmScript: "start"); //替换如下代码
spa.UseProxyToSpaDevelopmentServer("http://localhost:8080");

当启动 ASP.NET Core 应用时,它不会启动 Vue dev 服务器, 而是使用手动启动的实例。这使它能够更快地启动和重新启动。不再需要每次都等待 Vue CLI重新生成客户端应用。

6.发布-Publish

小项目,我们就不需要nginx去放静态文件,修改配置等等。

以往博主部署这种前后端分离项目,是通过nginx部署静态前端文件,反向代理后端接口。这种方式没问题。但是这里介绍一点新鲜的(至少对博主而言),前端Vue项目通过npm run build构建成一系列的静态文件。这些静态文件就是我们的SPA。说白了,就是一个静态网页。

所以需要静态文件中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{//omit some code..app.UseStaticFiles();if (!env.IsDevelopment()){app.UseSpaStaticFiles();}
}

然后指定我们静态文件的路径

//Startup.cs
public void ConfigureServices(IServiceCollection services)
{//omit some code..services.AddSpaStaticFiles(c=>{c.RootPath = "ClientApp/dist";});
}

这里我们把Vue项目包含在webapi项目中,文件夹ClientApp,他构建的文件夹为dist,当然这个也是可以修改的。

最重要一步来了,发布时让构建好的静态文件随着WebAPI一起发布,而不需要,单独执行npm run build然后手动拷贝,这里还是用到了MSbuild,所以同样需要修改csproj文件,增加publishTarget

<PropertyGroup><!--omit some xml..--><SpaRoot>ClientApp\</SpaRoot>
</PropertyGroup>  
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish"><!-- As part of publishing, ensure the JS resources are freshly built in production mode --><!--<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />--><Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" /><!-- Include the newly-built files in the publish output --><ItemGroup><DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" /><ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)"><RelativePath>%(DistFiles.Identity)</RelativePath><CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory><ExcludeFromSingleFile>true</ExcludeFromSingleFile></ResolvedFileToPublish></ItemGroup>
</Target>

大概指令:发布时运行webpack

  • 如果需要的话执行npm install还原(我注释了)

  • 执行npm run build进行构建

  • 拷贝构建好的dist文件夹内容到发布文件夹中

这时再通过Visual Studio后者命令发布时,就会同步构建前端项目,发布后端API且包含前端构建后的dist文件。便可以不用分开部署,从而融合为同一个程序。

参考链接

https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild-well-known-item-metadata?view=vs-2019

https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/visual-studio-publish-profiles?view=aspnetcore-3.1

https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild?view=vs-2019

https://blog.csdn.net/sinat_36112136/article/details/103039817

https://github.com/dotnet/sdk/issues/795#issuecomment-289782712

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306094.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

引入Jaeger——封装

随着微服务的普及&#xff0c;微服务间的调用全链路跟踪也火了起来&#xff0c;Jaeger(https://www.jaegertracing.io/)是CNCF孵化的全链路跟踪型项目&#xff0c;在.net core中&#xff0c;提供了一个Jaeger的Nuget(https://github.com/jaegertracing/jaeger-client-csharp)包…

临近年关,发生两起磁盘占满引发的服务下线故障

一口气说两个因为磁盘空间不足引发的应用故障。作为拿起键盘一把梭的Coder&#xff0c; 开发--->部署-->收工--->心旷神怡&#xff0c;滋一口82年的可乐.过了几个月&#xff0c;服务突然下线了&#xff01;CTO又有杀程序员祭天的理由了!事故1&#xff1a;Azure App Se…

c语言幼儿园积木游戏,幼儿园《积木游戏》课件【三篇】

【导语】课件制作本身就是作者综合素养的一种体现&#xff0c;它显现出制作者对教育、教学、教材改革方向的把握&#xff0c;对课堂教学的理解&#xff0c;对现代教育技术的领悟。因此教师在设计课件时一定要吃透教学内容&#xff0c;设计出符合教学的方案用于课件。下面是无忧…

蚂蚁调度AntJob-分布式任务调度系统

分布式任务调度系统&#xff0c;纯NET打造的重量级大数据实时计算平台&#xff0c;万亿级调度经验积累&#xff01;面向中小企业大数据分析场景。开源地址&#xff1a;https://github.com/NewLifeX/AntJob使用教程&#xff1a;https://www.yuque.com/smartstone/blood/antjob体…

c语言怎么让图形界面单独显示,「分享」C语言如何编写图形界面

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼贴吧内经常有人问C语言是不是只能用于字符终端界面开发&#xff0c;不能用于图形界面。大家也都有回答&#xff0c;需要其他的库。MFC&#xff0c;GTK&#xff0c;QT。本人近期刚用GTK库加上纯C写成了第一个LINUX实用程序。现在与大…

如何在 ASP.NET Core 中 自定义中间件

ASP.NET Core 是一个跨平台&#xff0c;开源的&#xff0c;轻量级&#xff0c;高性能 并且高度模块化的web框架&#xff0c;同时扩展性也是非常强&#xff0c;你可以在 request -> response 请求管道中安插各种中间件来根据自己的场景定制化&#xff0c;比如说&#xff1a;监…

ASP.NET Core Authentication and Authorization

最近把一个Asp .net core 2.0的项目迁移到Asp .net core 3.1&#xff0c;项目启动的时候直接报错:InvalidOperationException: Endpoint CoreAuthorization.Controllers.HomeController.Index (CoreAuthorization) contains authorization metadata, but a middleware was not …

android dialog 自定义布局,如何设置AlertDialog的自定义布局?

调用我的对话框:alertDialog showInfoDialog(message "$wrongPasscodeMessage\n$retryMessage")方法如下:fun FragmentActivity.showInfoDialog(message: String?): AlertDialog? {return try {val customLayout layoutInflater.inflate(R.layout.custom_layout…

android 打开谷歌导航,国内开启google位置记录功能/android版google maps 7+上,恢复位置记录功能在国内使用(需root)...

android版google 地图在 7以后的版本上&#xff0c;位置记录功能在国内不能用了&#xff0c;提示本功能不能在中国使用。至少对本人&#xff0c;“位置记录”功能是非常有用的功能&#xff0c;尤其是骑车出行时记录自己的路线。目前还没找到替代产品。之前一段时间内恢复回旧版…

程序员过关斩将--少年派登录安全的奇幻遐想

“据说&#xff0c;这篇也是快餐&#xff0c;完全符合年轻人口味说到登录&#xff0c;无人不知无人不晓。每一个有用户体系的相关系统都会有登录的入口&#xff0c;登录是为了确认操作人的正确性。说到登录安全&#xff0c;其实是一个很伟大的命题&#xff0c;不过常用的手段也…

C# 9 新特性 —— 增强的 foreach

C# 9 新特性 —— 增强的 foreachIntro在 C# 9 中增强了 foreach 的使用&#xff0c;使得一切对象都有 foreach 的可能我们来看一段代码&#xff0c;这里我们试图遍历一个 int 类型的值思考一下&#xff0c;我们可以怎么做使得上面的代码编译通过呢&#xff1f;迭代器模式迭代器…

android系统休眠发广播,Android - BroadcastReceiver

BroadcastReceiverBroadcastReceiver&#xff0c;广播接收者&#xff0c;用来接收系统和应用的广播&#xff0c;并做出相应的处理&#xff0c;如电量过低时提示用户充电等&#xff1b;BroadcastReceiver 是 Android 的四大组件之一&#xff0c;分为 普通广播、有序广播、粘性广…

开源·共享·创新|2020年中国.NET开发者大会圆满收官!

“疫情无限续费”的2020年&#xff0c;对于14亿中国人而言&#xff0c;是必须习惯口罩长在来脸上的一年&#xff1b;是各种线下聚会&#xff0c;被迫数次延期、滞后、云上举办的一年&#xff1b;……而对于潜心修行&#xff0c;静蓄能量的中国.NET开发者而言&#xff0c;2020绝…

android+百度lbs云,百度——LBS.云 v2.0——云存储扩展字段——Android

今天要解决两个问题&#xff1a;1云存储扩展字段2上传的数据是乱码3android版本上传数据到云端使用了一段时间LBS云功能之后&#xff0c;随着对系统的熟悉&#xff0c;默认提供的字段&#xff0c;肯定无法满足需要。比如增加注释&#xff0c;价格&#xff0c;档次等字段的时候。…

年终将至,回顾我们一起走过的 2020

又到了年终末尾匆匆忙忙的 2020 似乎按下了倍速键一晃眼我们就从夏天走到了冬天在这不平凡的一年中我们同途共进也笑着成长让我们跟随着六大年度词条重温这一年我们共同经历的值得骄傲的瞬间吧&#xff01;点击文内高亮部分&#xff0c;阅读文章了解更多人才“倍”出星桥计划出…

灵魂拷问:你和大佬,技术差距有多大?

今天咱们聊点技术以外的内容。前几天&#xff0c;有程序员在某个坛子上发帖吐槽&#xff0c;新来的应届生张嘴就是分布式&#xff0c;一堆框架&#xff0c;可代码根本不会写。马上有人跟贴说自己也遇到过这种情况&#xff0c;说之前自己遇到过一个应届生&#xff0c;开口闭口动…

达梦数据查询编码_查询数据库的编码方式

在Mysql中(1)查看Mysql数据库编码show variables like character_set_database 或者 show create database 数据库名称(2)查看Mysql中某张表的编码show create table 表名show create database 数据库名称、show create table 表名 &#xff0c;还能够显示建库和建表语句。(3)…

玩转git-flow工作流-分支解析

概述搞开发的相信大部分人git天天都在用&#xff0c;那么一般我们在实际工程当中&#xff0c;遵循一个合理、清晰的Git使用流程&#xff0c;是非常重要的。否则&#xff0c;每个人都提交一堆杂乱无章的commit&#xff0c;项目很快就会变得难以协调和维护。那么是如何来规范整个…

android中的帧动画,[Android开发] Android中的帧动画

MainActivity文件&#xff1a;public class MainActivity extends Activity implements OnClickListener{AnimationDrawable anim_draw;SuppressLint("NewApi")Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);set…

ksu7对讲机调频软件_数字对讲机的群呼功能原理是什么?你了解多少?

大家都明白数字对讲机能够达到组呼、群呼、选呼的用途&#xff0c;但对数字对讲机的群呼功能原理可能操作方并不是太熟悉&#xff0c;下面我们就和大家来谈谈有关数字对讲机的群呼功能原理&#xff1a;无线对讲机群呼是为了更好地达到1个数字对讲机能够同一时间跟多个数字对讲机…