Co-authored-by: Daniel Roe <daniel@roe.dev> Co-authored-by: Sébastien Chopin <seb@nuxtjs.com> Co-authored-by: Pooya Parsa <pooya@pi0.io> Co-authored-by: pooya parsa <pyapar@gmail.com> Co-authored-by: Clément Ollivier <clement.o2p@gmail.com>
9.5 KiB
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.
-
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)
-
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.
-
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
andreqSsrRef
, which were deprecated, have now been removed entirely. Follow the instructions below regarding ssrRef to replace this.
-
Remove any explicit imports of the basic Vue Composition API composables.
::alert{type=info} Nuxt Bridge auto-imports Vue composables, you don't have to explicitly import them. ::
- import { ref, useContext } from '@nuxtjs/composition-api`
-
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.
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 removing the function (as with defineNuxtMiddleware).
Remove the defineNuxtPlugin
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) {}
::alert You may wish to migrate your plugins to Nuxt 3-style plugins as a next (optional) step. ::
onGlobalSetup
This function has been removed, but its 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.
- import { onGlobalSetup } from '@nuxtjs/composition-api'
- export default () => {
- onGlobalSetup(() => {
+ export default defineNuxtPlugin((nuxtApp) => {
+ nuxtApp.hook('vue:setup', () => {
// ...
})
- }
+ })
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 Nuxt 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'
- 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'
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`
+ const { $store } = useNuxtApp()
useContext
and withContext
You can access injected helpers using useNuxtApp
.
- import { useContext } from '@nuxtjs/composition-api`
+ const { $axios } = useNuxtApp()
::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
These two composables can be replaced with useLazyAsyncData
and useLazyFetch
, which are documented in the Nuxt 3 docs. Just like the previous @nuxtjs/composition-api
composables, these composables do not block route navigation on the client-side (hence the 'lazy' part of the name).
::alert
Note that the API is entirely different, despite similar sounding names. Importantly, you should not attempt to change the value of other variables outside the composable (as you may have been doing with the previous useFetch
).
::
Migrating to the new composables from useAsync
:
<script setup>
- import { useAsync } from '@nuxtjs/composition-api'
- const posts = useAsync(() => $fetch('/api/posts'))
+ const { data: posts } = useLazyAsyncData('posts', () => $fetch('/api/posts'))
+ // or, more simply!
+ const { data: posts } = useLazyFetch('/api/posts')
</script>
Migrating to the new composables from useFetch
:
<script setup>
- import { useFetch } from '@nuxtjs/composition-api'
- const posts = ref([])
- const { fetch } = useFetch(() => { posts.value = await $fetch('/api/posts') })
+ const { data: posts, refresh } = useLazyAsyncData('posts', () => $fetch('/api/posts'))
+ // or, more simply!
+ const { data: posts, refresh } = useLazyFetch('/api/posts')
function updatePosts() {
- return fetch()
+ return refresh()
}
</script>
useMeta
In order to interact with vue-meta
, you may use useNuxt2Meta
, which will work in Nuxt Bridge (but not Nuxt 3) and will allow you to manipulate your meta tags in a vue-meta
-compatible way.
<script setup>
- import { useMeta } from '@nuxtjs/composition-api'
useNuxt2Meta({
title: 'My Nuxt App',
})
</script>
You can also pass in computed values or refs, and the meta values will be updated reactively:
<script setup>
const title = ref('my title')
useNuxt2Meta({
title,
})
title.value = 'new title'
</script>
::alert
Be careful not to use both useNuxt2Meta()
and the Options API head()
within the same component, as behavior may be unpredictable.
::
Nuxt Bridge also provides a Nuxt 3-compatible meta implementation that can be accessed with the useHead
composable.
<script setup>
- import { useMeta } from '@nuxtjs/composition-api'
useHead({
title: 'My Nuxt App',
})
</script>
You will also need to enable it explicitly in your nuxt.config
:
import { defineNuxtConfig } from '@nuxt/bridge'
export default defineNuxtConfig({
bridge: {
meta: true
}
})
This useHead
composable uses @vueuse/head
under the hood (rather than vue-meta
) to manipulate your <head>
. Accordingly, it is recommended not to use both the native Nuxt 2 head()
properties as well as useHead
, as they may conflict.
For more information on how to use this composable, see the Nuxt 3 docs.