Vuex状态中。另一个需要关注的问题是在客户端,在挂载到客户端应用程序之前,需要获取到与服务器端应用程序完全相同的数据 – 否则,客户端应用程序会因为使用与服务器端应用程序不同的状态,然后导致混合失败。
目前较好的解决方案是,给路由匹配的一级子组件一个
asyncData,在
asyncData方法中,
dispatch对应的
action。
asyncData是我们约定的函数名,表示渲染组件需要预先执行它获取初始数据,它返回一个
Promise,以便我们在后端渲染的时候可以知道什么时候该操作完成。注意,由于此函数会在组件实例化之前调用,所以它无法访问
this。需要将
store和路由信息作为参数传递进去:举个例子:
<!-- Lung.vue -->
<template>
<div></div>
</template><script>
export default {
// ...
async asyncData({ store, route }) {
return Promise.all([
store.dispatch('getA'),
store.dispatch('myModule/getB', { root:true }),
store.dispatch('myModule/getC', { root:true }),
store.dispatch('myModule/getD', { root:true }),
]);
},
// ...
}
</script>
在
entry-server.js中,我们可以通过路由获得与
router.getMatchedComponents()相匹配的组件,如果组件暴露出
asyncData,我们就调用这个方法。然后我们需要将解析完成的状态,附加到渲染上下文中。
const createApp = require('./app');module.exports = context => {
return new Promise((resolve, reject) => {
const { app, router, store } = createApp(context);
// 针对没有Vue router 的Vue实例,在项目中为列表页,直接resolve app
if (!router) {
resolve(app);
}
// 设置服务器端 router 的位置
router.push(context.url.replace('/base', ''));
// 等到 router 将可能的异步组件和钩子函数解析完
router.onReady(() => {
const matchedComponents = router.getMatchedComponents();
// 匹配不到的路由,执行 reject 函数,并返回 404
if (!matchedComponents.length) {
return reject('匹配不到的路由,执行 reject 函数,并返回 404');
}
Promise.all(matchedComponents.map(Component => {










