• 在ASP.NET MVC项目中使用React


    (此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注。)

    题记:最近在开发钉钉的微应用,考虑到性能和UI库的支持,遂采用了React来开发前端。

    目前我的项目是基于ABP框架的ASP.NET MVC/WEB API作为后端,AngularJS作为前端。但是发现钉钉官方的UI(SaltUI)是基于React封装的,另外AmazeUI的Touch版本也是React封装,也考虑到React性能更优,同时移动端网页的前端业务逻辑不会太复杂,就打算使用React来开发钉钉微应用页面。

    ReactJS.NET介绍

    要在ASP.NET MVC中集成React最简单的方式就是使用ReactJS.NET(http://reactjs.net/)。它提供了如下几个特性:

    1,即时编译JSX文件为JS:在HTML中直接引用JSX文件,ReactJS.NET会自动把其编译为JS并缓存在服务端。这种方式特别适合开发过程。如:

    bundles.Add(new JsxBundle("~/bundles/main").Include(
        // Add your JSX files here
        "~/Scripts/HelloWorld.jsx",
        "~/Scripts/AnythingElse.jsx",
        // You can include regular JavaScript files in the bundle too
        "~/Scripts/ajax.js",
    ));
    <!-- Reference it from HTML -->
    <script src="@Url.Content("~/Scripts/HelloWorld.jsx")"></script>

    2,通过流行的压缩和合并工具把JSX编译为JS:可以使用Cassette(http://getcassette.net/)或者ASP.NET内置的压缩合并特性,也可以集成Webpack或Browserify。如:

    // In BundleConfig.cs
    bundles.Add(new BabelBundle("~/bundles/main").Include(
        // Add your JSX files here
        "~/Scripts/HelloWorld.jsx",
        "~/Scripts/AnythingElse.jsx",
        // You can include regular JavaScript files in the bundle too
        "~/Scripts/ajax.js",
    ));
    <!-- In your view -->
    @Scripts.Render("~/bundles/main")

    3,可以实现服务端组件渲染:可以利用访问点组件渲染来加快初始页面的加载。如:

    <!-- This will render the component server-side -->
    @Html.React("CommentsBox", new {
        initialComments = Model.Comments
    })   <!-- Initialise the component in JavaScript too -->
    <script src="https://fb.me/react-15.0.1.js"></script>
    <script src="https://fb.me/react-dom-15.0.1.js"></script>
    @Scripts.Render("~/bundles/main")
    @Html.ReactInitJavaScript()

    ReactJS.NET安装和使用

    要安装也很容易,根据你项目ASP.NET版本不同有所不同:

    1,对于ASP.NET MVC 4 and 5,Install-Package React.Web.Mvc4

    2,对于ASP.NET Core,Install-Package React.AspNet

    3,对于ASP.NET MVC 3,Install-Package React.Web.Mvc3

    4,如果要使用Cassette,还要Install-Package Cassette.React

    5,如果要使用ASP.NET Bundling and Minification,还要Install-Package System.Web.Optimization.React

    详细的使用方法可以浏览ReactJS.NET的教程:http://reactjs.net/getting-started/tutorial.html

    我的技术选择和集成方式

    我的项目使用的是React.Web.Mvc4,没有使用即时编译直接就利用System.Web.Optimization.React来和内置ASP.NET压缩合并功能集成(因为项目其他部分就用的这个),没有使用服务端渲染(因为服务端渲染需要在ReactConfig.cs文件中逐一添加jsx文件,我有空可能会pr一个添加jsx文件夹的commit,那样会方便一些)。我的大致步骤如下:

    1,注册一些Bundle,来包含React的js、UI的js和自己应用的jsx,如下:

    //common js libs
    bundles.Add(new ScriptBundle("~/Bundles/MobileApp/libs/js")
        .Include(
            ScriptPaths.JQuery,
            ScriptPaths.Showdown,
            ScriptPaths.React_Addons,
            ScriptPaths.React_Dom,
            ScriptPaths.Abp,
            ScriptPaths.Abp_JQuery
        )
        .ForceOrdered()
        );
      //ui js libs
    bundles.Add(new ScriptBundle("~/Bundles/MobileApp/libs/SaltUI", ScriptPaths.Cdn.SaltUI)
        .Include(ScriptPaths.SaltUI)
        .ForceOrdered());
      bundles.Add(new ScriptBundle("~/Bundles/MobileApp/libs/Dingtalk", ScriptPaths.Cdn.Dingtalk)
       .Include(ScriptPaths.Dingtalk)
       .ForceOrdered());
      //ui css
    bundles.Add(new StyleBundle("~/Bundles/MobileApp/css/SaltUI", StylePaths.Cdn.SaltUI)
        .Include(StylePaths.SaltUI)
        .ForceOrdered());
      //app js
    bundles.Add(new BabelBundle("~/Bundles/MobileApp/app/DingtalkBI")
        .IncludeDirectory("~/MobileApp/DingtalkBI", "*.jsx", true)
        //.Include("~/MobileApp/App.jsx")
        .ForceOrdered()
        );

    其中,我在app js部分,通过BabelBundle来实现合并过程进行jsx编译,且我只是包含了jsx的目录,这个目录中只需要入口组件和依赖组件,无需app.jsx这样的文件。

    2,添加一个专用的Controller,在Action中返回相应的View并传递封装了所有props内容的ViewModel,如下:

    var vm = new ReactPropsViewModel
    {
        Props1 = false,
        Props2 = "hello"
    };
      return View(vm)

    3,在视图文件中引用相关的Bundle,并初始化React入口组件,如下:

    @model ReactPropsViewModel
    @{
        var camelCaseFormatter = new JsonSerializerSettings();
        camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }   <!DOCTYPE html>
      <html>
    <head>
        <meta charset="utf-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta content="width=device-width, initial-scale=1" name="viewport" />
        <meta content="" name="description" />
        <meta content="" name="author" />
      <link rel="shortcut icon" href="~/favicon.ico" />
      <title>ASP.NET MVC and React</title>
      @Styles.Render("~/Bundles/MobileApp/css/SaltUI")
    </head>
    <body>
        <div id="app"></div>
        @Scripts.Render("~/Bundles/MobileApp/libs/js")
        @Scripts.Render("~/Bundles/MobileApp/libs/SaltUI")
        @Scripts.Render("~/Bundles/MobileApp/libs/Dingtalk")
        @Scripts.Render("~/Bundles/MobileApp/app/DingtalkBI")   <script type="text/javascript">
            ReactDOM.render(
                React.createElement(Home, @Html.Raw(JsonConvert.SerializeObject(Model, camelCaseFormatter))),
                document.getElementById('app')
            );
        </script>
    </body>
    </html>

    至此,React就可以完美的和ASP.NET MVC融合在一起了。之前在前端如何调用后端的api,现在在React还是怎么调用。

  • 相关阅读:
    【Codeforces】Codeforces Round #680 Div2
    PS1 长命令回到行首进行覆盖
    vue 跟路径加载缺少跟前缀
    Mac OS Virtualbox 倒入 ova 镜像文件
    笔记本电脑扩展屏幕或设备后不能播放声音
    git clone 后使用子分支
    laravel 环境自编译过程
    virtual Box centos7 公司网络环境下不能联网的解决方案
    CentOS7 php7 安装 curl 扩展
    CentOS 7 安装 Nodejs npm 及版本冲突解决
  • 原文地址:https://www.cnblogs.com/redmoon/p/5810252.html
Copyright © 2020-2023  润新知