1

我正在尝试使我的 Vue 应用程序具有服务器端渲染。我正在使用vue-server-rendererhttps://www.npmjs.com/package/vue-server-renderer)。客户端渲染工作正常。

我的应用程序使用vue-routeraxios

这是我的server.js

server.get('*', (request, response) => {
  bundleRenderer.renderToString({ url: request.url }, (error, htmlPromise) => {
    if (error) {
      // Log the error in the console
      console.error(error)
      // Tell the client something went wrong
      return response
        .status(500)
        .send(error)
    }
    response.send(layout.replace('<div id=app></div>', htmlPromise))
  })
})

getInfo()是获取服务器数据的方法。

这里是getInfo()

export default {
  methods: {
    getInfo(api) {
        return axios
          .get(api || this.$route.params.path)
          .then((data) => {
            this.data = data
            this.$set(this, 'isLoading', false)
          })
    },
  },
}

我的服务器条目是:

import { app, router, store } from './index'

export default context => {

  let componentPromises = router.getMatchedComponents().filter((component) => {
    return component.methods && component.methods.getInfo
  }).map((component) => {
    return component.methods.getInfo()
  })

  return Promise.all(componentPromises).then(() => {
    return app
  })
}

但是,我很快意识到,所有组件router.getMatchedComponents()都没有$route$set。因此,该方法getInfo()停止工作。

https://router.vuejs.org/en/api/router-instance.html的文档很短,没有提供太多信息:

router.getMatchedComponents()

返回与当前路由匹配的组件(定义/构造函数,而不是实例)的数组。这主要用于在服务器端渲染期间执行数据预取。

我该如何解决这个问题?

4

1 回答 1

0

我以前遇到过类似的问题,并通过执行以下操作成功地预取数据:

app.$router.onReady(() => {
   const matchedComponents = app.$router.getMatchedComponents()

   if (!matchedComponents.length) { /* ... */}

   Promise.all(matchedComponents.map((Component: any) => {
     if (Component.options.methods.asyncData) {
       return Component.options.methods.asyncData({
         store: app.$store,
         route: app.$router.currentRoute
       });
     }
   })).then(() => { /* your callback here ... */ });
}

根据 vue ssr 文档(https://ssr.vuejs.org/en/data.html),建议的方法是在组件中使用自定义 asyncData 方法来执行数据获取,而不是直接调用组件方法:

export default {
   asyncData ({ store, route }) {
      // return the Promise from the action
      return store.dispatch('fetchItem', route.params.id)
   }
},
于 2017-09-09T12:06:03.510 回答