美文网首页.Netcoreasp.net coreASP.NET Core见识录
AspDotNet+VueCli3+MVC共存模式开发

AspDotNet+VueCli3+MVC共存模式开发

作者: Angeladaddy | 来源:发表于2019-08-20 15:30 被阅读10次

    最近做项目时有一个需求,就是项目中要能够同时存在传统MVC页面和SPA页面,SPA本人比较熟悉Vue,就用VueCli3做。有关.NetCore项目中使用Vue,在我的另一篇文章AspDotNet+VueCli3从零开始有详细介绍。但是那篇文章的做法无法满足今天的需求:

    1. MVC页面和SPA页面单独路由控制,如/admin即定向到spa页面。//home则定向到home view
    2. 从spa页面发起api请求后定向到/api路由下
    3. 使用.net core的HMR而不是webpack的,两者功能重合。开发时编译两遍,速度很慢。

    工程需求

    • 要有一个Home界面,此界面为MVC,是网站的默认界面,从此界面可以导航到网站其它界面。
    • 一个admin spa项目,放置在工程目录下单独的admin文件夹下
    • 使Vue Cli3构建。

    实现步骤

    1. 建立工程
    #创建dotnet api工程
    dotnet new webapi -o dotnet_mvc_spa_demo
    cd dotnet_mvc_spa_demo
    #根据需要自行选择模板
    vue create admin
    cd admin
    # 这两个包是我们实现功能的关键,必须要安装
    yarn add aspnet-webpack webpack-hot-middleware --dev
    

    安装完毕后工程目录如下:

    .
    ├── Program.cs
    ├── Properties
    │   └── launchSettings.json
    ├── Startup.cs
    ├── admin
    │   ├── README.md
    │   ├── babel.config.js
    │   ├── node_modules
    │   ├── package.json
    │   ├── public
    │   ├── src
    │   ├── vue.config.js
    │   └── yarn.lock
    ├── appsettings.Development.json
    ├── appsettings.json
    ├── dotnet_mvc_spa_demo.csproj
    ├── dotnet_mvc_spa_demo.csproj.user
    ├── dotnet_mvc_spa_demo.sln
    
    

    工程设置

    1. 在admin目录下建立vue.config.js文件:
    module.exports = {
        //将webpack打包后的输出设置为工程根目录下的wwwroot/admin文件夹下
        outputDir: '../wwwroot/admin',
        //注意这里很重要,这样才能实现url隔离,即访问admin定位到spa
        baseUrl: "/admin",
        chainWebpack: config => {
            //不使用weboack的HMR功能
            config.plugins.delete('hmr');
        }
    }
    
    1. 修改Startup.js文件
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Rewrite;
    using Microsoft.AspNetCore.SpaServices.Webpack;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using System.IO;
    
    namespace dotnet_mvc_spa_demo
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    //使用.net的hmr功能,需要指定node_module位置
                    app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
                    {
                        HotModuleReplacement = true,
                        ProjectPath= Path.Combine(env.ContentRootPath,  "admin"),
                        ConfigFile = Path.Combine(env.ContentRootPath, @"admin\node_modules\@vue\cli-service\webpack.config.js")
                    });
                }
     
                app.UseStaticFiles();
                // 如果路径匹配到admin,则使用AdminController
                app.MapWhen(x => x.Request.Path.Value.StartsWith("/admin"), builder =>
                {
                    builder.UseMvc(routes =>
                    {
                        routes.MapSpaFallbackRoute(
                            name: "spa-fallback-admin",
                            defaults: new { controller = "Admin", action = "Index" });
                    });
                });
                // 将"/"重定向到“/home”
                app.UseRewriter(new RewriteOptions().AddRewrite("/", "/Home", true));
    
                //其余走默认的路由
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }
    

    新建Controllers

    ├── Controllers
    │   ├── AdminController.cs
    │   ├── HomeController.cs
    

    HomeController.cs就是正常的MVC:

        public class HomeController : Controller
        {
            public IActionResult Index()
            {
                return View();
            }
        }
    

    既然有Controller就需要有View,新建Views/Home文件夹:

    ./Views/
    └── Home
        └── Index.cshtml
    

    Index.cshtml中,我们使用一个超链接到/admin

    
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
    </head>
    <body>
        <h1>this is home page</h1>
        <p><a href="/admin">to admin spa</a></p>
    </body>
    </html>
    
    

    AdminController.cs,只是简单的读取了wwwroot/admin文件夹下的index.html文件,这个文件是webpack打包自动生成的,不用管。

        public class AdminController : Controller
        {
            public IActionResult Index()
            {
                return File("~/admin/index.html", "text/html");
            }
        }
    
    

    在项目根目录下新建wwwroot文件夹

    按下F5进行测试,


    image.png
    image.png

    这样就齐活了。
    感觉这种方法比上一篇文章中介绍的方法更加灵活。开发起来也更加顺畅。

    相关文章

      网友评论

        本文标题:AspDotNet+VueCli3+MVC共存模式开发

        本文链接:https://www.haomeiwen.com/subject/uvdpsctx.html