设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

Vue服务端渲染实践 ——Web应用首屏耗时最优化方案(7)

发布时间:2019-03-21 00:39 所属栏目:21 来源:counterxing
导读:在entry-server.js中,我们可以通过路由获得与router.getMatchedComponents()相匹配的组件,如果组件暴露出asyncData,我们就调用这个方法。然后我们需要将解析完成的状态,附加到渲染上下文中。 constcreateApp=re

在entry-server.js中,我们可以通过路由获得与router.getMatchedComponents()相匹配的组件,如果组件暴露出asyncData,我们就调用这个方法。然后我们需要将解析完成的状态,附加到渲染上下文中。

  1. const createApp = require('./app');  
  2. module.exports = context => {  
  3.   return new Promise((resolve, reject) => {  
  4.     const { app, router, store } = createApp(context);  
  5.     // 针对没有Vue router 的Vue实例,在项目中为列表页,直接resolve app  
  6.     if (!router) {  
  7.       resolve(app);  
  8.     }  
  9.     // 设置服务器端 router 的位置  
  10.       router.push(context.url.replace('/base', ''));  
  11.     // 等到 router 将可能的异步组件和钩子函数解析完  
  12.     router.onReady(() => {  
  13.       const matchedComponents = router.getMatchedComponents();  
  14.       // 匹配不到的路由,执行 reject 函数,并返回 404  
  15.       if (!matchedComponents.length) {  
  16.         return reject('匹配不到的路由,执行 reject 函数,并返回 404');  
  17.       }  
  18.       Promise.all(matchedComponents.map(Component => {  
  19.         if (Component.asyncData) {  
  20.           return Component.asyncData({  
  21.             store,  
  22.             route: router.currentRoute,  
  23.           });  
  24.         }  
  25.       })).then(() => {  
  26.         // 在所有预取钩子(preFetch hook) resolve 后,  
  27.         // 我们的 store 现在已经填充入渲染应用程序所需的状态。  
  28.         // 当我们将状态附加到上下文,并且 `template` 选项用于 renderer 时,  
  29.         // 状态将自动序列化为 `window.__INITIAL_STATE__`,并注入 HTML。  
  30.         context.state = store.state;  
  31.         resolve(app);  
  32.       }).catch(reject);  
  33.     }, reject);  
  34.   });  

客户端托管全局状态

当服务端使用模板进行渲染时,context.state将作为window.__INITIAL_STATE__状态,自动嵌入到最终的HTML 中。而在客户端,在挂载到应用程序之前,store就应该获取到状态,最终我们的entry-client.js被改造为如下所示:

  1. import createApp from './app';  
  2. const { app, router, store } = createApp();  
  3. // 客户端把初始化的store替换为window.__INITIAL_STATE__  
  4. if (window.__INITIAL_STATE__) {  
  5.   store.replaceState(window.__INITIAL_STATE__);  
  6. }  
  7. if (router) {  
  8.   router.onReady(() => {  
  9.     app.$mount('#app')  
  10.   });  
  11. } else {  
  12.   app.$mount('#app');  

常见问题的解决方案

至此,基本的代码改造也已经完成了,下面说的是一些常见问题的解决方案:

  •  在服务端没有window、location对象:

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读