Vue.js与 ASP.NET Core 服务端渲染功能整合
http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/
原作者:Mihály Gyöngyösi
译者:oopsguy.com
我真的很喜欢在前端使用 Vue.js,Vue 服务端渲染直到第二个版本才被支持。 在本例中,我想展示如何将 Vue.js
服务端渲染功能整合 ASP.NET Core。 我们在服务端使用了 Microsoft.AspNetCore.SpaServices
包,该包提供 ASP.NET Core API,以便于我们可以使用上下文信息调用 Node.js 托管的 JavaScript 代码,并将生成的
HTML 字符串注入渲染页面。
在此示例中,应用程序将展示一个消息列表,服务端只渲染最后两条消息(按日期排序)。可以通过点击“获取消息”按钮从服务端下载剩余的消息。
项目结构如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
. ├── VuejsSSRSample | ├── Properties | ├── References | ├── wwwroot | └── Dependencies ├── Controllers | └── HomeController.cs ├── Models | ├── ClientState.cs | ├── FakeMessageStore.cs | └── Message.cs ├── Views | ├── Home | | └── Index.cshtml | └── _ViewImports.cshtml ├── VueApp | ├── components | | ├── App.vue | | └── Message.vue | ├── vuex | | ├── actions.js | | └── store.js | ├── app.js | ├── client.js | ├── renderOnServer.js | └── server.js ├── .babelrc ├── appsettings.json ├── Dockerfile ├── packages.json ├── Program.cs ├── project.json ├── Startup.cs ├── web.config ├── webpack.client.config.js └── webpack.server.config.js |
正如你看到的,Vue 应用位于 VueApp 文件夹下,它有两个组件、一个包含了一个 mutation 和一个 action 的简单
Vuex store 和一些我们接下来要讨论的其他文件:app.js、client.js、
renderOnServer.js、server.js。
实现 Vue.js 服务端渲染
要使用服务端渲染,我们必须从 Vue 应用创建两个不同的 bundle:一个用于服务端(由 Node.js 运行),另一个用于将在浏览器中运行并在客户端上混合应用。
app.js
引导此模块中的 Vue 实例。它由两个 bundle 共同使用。
1
2
3
4
5
6
7
8
|
import Vue from 'vue' ; import App from './components/App.vue' ; import store from './vuex/store.js' ; const app = new Vue({ store, ...App }); export { app, store }; |
server.js
此服务端 bundle 的入口点导出一个函数,该函数有一个 context 属性,可用于从渲染调用中推送任何数据。
client.js
客户端 bundle 的入口点,其用一个名为 INITIAL_STATE 的全局 Javascript 对象(该对象将由预渲染模块创建)替换 store 的当前状态,并将应用挂载到指定的元素(.my-app)。
1
2
3
|
import { app, store } from './app' ; store.replaceState(__INITIAL_STATE__); app.$mount( '.my-app' ); |
Webpack 配置
为了创建 bundle,我们必须添加两个 Webpack 配置文件(一个用于服务端,一个用于客户端构建),不要忘了安装 Webpack,如果尚未安装,则:npm install -g webpack。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
webpack.server.config.js const path = require( 'path' ); module.exports = { target: 'node' , entry: path.join(__dirname, 'VueApp/server.js' ), output: { libraryTarget: 'commonjs2' , path: path.join(__dirname, 'wwwroot/dist' ), filename: 'bundle.server.js' , }, module: { loaders: [ { test: /\.vue$/, loader: 'vue' , }, { test: /\.js$/, loader: 'babel' , include: __dirname, exclude: /node_modules/ }, { test: /\.json?$/, loader: 'json' } ] }, }; webpack.client.config.js const path = require( 'path' ); module.exports = { entry: path.join(__dirname, 'VueApp/client.js' ), output: { path: path.join(__dirname, 'wwwroot/dist' ), filename: 'bundle.client.js' , }, module: { loaders: [ { test: /\.vue$/, loader: 'vue' , }, { test: /\.js$/, loader: 'babel' , include: __dirname, exclude: /node_modules/ }, ] }, }; |
运行 webpack --config webpack.server.config.js, 如果运行成功,则可以在
/wwwroot/dist/bundle.server.js 找到服端 bundle。获取客户端 bundle 请运行 webpack
--config webpack.client.config.js,相关输出可以在 /wwwroot/dist/bundle.client.js
中找到。
实现 Bundle Render
该模块将由 ASP.NET Core 执行,其负责:
渲染我们之前创建的服务端 bundle
将 **window.__ INITIAL_STATE__** 设置为从服务端发送的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
process.env.VUE_ENV = 'server' ; const fs = require( 'fs' ); const path = require( 'path' ); const filePath = path.join(__dirname, '../wwwroot/dist/bundle.server.js' ) const code = fs.readFileSync(filePath, 'utf8' ); const bundleRenderer = require( 'vue-server-renderer' ).createBundleRenderer(code) module.exports = function (params) { return new Promise( function (resolve, reject) { bundleRenderer.renderToString(params.data, (err, resultHtml) => { // params.data is the store's initial state. Sent by the asp-prerender-data attribute if (err) { reject(err.message); } resolve({ html: resultHtml, globals: { __INITIAL_STATE__: params.data // window.__INITIAL_STATE__ will be the initial state of the Vuex store } }); }); }); }; |
实现 ASP.NET Core 部分
如之前所述,我们使用了 Microsoft.AspNetCore.SpaServices 包,它提供了一些 TagHelper,可轻松调用
Node.js 托管的 Javascript(在后台,SpaServices 使用
Microsoft.AspNetCore.NodeServices 包来执行 Javascript)。
Views/_ViewImports.cshtml
为了使用 SpaServices 的 TagHelper,我们需要将它们添加到 _ViewImports 中。
1
2
3
4
5
6
7
8
9
10
11
|
@addTagHelper "*, Microsoft.AspNetCore.SpaServices" Home/Index public IActionResult Index() { var initialMessages = FakeMessageStore.FakeMessages.OrderByDescending(m => m.Date).Take(2); var initialValues = new ClientState() { Messages = initialMessages, LastFetchedMessageDate = initialMessages.Last().Date }; return View(initialValues); } |
它从 MessageStore(仅用于演示目的的一些静态数据)中获取两条最新的消息(按日期倒序排序),并创建一个 ClientState 对象,该对象将被用作 Vuex store 的初始状态。
Vuex store 默认状态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
const store = new Vuex.Store({ state: { messages: [], lastFetchedMessageDate: -1 }, // ... }); ClientState 类: public class ClientState { [JsonProperty(PropertyName = "messages" )] public IEnumerable<Message> Messages { get; set; } [JsonProperty(PropertyName = "lastFetchedMessageDate" )] public DateTime LastFetchedMessageDate { get; set; } } |
Index View
最后,我们有了初始状态(来自服务端)和 Vue 应用,所以只需一个步骤:使用 asp-prerender-module 和 asp-prerender-data TagHelper 在视图中渲染 Vue 应用的初始值。
1
2
3
4
5
6
7
|
@model VuejsSSRSample.Models.ClientState <!-- ... --> <body> <div class= "my-app" asp-prerender-module= "VueApp/renderOnServer" asp-prerender-data= "Model" ></div> <script src= "~/dist/bundle.client.js" asp-append-version= "true" ></script> </body> <!-- ... --> |
asp-prerender-module 属性用于指定要渲染的模块(在我们的例子中为 VueApp/renderOnServer)。我们可以使用 asp-prerender-data 属性指定一个将被序列化并发送到模块的默认函数作为参数的对象。
您可以从以下地址下载原文的示例代码:
http://github.com/mgyongyosi/VuejsSSRSample
总结
以上所述是小编给大家介绍的Vue.js与 ASP.NET Core 服务端渲染功能整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
原文链接:https://www.cnblogs.com/oopsguy/p/7837400.html
Vue.js与 ASP.NET Core 服务端渲染功能整合的更多相关文章
- 用prerender-spa-plugin插件Vue项目优化SEO做ssr服务端渲染及预渲染
今天在做公交的时候没干,用手机看看文章,偶然发现了一个关于Vue优化seo的文章,我先是在Vue的官方文档看了一篇关于Vue做SEO优化的文章. 上面提到了nuxt.js这个框架,这个框架我做过一个小 ...
- 基于vue的nuxt框架cnode社区服务端渲染
nuxt-cnode 基于vue的nuxt框架仿的cnode社区服务端渲染,主要是为了seo优化以及首屏加载速度 线上地址 http://nuxt-cnode.foreversnsd.cngithub ...
- ASP.NET Core 与 Vue.js 服务端渲染
http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/ 原作者:Mihály Gyöngyösi 译者:oop ...
- NET Core 与 Vue.js 服务端渲染
NET Core 与 Vue.js 服务端渲染 http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/原作者: ...
- 服务端渲染 数据驱动 不是渲染后的网页,而是一个由html和Javascript组成的app ssr 隐藏接口服务器
小结: 1. 服务端渲染主要的工作是把组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序. 服务器给到客户端的已经是 ...
- Headless Chrome:服务端渲染JS站点的一个方案【上篇】【翻译】
原文链接:https://developers.google.com/web/tools/puppeteer/articles/ssr 注:由于英文水平有限,没有逐字翻译,可以选择直接阅读原文 tip ...
- [Next] 服务端渲染知识补充
渲染 渲染:就是将数据和模版组装成 html 客户端渲染 客户端渲染模式下,服务端把渲染的静态文件给到客户端,客户端拿到服务端发送过来的文件自己跑一遍 js,根据 JS 运行结果,生成相应 DOM,然 ...
- 动态栅格(DEM)图层实现服务端渲染
PS:此处动态图层指,图层文件都放在经过注册的文件目录里,可以通过文件名动态加载图层 动态加载的矢量图层,可以实现客户端和服务端的定制渲染,但栅格一般是不能再渲染的,以下介绍可行的方法 建立一个很简单 ...
- Vue.js 服务端渲染业务入门实践
作者:威威(沪江前端开发工程师) 本文原创,转载请注明作者及出处. 背景 最近, 产品同学一如往常笑嘻嘻的递来需求文档, 纵使内心万般拒绝, 身体倒是很诚实. 接过需求,好在需求不复杂, 简单构思 后 ...
随机推荐
- 2-3 Sass的函数功能-列表函数
列表函数主要包括一些对列表参数的函数使用,主要包括以下几种: length($list):返回一个列表的长度值: nth($list, $n):返回一个列表中指定的某个标签值 join($list1, ...
- 项目经验:GIS<MapWinGIS>建模第四天
实现了查询,与定位功能
- Codeforces Round #413 A. Carrot Cakes
A. Carrot Cakes time limit per test 1 second memory limit per test 256 megabytes In some game ...
- java反射机制的简单介绍
参考博客: https://blog.csdn.net/mlc1218559742/article/details/52754310 先给出反射机制中常用的几个方法: Class.forName (& ...
- 第三次scrum作业!
1.小组成员 舒 溢 许嘉荣 唐 浩 黄欣欣 廖帅元 刘洋江 薛思汝 2.个人在小组第三次冲刺任务及其完成情况描述 根据小组讨论所分配任务,积极辅助组长以及各个成员,理清思路,编写代码,尽量在规定时间 ...
- 密码存储中MD5的安全问题与替代方案
md5安全吗?有多么地不安全?如何才能安全地存储密码?... md5安全吗? 经过各种安全事件后,很多系统在存放密码的时候不会直接存放明文密码了,大都改成了存放了 md5 加密(hash)后的密码,可 ...
- windows系统的错误码
https://blog.csdn.net/u011785544/article/details/51682290
- 新浪OAuth网络登录,请求access_token时遇到21323的错误
按照新浪给出的文档写了,但是遇到错误,总是获取不到token值,也是post方式提交的. 查阅百度资料,发现有网友给出了解决办法,是因为 文档中有这么一句提示: HTTP请求方式:POST 这句话太简 ...
- 根据操作系统进程号,查找sql语句
有时需要根据操作系统编号查找正在执行的sql语句:select sess.username,sql1.SQL_TEXTfrom v$session sess,v$sqltext sql1,v$proc ...
- jQuery解决高度统一问题
<div class="itemdl over"> <dl class="fl"> <dt><img src=&quo ...