在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還是怎么調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM