2016-11-18 4 views
1

Я пытаюсь сделать приложение Vue на стороне сервера. Я использую vue-server-renderer (https://www.npmjs.com/package/vue-server-renderer). Клиентский рендеринг работает нормально.Компонент в рендеринге на стороне сервера Vue.js

Мое использование приложение vue-router и axios

Вот мой 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()

возвращает массив компонентов (определение/конструктор, не экземпляров) соответствует текущему маршруту. Это в основном используется во время рендеринга на стороне сервера , чтобы выполнить предварительную выборку данных.

Как исправить проблему?

+0

И это именно то, где концепция магазина пинков в Vuex может хранить данные, получаемые от асинхронной API для объекта разделяемого во всех компонентах.. Оформить заказ https://github.com/vuejs/vue-hackernews-2.0 –

ответ

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 ... */ }); 
} 

Согласно вю 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) 
    } 
}, 
Смежные вопросы