Skip to content

Commit 3f1502b

Browse files
committed
Merge branch 'working' into css
2 parents 9889765 + d29400c commit 3f1502b

15 files changed

+1375
-2
lines changed

ru/data.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export default context => {
138138
// заполнено состоянием, необходимым для рендеринга приложения.
139139
// Когда мы присоединяем состояние к контексту, и есть опция `template`
140140
// используемая для рендерера, состояние будет автоматически
141-
// сериализовано и внедрено в HTML как window.__INITIAL_STATE__.
141+
// сериализовано и внедрено в HTML как `window.__INITIAL_STATE__`.
142142
context.state = store.state
143143

144144
resolve(app)
@@ -215,7 +215,7 @@ if (window.__INITIAL_STATE__) {
215215

216216
2. **Загружать данные после отображения нового представления:**
217217

218-
Эта стратегия располагает логику загрузки данных на стороне клиента в функции компонента `beforeMount`. Это позволяет переключаться мгновенно при срабатывании навигации по маршруту, поэтому приложение ощущается более отзывчивым. Однако на момент отображения нового представления у него не будет полных данных. Поэтому необходимо иметь добавлять условие проверки загруженности состояния для каждого компонента, использующего эту стратегию.
218+
Эта стратегия располагает логику загрузки данных на стороне клиента в функции компонента `beforeMount`. Это позволяет переключаться мгновенно при срабатывании навигации по маршруту, поэтому приложение ощущается более отзывчивым. Однако на момент отображения нового представления у него не будет полных данных. Поэтому необходимо добавлять условие проверки загруженности состояния для каждого компонента, использующего эту стратегию.
219219

220220
Этого можно достичь с помощью глобальной примеси на клиенте:
221221

zh/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Vue.js 服务器端渲染指南
2+
3+
> **注意:**本指南需要最低为如下版本的 Vue,以及以下 library 支持:
4+
> - vue & vue-server-renderer >= 2.3.0
5+
> - vue-router >= 2.5.0
6+
> - vue-loader >= 12.0.0 & vue-style-loader >= 3.0.0如果先前已经使用过 Vue 2.2 的服务器端渲染(SSR),您应该注意到,推荐的代码结构现在[略有不同](./structure.md)(使用新的 [runInNewContext](./api.md#runinnewcontext) 选项,并设置为 `false`)。现有的应用程序可以继续运行,但建议您迁移到新的推荐规范。
7+
8+
## 什么是服务器端渲染(SSR)?
9+
10+
Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序。
11+
12+
服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器****客户端上运行。
13+
14+
## 为什么使用服务器端渲染(SSR)?
15+
16+
与传统 SPA(Single-Page Application - 单页应用程序)相比,服务器端渲染(SSR)的优势主要在于:
17+
18+
- 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。
19+
20+
请注意,截至目前,Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引。在这里,同步是关键。如果您的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。
21+
22+
- 更快的内容到达时间(time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。无需等待所有的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,所以你的用户将会更快速地看到完整渲染的页面。通常可以产生更好的用户体验,并且对于那些「内容到达时间(time-to-content)与转化率直接相关」的应用程序而言,服务器端渲染(SSR)至关重要。
23+
24+
使用服务器端渲染(SSR)时还需要有一些权衡之处:
25+
26+
- 开发条件所限。浏览器特定的代码,只能在某些生命周期钩子函数(lifecycle hook)中使用;一些外部扩展库(external library)可能需要特殊处理,才能在服务器渲染应用程序中运行。
27+
- 涉及构建设置和部署的更多要求。与可以部署在任何静态文件服务器上的完全静态单页面应用程序(SPA)不同,服务器渲染应用程序,需要处于 Node.js server 运行环境。
28+
- 更多的服务器端负载。在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源(CPU-intensive - CPU 密集),因此如果您预料在高流量环境(high traffic)下使用,请准备相应的服务器负载,并明智地采用缓存策略。
29+
30+
在对您的应用程序使用服务器端渲染(SSR)之前,您应该问第一个问题是否真的需要它。这主要取决于内容到达时间(time-to-content)对应用程序的重要程度。例如,如果您正在构建一个内部仪表盘,初始加载时的额外几百毫秒并不重要,这种情况下去使用服务器端渲染(SSR)将是一个小题大作之举。然而,内容到达时间(time-to-content)要求是绝对关键的指标,在这种情况下,服务器端渲染(SSR)可以帮助您实现最佳的初始加载性能。
31+
32+
## 服务器端渲染 vs 预渲染(SSR vs Prerendering)
33+
34+
如果您调研服务器端渲染(SSR)只是用来改善少数营销页面(例如 `/`, `/about`, `/contact` 等)的 SEO,那么您可能需要**预渲染**。无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时(build time)简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将您的前端作为一个完全静态的站点。
35+
36+
如果您使用 webpack,您可以使用 [prerender-spa-plugin](https://github.com/chrisvfritz/prerender-spa-plugin) 轻松地添加预渲染。它已经被 Vue 应用程序广泛测试 - 事实上,[作者](https://github.com/chrisvfritz)是 Vue 核心团队的成员。
37+
38+
## 关于此指南
39+
40+
本指南专注于,使用 Node.js server 的服务器端单页面应用程序渲染。将 Vue 服务器端渲染(SSR)与其他后端设置进行混合使用,是其它后端自身的一个主题,本指南不包括在内。
41+
42+
本指南将会非常深入,并且假设您已经熟悉 Vue.js 本身,并且具有 Node.js 和 webpack 的相当不错的应用经验。如果您具有更高级解决方案,可以提供一个平缓的开箱即用体验,您应该去尝试使用 [Nuxt.js](http://nuxtjs.org/)。它建立在同等的 Vue 技术栈之上,但抽象出很多模板,并提供了一些额外的功能,例如静态站点生成。但是,如果您需要更直接地控制应用程序的结构,Nuxt.js 并不适合这种使用场景。无论如何,阅读本指南将更有助于更好地了解一切如何运行。
43+
44+
当您阅读时,参考官方 [HackerNews Demo](https://github.com/vuejs/vue-hackernews-2.0/) 将会有所帮助,此示例使用了本指南涵盖的大部分技术。
45+
46+
最后,请注意,本指南中的解决方案不是限定的 - 我们发现它们对我们来说很好,但这并不意味着无法继续改进。可能会在未来持续改进,欢迎通过随意提交 pull request 作出贡献!

zh/SUMMARY.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
- [基本用法](basic.md)
2+
- [编写通用代码](universal.md)
3+
- [源码结构](structure.md)
4+
- [路由和代码分割](routing.md)
5+
- [数据预取和状态](data.md)
6+
- [客户端混合](hydration.md)
7+
- [Bundle Renderer 指引](bundle-renderer.md)
8+
- [构建配置](build-config.md)
9+
- [CSS 管理](css.md)
10+
- [Head 管理](head.md)
11+
- [缓存](caching.md)
12+
- [流式渲染](streaming.md)
13+
- [API 参考](api.md)
14+
- [createRenderer](api.md#createrendereroptions)
15+
- [createBundleRenderer](api.md#createbundlerendererbundle-options)
16+
- [Class: Renderer](api.md#class-renderer)
17+
- [Class: BundleRenderer](api.md#class-bundlerenderer)
18+
- [Renderer 选项](api.md#renderer-options)
19+
- [template](api.md#template)
20+
- [clientManifest](api.md#clientmanifest)
21+
- [inject](api.md#inject)
22+
- [shouldPreload](api.md#shouldpreload)
23+
- [runInNewContext](api.md#runinnewcontext)
24+
- [basedir](api.md#basedir)
25+
- [cache](api.md#cache)
26+
- [directives](api.md#directives)
27+
- [webpack 插件](api.md#webpack-plugins)

zh/basic.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# 基本用法
2+
3+
## 安装
4+
5+
```bash
6+
npm install vue vue-server-renderer --save
7+
```
8+
9+
我们将在整个指南中使用 NPM,但是还可以随意使用 [Yarn](https://yarnpkg.com/en/)
10+
11+
#### 注意
12+
13+
- 推荐使用 Node.js 版本 6+。
14+
- `vue-server-renderer``vue` 必须匹配版本。
15+
- `vue-server-renderer` 依赖一些 Node.js 原生模块,因此只能在 Node.js 中使用。我们可能会提供一个更简单的构建,可以在将来在其他「JavaScript 运行时(runtime)」运行。
16+
17+
## 渲染一个 Vue 实例
18+
19+
```js
20+
// 第 1 步:创建一个 Vue 实例
21+
const Vue = require('vue')
22+
const app = new Vue({
23+
template: `<div>Hello World</div>`
24+
})
25+
// 第 2 步:创建一个 renderer
26+
const renderer = require('vue-server-renderer').createRenderer()
27+
// 第 3 步:将 Vue 实例渲染为 HTML
28+
renderer.renderToString(app, (err, html) => {
29+
if (err) throw err
30+
console.log(html)
31+
// => <div data-server-rendered="true">Hello World</div>
32+
})
33+
```
34+
35+
## 与服务器集成
36+
37+
在 Node.js 服务器中使用时相当简单直接,例如 [Express](https://expressjs.com/)
38+
39+
```bash
40+
npm install express --save
41+
```
42+
43+
---
44+
45+
```js
46+
const Vue = require('vue')
47+
const server = require('express')()
48+
const renderer = require('vue-server-renderer').createRenderer()
49+
server.get('*', (req, res) => {
50+
const app = new Vue({
51+
data: {
52+
url: req.url
53+
},
54+
template: `<div>访问的 URL 是: {{ url }}</div>`
55+
})
56+
renderer.renderToString(app, (err, html) => {
57+
if (err) {
58+
res.status(500).end('Internal Server Error')
59+
return
60+
}
61+
res.end(`
62+
<!DOCTYPE html>
63+
<html lang="en">
64+
<head><title>Hello</title></head>
65+
<body>${html}</body>
66+
</html>
67+
`)
68+
})
69+
})
70+
server.listen(8080)
71+
```
72+
73+
## 使用一个页面模板
74+
75+
当你在渲染 Vue 应用程序时,renderer 只从应用程序生成 HTML 标记(markup)。在这个示例中,我们必须用一个额外的 HTML 页面包裹容器,来包裹生成的 HTML 标记。
76+
77+
为了简化这些,你可以直接在创建 renderer 时提供一个页面模板。多数时候,我们会将页面模板放在特有的文件中,例如 `index.template.html`
78+
79+
```html
80+
<!DOCTYPE html>
81+
<html lang="en">
82+
<head><title>Hello</title></head>
83+
<body>
84+
<!--vue-ssr-outlet-->
85+
</body>
86+
</html>
87+
```
88+
89+
注意 `<!--vue-ssr-outlet-->` 注释 -- 这里将是应用程序 HTML 标记注入的地方。
90+
91+
然后,我们可以读取和传输文件到 Vue renderer 中:
92+
93+
```js
94+
const renderer = createRenderer({
95+
template: require('fs').readFileSync('./index.template.html', 'utf-8')
96+
})
97+
renderer.renderToString(app, (err, html) => {
98+
console.log(html) // will be the full page with app content injected.
99+
})
100+
```
101+
102+
### 模板插值
103+
104+
模板还支持简单插值。给定如下模板:
105+
106+
```html
107+
<html>
108+
<head>
109+
<!-- 使用双花括号(double-mustache)进行 HTML 转义插值(HTML-escaped interpolation) -->
110+
<title>{{ title }}</title>
111+
<!-- 使用三花括号(triple-mustache)进行 HTML 不转义插值(non-HTML-escaped interpolation) -->
112+
{{{ meta }}}
113+
</head>
114+
<body>
115+
<!--vue-ssr-outlet-->
116+
</body>
117+
</html>
118+
```
119+
120+
我们可以通过传入一个"渲染上下文对象",作为 `renderToString` 函数的第二个参数,来提供插值数据:
121+
122+
```js
123+
const context = {
124+
title: 'hello',
125+
meta: `
126+
<meta ...>
127+
<meta ...>
128+
`
129+
}
130+
renderer.renderToString(app, context, (err, html) => {
131+
// page title will be "Hello"
132+
// with meta tags injected
133+
})
134+
```
135+
136+
也可以与 Vue 应用程序实例共享 `context` 对象,允许模板插值中的组件动态地注册数据。
137+
138+
此外,模板支持一些高级特性,例如:
139+
140+
- 在使用 `*.vue` 组件时,自动注入「关键的 CSS(critical CSS)」;
141+
- 在使用 `clientManifest` 时,自动注入「资源链接(asset links)和资源预加载提示(resource hints)」;
142+
- 在嵌入 Vuex 状态进行客户端融合(client-side hydration)时,自动注入以及 XSS 防御。
143+
144+
在之后的指南中介绍相关概念时,我们将详细讨论这些。

0 commit comments

Comments
 (0)