Nuxt/docs/content/1.getting-started/4.bridge-composition-api.md
Daniel Roe 875deefafc
docs: add migration guide for bridge composition api (#1669)
Co-authored-by: pooya parsa <pyapar@gmail.com>
2021-11-04 12:20:40 +01:00

7.7 KiB

navigation
false

Migrating to Bridge Composition API

Nuxt Bridge provides access to Composition API syntax. It is specifically designed to be aligned with Nuxt 3. Because of this, there are a few extra steps to take when enabling Nuxt Bridge, if you have been using the Composition API previously.

Using @vue/composition-api

If you have been using just @vue/composition-api and not @nuxtjs/composition-api, then things are very straightforward.

  1. First, remove the plugin where you are manually registering the Composition API. Nuxt Bridge will handle this for you.

    - import Vue from 'vue'
    - import VueCompositionApi from '@vue/composition-api'
    -
    - Vue.use(VueCompositionApi)
    
  2. Otherwise, there is nothing you need to do. However, if you want, you can remove your explicit imports from @vue/composition-api and rely on Nuxt Bridge auto-importing them for you.

Migrating from @nuxtjs/composition-api

Nuxt Bridge implements the Composition API slightly differently from @nuxtjs/composition-api and provides different composables (designed to be aligned with the composables that Nuxt 3 provides).

Because some composables have been removed and don't yet have a replacement, this will be a slightly more complicated process.

  1. Remove @nuxtjs/composition-api from your project dependencies, and remove @nuxtjs/composition-api/module from your buildModules.

    You don't have to immediately update your imports yet - Nuxt Bridge will automatically provide a 'shim' for most imports you currently have, to give you time to migrate to the new, Nuxt 3-compatible composables, with the following exceptions:

    • withContext has been removed. See below.
    • useStatic has been removed. There is no current replacement. Feel free to raise a discussion if you have a use case for this.
    • reqRef and reqSsrRef, which were deprecated, have now been removed entirely. Follow the instructions below regarding ssrRef to replace this.
  2. Remove any explicit imports of the basic Vue Composition API composables, or move them to import from #app or vue.

    - import { ref, useContext } from '@nuxtjs/composition-api`
    + import { ref } from '#app'
    
  3. For each other composable you are using from @nuxtjs/composition-api, follow the steps below.

defineNuxtMiddleware

This was a type-helper stub function that is now removed.

Simply remove the defineNuxtMiddleware wrapper:

- import { defineNuxtMiddleware } from '@nuxtjs/composition-api`
- export default defineNuxtMiddleware((ctx) => {})
+ export default (ctx) => {}

For typescript support, you can use @nuxt/types:

import type { Middleware } from '@nuxt/types'

export default <Middleware> function (ctx) { }

defineNuxtPlugin

This was a type-helper stub function that is now removed.

You may also keep using Nuxt 2-style plugins, by simply removing the function (as with defineNuxtMiddleware).

Simply remove the defineNuxtMiddleware wrapper:

- import { defineNuxtPlugin } from '@nuxtjs/composition-api`
- export default defineNuxtPlugin((ctx, inject) => {})
+ export default (ctx, inject) => {}

For typescript support, you can use @nuxt/types:

import type { Plugin } from '@nuxt/types'

export default <Plugin> function (ctx, inject) {}

onGlobalSetup

This function has been removed, but many use cases can be met by using useNuxtApp or useState within defineNuxtPlugin. You can also run any custom code within the setup() function of a layout. If you have another use case for onGlobalSetup, please let us know via a discussion.

ssrRef and shallowSsrRef

These two functions have been replaced with a new composable that works very similarly under the hood: useState.

The key differences are that you must provide a key for this state (which previously will have been generated automatically for ssrRef and shallowSsrRef), and that it can only be called within a Nuxt 3 plugin (which is defined by defineNuxtPlugin) or a component instance. (In other words, you cannot use useState with a global/ambient context, because of the danger of shared state across requests.)

- import { ssrRef } from '@nuxtjs/composition-api'
+ import { useState } from '#app'

- const ref1 = ssrRef('initialData')
- const ref2 = ssrRef(() => 'factory function')
+ const ref1 = useState('ref1-key', () => 'initialData')
+ const ref2 = useState('ref2-key', () => 'factory function')
  // accessing the state
  console.log(ref1.value)

Because the state is keyed, you can access the same state from multiple locations, as long as you are using the same key.

You can read more about how to use this composable in the Nuxt 3 docs.

ssrPromise

This function has been removed, and you will need to find an alternative implementation if you were using it. If you have a use case for ssrPromise, please let us know via a discussion.

useRouter and useRoute

Nuxt Bridge provides direct replacements for these composables via useRouter and useRoute.

The only key difference is that useRoute no longer returns a computed property.

- import { useRouter, useRoute } from '@nuxtjs/composition-api'
+ import { useRouter, useRoute } from '#app'

  const router = useRouter()
  const route = useRoute()

- console.log(route.value.path)
+ console.log(route.path)

useStore

In order to access Vuex store instance, you can use useNuxtApp().$store.

- import { useStore } from '@nuxtjs/composition-api`
+ import { useNuxtApp } from '#app'
+ const  { $store } = useNuxtApp()
<script>
import { useNuxtApp } from '#app'
const { $store } = useNuxtApp()
</script>

useContext and withContext

You can access injected helpers using useNuxtApp.

- import { useContext } from '@nuxtjs/composition-api`
+ import { useNuxtApp } from '#app'
+ const  { $axios } = useNuxtApp()
<script>
import { useNuxtApp } from '#app'
const { $axios } = useNuxtApp()
</script>

::alert{icon=👉} useNuxtApp() also provides a key called nuxt2Context which contains all the same properties you would normally access from Nuxt 2 context, but it's advised not to use this directly, as it won't exist in Nuxt 3. Instead, see if there is another way to access what you need. (If not, please raise a feature request or discussion.) ::

wrapProperty

This helper function is not provided any more but you can replace it with the following code:

const wrapProperty = (property, makeComputed = true) => () => {
  const vm = getCurrentInstance().proxy
  return makeComputed ? computed(() => vm[property]) : vm[property]
}

useAsync and useFetch

There is currently no replacement for these two functions with bridge.

You can continue to use useAsync and useFetch by importing them from @nuxtjs/composition-api, which is shimmed by Nuxt Bridge.

useMeta

In order to use vue-meta, you can continue importing useMeta and defineComponent from @nuxtjs/composition-api, which is shimmed by Nuxt Bridge.

However, note that the existing limitations of useMeta continue, so it cannot be used in <script setup> and you must include a head: {} object within your defineComponent.

import { defineComponent, useMeta } from '@nuxtjs/composition-api'

export default defineComponent({
  // You need to define an empty head to activate this functionality
  head: {},
  setup() {
    // This will allow you to set the title in head - but won't allow you to read its state outside of this component.
    const { title } = useMeta()
    title.value = 'My page'
  },
})