Composition-api: lack of life cycle method `serverPrefetch`

Created on 23 Jul 2019  路  6Comments  路  Source: vuejs/composition-api

There is no life cycle method serverPrefetch , so can not be fully used on SSR.

In order to support SSR, the only choice is to remain serverPrefetch() method. And then, all methods and data properties used by serverPrefetch() has to be remained. And then, very little code can be ported into setup() method. And the code is in "mixed style", very ugly.

enhancement

Most helpful comment

I'm also encountering this issue.

I have made the change from PR https://github.com/vuejs/composition-api/pull/80 locally and the onServerPrefetch hook is being called and I can see async function being called server side, but I'm not sure how to assign the result of the call to a reactive property to be used in the template.

What is the correct way to assign the result of a server side async call to a reactive property?

Sample code:

import { createComponent, reactive, watch, onServerPrefetch } from '@vue/composition-api'
import gql from 'graphql-tag'

async function useCourses(client) {
  return client
    .query({
      query: gql`
        query getCourses {
          courses {
            id
            title
            author
            description
            topic
            url
          }
        }
      `
    })
    .then(res => res.data.courses)
}

const Courses = createComponent({
  name: 'Courses',
  components: {
    'c-course': () => import('./Course.vue')
  },

  setup(initialProps, context) {
    const { defaultClient: apolloClient } = context.root.$apolloProvider

    const state = reactive({
      courses: []
    })

    onServerPrefetch(async () => {
      // Working: the gql call is being made
      const result = await useCourses(apolloClient)
      // console.log(result)
      // Not working: Can't assign the result to state.courses
      watch(async () => {
        state.courses = result
      })
    })

    // Working: client side call and assignment
    watch(async () => {
      state.courses = await useCourses(apolloClient)
    })

    return { state }
  }
})
export default Courses

All 6 comments

I think this is a limitation of this plugin in Vue 2. Making the new API work with SSR will require change to internals that we will do in Vue 3, but not Vue 2.

@liximomo if this is indeed a limitation we can label it as wont fix and close it

@posva I think It's feasible. Assigning the param of onServerPrefetch to $options.serverPrefetch should be enough.

not sure how to test this one, but I can implement it.

80

There exists a pull request.

I'm also encountering this issue.

I have made the change from PR https://github.com/vuejs/composition-api/pull/80 locally and the onServerPrefetch hook is being called and I can see async function being called server side, but I'm not sure how to assign the result of the call to a reactive property to be used in the template.

What is the correct way to assign the result of a server side async call to a reactive property?

Sample code:

import { createComponent, reactive, watch, onServerPrefetch } from '@vue/composition-api'
import gql from 'graphql-tag'

async function useCourses(client) {
  return client
    .query({
      query: gql`
        query getCourses {
          courses {
            id
            title
            author
            description
            topic
            url
          }
        }
      `
    })
    .then(res => res.data.courses)
}

const Courses = createComponent({
  name: 'Courses',
  components: {
    'c-course': () => import('./Course.vue')
  },

  setup(initialProps, context) {
    const { defaultClient: apolloClient } = context.root.$apolloProvider

    const state = reactive({
      courses: []
    })

    onServerPrefetch(async () => {
      // Working: the gql call is being made
      const result = await useCourses(apolloClient)
      // console.log(result)
      // Not working: Can't assign the result to state.courses
      watch(async () => {
        state.courses = result
      })
    })

    // Working: client side call and assignment
    watch(async () => {
      state.courses = await useCourses(apolloClient)
    })

    return { state }
  }
})
export default Courses
Was this page helpful?
0 / 5 - 0 ratings