docs: sync Chinese doc to 3.0.0-beta.28 (#509)
Just a suggestion: maybe a stable version of vue-apollo can be published after this wonderful ssr refactor?
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
- `skip`: Boolean disabling query fetching
|
||||
- `clientId`: id of the Apollo Client used by the query (defined in ApolloProvider `clients` option)
|
||||
- `deep`: Boolean to use deep Vue watchers
|
||||
- `tag`: String HTML tag name (default: `div`); if falsy (for example `null` or `undefined`), the component will be renderless (the content won't be wrapped in a tag). In this case, only the first child will be rendered.
|
||||
- `tag`: String HTML tag name (default: `div`); if falsy (for example `null` or `undefined`), the component will be renderless (the content won't be wrapped in a tag), in this case, only the first child will be rendered
|
||||
- `debounce`: Number of milliseconds for debouncing refetches (for example when the variables are changed)
|
||||
- `throttle`: Number of milliseconds for throttling refetches (for example when the variables are changed)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Each subscription declared in the `apollo.$subscribe` option in a component resu
|
||||
- `variables`: Object or reactive function that returns an object. Each key will be mapped with a `'$'` in the GraphQL document, for example `foo` will become `$foo`.
|
||||
- `throttle`: throttle variables updates (in ms).
|
||||
- `debounce`: debounce variables updates (in ms).
|
||||
- `result(data)` is a hook called when a result is received
|
||||
- `result(data, key)` is a hook called when a result is received
|
||||
|
||||
## Properties
|
||||
|
||||
|
||||
+1
-2
@@ -121,7 +121,7 @@ If `ssr` is false, we try to restore the state of the Apollo cache with `cache.r
|
||||
|
||||
Here is an example:
|
||||
|
||||
```js{21-31}
|
||||
```js{21-30}
|
||||
// apollo.js
|
||||
|
||||
import Vue from 'vue'
|
||||
@@ -144,7 +144,6 @@ export function createApolloClient (ssr = false) {
|
||||
|
||||
// If on the client, recover the injected state
|
||||
if (!ssr) {
|
||||
// If on the client, recover the injected state
|
||||
if (typeof window !== 'undefined') {
|
||||
const state = window.__APOLLO_STATE__
|
||||
if (state) {
|
||||
|
||||
@@ -152,7 +152,7 @@ const apolloProvider = new VueApollo({
|
||||
|
||||
// Use the provider
|
||||
new Vue({
|
||||
provide: apolloProvider.provide(),
|
||||
apolloProvider,
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
@@ -32,11 +32,11 @@ footer: LICENCE MIT - Created by Guillaume CHAU (@Akryum)
|
||||
### 铜牌赞助商
|
||||
|
||||
<p align="center">
|
||||
<a href="https://vuetifyjs.com" target="_blank" title="Vuetify">
|
||||
<img src="https://cdn.vuetifyjs.com/images/logos/v-alt.svg" width="48" height="48">
|
||||
<a href="https://vuetifyjs.com" target="_blank">
|
||||
<img src="https://cdn.discordapp.com/attachments/537832759985700914/537832771691872267/Horizontal_Logo_-_Dark.png" alt="Vuetify logo" class="bronze-sponsor">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
::: tip 当前版本
|
||||
中文文档现在同步至 v3.0.0-beta.26
|
||||
中文文档现在同步至 v3.0.0-beta.28
|
||||
:::
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
- `optimisticResponse`:详见 [乐观 UI](https://www.apollographql.com/docs/react/features/optimistic-ui.html)
|
||||
- `update`:详见 [变更后更新缓存](https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-mutation-options-update)
|
||||
- `refetchQueries`:详见 [变更后重新获取查询](https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-mutation-options-refetchQueries)
|
||||
- `clientId`:用于解析使用的 Apollo 客户端(在 ApolloProvider 中定义)
|
||||
- `clientId`:查询所使用的 Apollo 客户端 id(在 ApolloProvider 的 `clients` 选项中定义)
|
||||
- `tag`:字符串,HTML 标签名(默认值:`div`);如果是 `undefined`,该组件将成为无渲染组件(内容不会被包装在标签中)
|
||||
|
||||
## 作用域插槽 props
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
- `notifyOnNetworkStatusChange`:详见 [apollo notifyOnNetworkStatusChange](https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-notifyOnNetworkStatusChange)
|
||||
- `context`:详见 [apollo context](https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-context)
|
||||
- `skip`:布尔值,禁用查询获取
|
||||
- `clientId`:用于解析使用的 Apollo 客户端(在 ApolloProvider 中定义)
|
||||
- `clientId`:查询所使用的 Apollo 客户端 id(在 ApolloProvider 的 `clients` 选项中定义)
|
||||
- `deep`:布尔值,使用深度 Vue 侦听器
|
||||
- `tag`:字符串,HTML 标签名(默认值:`div`);如果是 `undefined`,该组件将成为无渲染组件(内容不会被包装在标签中)
|
||||
- `tag`:字符串,HTML 标签名(默认值:`div`);如果是假值(如 `null` 或 `undefined`),该组件将成为无渲染组件(内容不会被包装在标签中),在这种情况下,只有第一个子元素会被渲染
|
||||
- `debounce`:对重新获取查询结果的防抖毫秒数(例如当变量更改时)
|
||||
- `throttle`:对重新获取查询结果的节流毫秒数(例如当变量更改时)
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
- `vm`:关联的组件。
|
||||
- `queries`:组件的智能查询的数组。
|
||||
- `subscriptions`:组件的智能订阅的数组。
|
||||
- `client`:组件当前使用的 Apollo 客户端。
|
||||
- `provider`:注入的 [Apollo Provider](./apollo-provider.md)。
|
||||
- `loading`:是否至少有一个查询正在加载。
|
||||
- `skipAllQueries`:(setter) 布尔值,用于暂停或取消暂停所有智能查询。
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
- `debounce`:变量更新防抖时间(毫秒)。
|
||||
- `pollInterval`:使用轮询自动更新的时间(表示每隔 `x` 毫秒重新获取一次)。
|
||||
- `update(data) {return ...}` 用来自定义设置到 vue 属性中的值,例如当字段名称不匹配时。
|
||||
- `result(ApolloQueryResult)` 是收到结果时调用的钩子(更多参见 [ApolloQueryResult](https://github.com/apollographql/apollo-client/blob/master/packages/apollo-client/src/core/types.ts) 的文档)。
|
||||
- `result(ApolloQueryResult, key)` 是收到结果时调用的钩子(更多参见 [ApolloQueryResult](https://github.com/apollographql/apollo-client/blob/master/packages/apollo-client/src/core/types.ts) 的文档)。`key` 是在 `apollo` 选项中定义此查询时使用的键名。
|
||||
- `error(error)` 是有错误时调用的钩子。`error` 是一个具有 `graphQLErrors` 属性或 `networkError` 属性的 Apollo 错误对象。
|
||||
- `loadingKey` 将更新你传递的值所对应的组件数据属性。你应该在组件的 `data()` 钩子中将此属性初始化为 `0` 。当查询正在加载时,此属性将增加 1;当不再加载时,它将减去 1。这样,该属性可以表示当前正在加载中的查询的计数器。
|
||||
- `watchLoading(isLoading, countModifier)` 是一个在查询的加载状态发生变化时调用的钩子。`countModifier` 参数当查询正在加载时等于 `1`,不再加载时为 `-1`。
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
- `variables`:对象或返回对象的响应式函数。每个键将用 `'$'` 映射到 GraphQL 文档中,例如 `foo` 将变为 `$foo`。
|
||||
- `throttle`:变量更新节流时间(毫秒)。
|
||||
- `debounce`:变量更新防抖时间(毫秒)。
|
||||
- `result(data)` 是收到结果时调用的钩子。
|
||||
- `result(data, key)` 是收到结果时调用的钩子。
|
||||
|
||||
## 属性
|
||||
|
||||
|
||||
@@ -6,45 +6,6 @@
|
||||
|
||||
## 方法
|
||||
|
||||
### install
|
||||
|
||||
仅在服务端安装 SSR 插件:
|
||||
|
||||
```js
|
||||
Vue.use(ApolloSSR)
|
||||
```
|
||||
|
||||
你可以像这样传递附加选项:
|
||||
|
||||
```js
|
||||
Vue.use(ApolloSSR, {
|
||||
fetchPolicy: 'network-only',
|
||||
suppressRenderErrors: false,
|
||||
})
|
||||
```
|
||||
|
||||
#### fetchPolicy
|
||||
|
||||
当预取一个 Apollo 查询时,建议覆盖 `fetchPolicy` 以强制查询发送。
|
||||
|
||||
默认值:`'network-only'`。
|
||||
|
||||
#### suppressRenderErrors
|
||||
|
||||
隐藏虚假渲染时的错误。
|
||||
|
||||
默认值:`false`。
|
||||
|
||||
### prefetchAll
|
||||
|
||||
预取所有队列中的组件定义,并在所有对应的 apollo 数据准备就绪时返回已解决的(resolved) promise。
|
||||
|
||||
```js
|
||||
await ApolloSSR.prefetchAll (apolloProvider, componentDefs, context)
|
||||
```
|
||||
|
||||
`context` 作为参数传递给智能查询中的 `prefetch` 选项。它可能包含路由和 store。
|
||||
|
||||
### getStates
|
||||
|
||||
将 apollo store 状态作为 JavaScript 对象返回。
|
||||
@@ -82,40 +43,3 @@ const js = ApolloSSR.exportStates(apolloProvider, options)
|
||||
exportNamespace: '',
|
||||
}
|
||||
```
|
||||
|
||||
### globalPrefetch
|
||||
|
||||
允许你注册一个需要显式预取的组件。
|
||||
|
||||
简单示例如下:
|
||||
|
||||
```js
|
||||
import MyComponent from '@/components/MyComponent.vue'
|
||||
|
||||
ApolloSSR.globalPrefetch(() => MyComponent)
|
||||
```
|
||||
|
||||
你可以根据上下文禁用预取:
|
||||
|
||||
```js
|
||||
ApolloSSR.globalPrefetch(context => {
|
||||
if (context.route.name === 'foo'){
|
||||
return MyComponent
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### mockInstance
|
||||
|
||||
在 `prefetchAll` 期间,应用程序组件树将使用虚假实例重新创建以使进程更快。如果你在模板或渲染函数中访问了像 `this.$http` 这样的辅助函数(通常为 `Undefined error`),你可以通过插件来修改虚假实例,以防止它们的渲染函数崩溃。建议 mock 这些辅助函数以提高性能。
|
||||
|
||||
```js
|
||||
const noop = () => {}
|
||||
|
||||
ApolloSSR.mockInstance({
|
||||
apply: vm => {
|
||||
// Mock $http
|
||||
vm.$http = noop
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
### 铜牌赞助商
|
||||
|
||||
<p align="center">
|
||||
<a href="https://vuetifyjs.com" target="_blank" title="Vuetify">
|
||||
<img src="https://cdn.vuetifyjs.com/images/logos/v-alt.svg" width="48" height="48">
|
||||
<a href="https://vuetifyjs.com" target="_blank">
|
||||
<img src="https://cdn.discordapp.com/attachments/537832759985700914/537832771691872267/Horizontal_Logo_-_Dark.png" alt="Vuetify logo" class="bronze-sponsor">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -36,5 +36,6 @@ export default {
|
||||
|
||||
- [示例项目](https://codesandbox.io/s/zqqj82396p) (by @chriswingler)
|
||||
- [Todo App](https://codesandbox.io/s/x2jr96r8pp) (by @NikkitaFTW)
|
||||
- [Todo App - 扩展](https://codesandbox.io/s/k3621oko23) (by @ScottMolinari fork of @NikkitaFTW's)
|
||||
|
||||
---
|
||||
|
||||
+99
-146
@@ -1,5 +1,9 @@
|
||||
# 服务端渲染
|
||||
|
||||
::: warning
|
||||
**需要 Vue 2.6+ 对 `serverPrefetch` 的支持**
|
||||
:::
|
||||
|
||||
## Vue CLI 插件
|
||||
|
||||
我为 [vue-cli](http://cli.vuejs.org) 制作了一个插件,因此仅用两分钟你就可以将你的 vue-apollo 应用转换为同构 SSR 应用!✨🚀
|
||||
@@ -12,17 +16,16 @@ vue add @akryum/ssr
|
||||
|
||||
[更多信息](https://github.com/Akryum/vue-cli-plugin-ssr)
|
||||
|
||||
## 预取组件
|
||||
## 组件的预取
|
||||
|
||||
在要在服务端预取的查询上,添加 `prefetch` 选项。它可以是:
|
||||
- 一个变量对象;
|
||||
- 一个获取上下文对象(例如可以包含 URL)并返回一个变量对象的函数;
|
||||
- `false` 禁用此查询的预取。
|
||||
::: tip
|
||||
按照 [官方 SSR 指南](https://ssr.vuejs.org) 了解有关 Vue 服务端渲染的更多信息。
|
||||
:::
|
||||
|
||||
如果你在 `prefetch` 选项中返回一个变量对象,请确保它与 `variables` 选项的结果相匹配。如果它们不匹配,则在服务端渲染模板时,查询的数据属性将不会被填充。
|
||||
在使用了 `vue-server-renderer` 的默认情况下,服务端渲染的组件中的所有 GraphQL 查询都将被自动预取。
|
||||
|
||||
::: danger
|
||||
在服务端进行预取时,你无法访问组件实例。
|
||||
::: tip
|
||||
即使在服务端,你也能够在诸如 `variables` 等选项中使用 `this`!
|
||||
:::
|
||||
|
||||
示例:
|
||||
@@ -31,7 +34,6 @@ vue add @akryum/ssr
|
||||
export default {
|
||||
apollo: {
|
||||
allPosts: {
|
||||
// 此查询将被预取
|
||||
query: gql`query AllPosts {
|
||||
allPosts {
|
||||
id
|
||||
@@ -39,7 +41,6 @@ export default {
|
||||
description
|
||||
}
|
||||
}`,
|
||||
prefetch: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,11 +59,6 @@ export default {
|
||||
description
|
||||
}
|
||||
}`,
|
||||
prefetch: ({ route }) => {
|
||||
return {
|
||||
id: route.params.id,
|
||||
}
|
||||
},
|
||||
variables () {
|
||||
return {
|
||||
id: this.id,
|
||||
@@ -73,11 +69,13 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
### 跳过预取
|
||||
## 跳过预取
|
||||
|
||||
你可以通过将一个查询的 `prefetch` 选项设置为 `false` 来跳过对它的服务端预取。
|
||||
|
||||
不预取查询的示例:
|
||||
|
||||
```js
|
||||
```js{12}
|
||||
export default {
|
||||
apollo: {
|
||||
allPosts: {
|
||||
@@ -97,7 +95,7 @@ export default {
|
||||
|
||||
如果要跳过特定组件的所有查询的预取,使用 `$prefetch` 选项:
|
||||
|
||||
```js
|
||||
```js{4}
|
||||
export default {
|
||||
apollo: {
|
||||
// 不要预取任何查询
|
||||
@@ -115,127 +113,16 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
你也可以在任何组件上放置一个 `no-prefetch` 属性,以便在遍历树收集 Apollo 查询时忽略它:
|
||||
|
||||
```vue
|
||||
<ApolloQuery no-prefetch>
|
||||
```
|
||||
|
||||
## 在服务端
|
||||
|
||||
在服务端入口中,你需要在 Vue 中安装 `ApolloSSR` 插件:
|
||||
|
||||
```js
|
||||
import Vue from 'vue'
|
||||
import ApolloSSR from 'vue-apollo/ssr'
|
||||
|
||||
Vue.use(ApolloSSR)
|
||||
```
|
||||
|
||||
使用 `ApolloSSR.prefetchAll` 方法来预取你已标记的所有 apollo 查询。第一个参数是 `apolloProvider`。第二个参数是要包含的组件定义数组(例如来自 `router.getMatchedComponents` 方法)。第三个参数是传递给 `prefetch` 钩子的上下文对象(参见上文),建议传入 vue-router 的 `currentRoute` 对象。当所有的 apollo 查询都被加载时,它返回已解决的(resolved) promise。
|
||||
|
||||
以下是一个使用了 vue-router 和 Vuex store 的示例:
|
||||
|
||||
```js
|
||||
import Vue from 'vue'
|
||||
import ApolloSSR from 'vue-apollo/ssr'
|
||||
import App from './App.vue'
|
||||
|
||||
Vue.use(ApolloSSR, {
|
||||
// SSR 配置
|
||||
fetchPolicy: 'network-only',
|
||||
suppressRenderErrors: false,
|
||||
})
|
||||
|
||||
export default () => new Promise((resolve, reject) => {
|
||||
const { app, router, store, apolloProvider } = CreateApp({
|
||||
ssr: true,
|
||||
})
|
||||
|
||||
// 设置 router 的位置
|
||||
router.push(context.url)
|
||||
|
||||
// 等待 router 解析完可能的异步钩子
|
||||
router.onReady(() => {
|
||||
const matchedComponents = router.getMatchedComponents()
|
||||
|
||||
// 匹配不到的路由
|
||||
if (!matchedComponents.length) {
|
||||
reject({ code: 404 })
|
||||
}
|
||||
|
||||
let js = ''
|
||||
|
||||
// 调用匹配到路由的组件的预取钩子
|
||||
// 每个 preFetch 钩子分配到一个 store action 并返回一个 Promise
|
||||
// 当 action 操作完成且 store 状态已更新时解析这个 Promise
|
||||
|
||||
// Vuex Store 预取
|
||||
Promise.all(matchedComponents.map(component => {
|
||||
return component.asyncData && component.asyncData({
|
||||
store,
|
||||
route: router.currentRoute,
|
||||
})
|
||||
}))
|
||||
// Apollo 预取
|
||||
// 这里将预取整个应用中的所有 Apollo 查询
|
||||
.then(() => ApolloSSR.prefetchAll(apolloProvider, [App, ...matchedComponents], {
|
||||
store,
|
||||
route: router.currentRoute,
|
||||
}))
|
||||
.then(() => {
|
||||
// 将 Vuex 状态和 Apollo 缓存注入到页面
|
||||
// 这将防止不必要的查询
|
||||
|
||||
// Vuex
|
||||
js += `window.__INITIAL_STATE__=${JSON.stringify(store.state)};`
|
||||
|
||||
// Apollo
|
||||
js += ApolloSSR.exportStates(apolloProvider)
|
||||
|
||||
resolve({
|
||||
app,
|
||||
js,
|
||||
})
|
||||
}).catch(reject)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
使用 `ApolloSSR.exportStates(apolloProvider, options)` 方法来获取你需要注入到生成出来页面的 JavaScript 代码,这些代码用于将 apollo 缓存数据传递给客户端。
|
||||
|
||||
它需要一个 `options` 参数,默认为:
|
||||
|
||||
```js
|
||||
{
|
||||
// 全局变量名
|
||||
globalName: '__APOLLO_STATE__',
|
||||
// 变量设置到的全局对象
|
||||
attachTo: 'window',
|
||||
// 每个 apollo 客户端状态的 key 的前缀
|
||||
exportNamespace: '',
|
||||
}
|
||||
```
|
||||
|
||||
你也可以使用 `ApolloSSR.getStates(apolloProvider, options)` 方法来获取 JS 对象而不是脚本字符串。
|
||||
|
||||
它需要一个 `options` 参数,默认为:
|
||||
|
||||
```js
|
||||
{
|
||||
// 每个 apollo 客户端状态的 key 的前缀
|
||||
exportNamespace: '',
|
||||
}
|
||||
```
|
||||
|
||||
### 创建 Apollo Client
|
||||
## 创建 Apollo 客户端
|
||||
|
||||
建议在一个带有 `ssr` 参数的函数内部创建 apollo 客户端,参数在服务端为 `true`,在客户端为 `false`。
|
||||
|
||||
如果 `ssr` 为 false,我们将在服务端的 SSR 阶段中将 `window.__APOLLO_STATE__` 变量注入到 HTML 页面中,并通过该变量尝试使用 `cache.restore` 来还原 Apollo 缓存的状态。
|
||||
|
||||
这里是一个示例:
|
||||
|
||||
```js
|
||||
// src/api/apollo.js
|
||||
```js{21-30}
|
||||
// apollo.js
|
||||
|
||||
import Vue from 'vue'
|
||||
import { ApolloClient } from 'apollo-client'
|
||||
@@ -282,16 +169,24 @@ export function createApolloClient (ssr = false) {
|
||||
}
|
||||
```
|
||||
|
||||
常见的 `CreateApp` 方法示例:
|
||||
## 创建应用
|
||||
|
||||
我们并不立即创建根 Vue 实例,而代以一个接受 `context` 参数的 `createApp` 函数。
|
||||
|
||||
此函数将同时在客户端和服务端入口被使用,但在上下文中具有不同的 `ssr` 值。我们在之前编写的 `createApolloClient` 方法中使用此值。
|
||||
|
||||
常见的 `createApp` 方法示例:
|
||||
|
||||
```js{9,37}
|
||||
// app.js
|
||||
|
||||
```js
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import Vuex from 'vuex'
|
||||
import { sync } from 'vuex-router-sync'
|
||||
|
||||
import VueApollo from 'vue-apollo'
|
||||
import { createApolloClient } from './api/apollo'
|
||||
import { createApolloClient } from './apollo'
|
||||
|
||||
import App from './ui/App.vue'
|
||||
import routes from './routes'
|
||||
@@ -312,6 +207,12 @@ function createApp (context) {
|
||||
// 将注册 `store.state.route`
|
||||
sync(store, router)
|
||||
|
||||
// Vuex 状态恢复
|
||||
if (!context.ssr && window.__INITIAL_STATE__) {
|
||||
// 我们使用服务端注入的数据来初始化 store 状态
|
||||
store.replaceState(window.__INITIAL_STATE__)
|
||||
}
|
||||
|
||||
// Apollo
|
||||
const apolloClient = createApolloClient(context.ssr)
|
||||
const apolloProvider = new VueApollo({
|
||||
@@ -335,23 +236,34 @@ function createApp (context) {
|
||||
export default createApp
|
||||
```
|
||||
|
||||
在客户端:
|
||||
## 客户端入口
|
||||
|
||||
客户端入口非常简单——我们只需将 `ssr` 设为 `false` 来调用 `createApp`:
|
||||
|
||||
```js
|
||||
import CreateApp from './app'
|
||||
// client-entry.js
|
||||
|
||||
CreateApp({
|
||||
import createApp from './app'
|
||||
|
||||
createApp({
|
||||
ssr: false,
|
||||
})
|
||||
```
|
||||
|
||||
在服务端:
|
||||
## 服务端入口
|
||||
|
||||
```js
|
||||
import CreateApp from './app'
|
||||
除了存储 Apollo 缓存并将其注入客户端 HTML 之外,不需要任何特殊内容。在官方 SSR 指南中了解有关 [带路由的服务端入口](https://ssr.vuejs.org/guide/routing.html#routing-with-vue-router) 和 [数据预取](https://ssr.vuejs.org/guide/data.html#data-store) 的更多信息。
|
||||
|
||||
这里是使用了 vue-router 和 Vuex 的一个示例:
|
||||
|
||||
```js{3,26}
|
||||
// server-entry.js
|
||||
|
||||
import ApolloSSR from 'vue-apollo/ssr'
|
||||
import createApp from './app'
|
||||
|
||||
export default () => new Promise((resolve, reject) => {
|
||||
const { app, router, store, apolloProvider } = CreateApp({
|
||||
const { app, router, store, apolloProvider } = createApp({
|
||||
ssr: true,
|
||||
})
|
||||
|
||||
@@ -360,9 +272,50 @@ export default () => new Promise((resolve, reject) => {
|
||||
|
||||
// 等待 router 解析完可能的异步钩子
|
||||
router.onReady(() => {
|
||||
// 预取,渲染 HTML(参见上文)
|
||||
// 此 `rendered` 钩子将在应用完成渲染时被调用
|
||||
context.rendered = () => {
|
||||
// 在应用完成渲染后,
|
||||
// 我们的 store 现在已经填充入渲染应用程序所需的状态。
|
||||
// 当我们将状态附加到上下文,
|
||||
// 并且 `template` 选项用于 renderer 时,
|
||||
// 状态将自动序列化为 `window.__INITIAL_STATE__`,并注入 HTML。
|
||||
context.state = store.state
|
||||
|
||||
// 同样注入 apollo 缓存状态
|
||||
context.apolloState = ApolloSSR.getStates(apolloProvider)
|
||||
}
|
||||
resolve(app)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
请查看 [SSR API](../api/ssr.md) 了解更多详情和其他功能。
|
||||
使用 [ApolloSSR.getStates](../api/ssr.md#getstates) 方法以获取需要注入到生成的页面、用来将 apollo 缓存数据传递给客户端的 JavaScript 代码。
|
||||
|
||||
在 [页面模板](https://ssr.vuejs.org/guide/#using-a-page-template) 中,使用 `renderState` 辅助函数:
|
||||
|
||||
```html
|
||||
{{{ renderState({ contextKey: 'apolloState', windowKey: '__APOLLO_STATE__' }) }}}
|
||||
```
|
||||
|
||||
这里是一个完整的示例:
|
||||
|
||||
```html{15}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>{{ title }}</title>
|
||||
{{{ renderResourceHints() }}}
|
||||
{{{ renderStyles() }}}
|
||||
</head>
|
||||
<body>
|
||||
<!--vue-ssr-outlet-->
|
||||
{{{ renderState() }}}
|
||||
{{{ renderState({ contextKey: 'apolloState', windowKey: '__APOLLO_STATE__' }) }}}
|
||||
{{{ renderScripts() }}}
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
@@ -152,7 +152,7 @@ const apolloProvider = new VueApollo({
|
||||
|
||||
// 使用 provider
|
||||
new Vue({
|
||||
provide: apolloProvider.provide(),
|
||||
apolloProvider,
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user