fix(bridge): don't double-install plugins when using compat vueApp.use (#3898)

This commit is contained in:
Daniel Roe 2022-03-25 11:53:56 +00:00 committed by GitHub
parent c7f4e3c709
commit 773dd59a2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 4 deletions

View File

@ -194,6 +194,10 @@ export default defineNuxtPlugin(nuxtApp => {
If you want to use the new Nuxt composables (such as `useNuxtApp` or `useRuntimeConfig`) within your plugins, you will need to use the `defineNuxtPlugin` helper for those plugins. If you want to use the new Nuxt composables (such as `useNuxtApp` or `useRuntimeConfig`) within your plugins, you will need to use the `defineNuxtPlugin` helper for those plugins.
:: ::
::alert{type=warning}
Although a compatibility interface is provided via `nuxtApp.vueApp` you should avoid registering plugins, directives, mixins or components this way without adding your own logic to ensure they are not installed more than once, or this may cause a memory leak.
::
## New `useMeta` (optional) ## New `useMeta` (optional)
Nuxt Bridge provides a new Nuxt 3 meta API that can be accessed with a new `useMeta` composable. Nuxt Bridge provides a new Nuxt 3 meta API that can be accessed with a new `useMeta` composable.

View File

@ -19,20 +19,29 @@ function proxiedState (state) {
}) })
} }
const runOnceWith = (obj, fn) => {
if (!obj || !['function', 'object'].includes(typeof obj)) {
return fn()
}
if (obj.__nuxt_installed) { return }
obj.__nuxt_installed = true
return fn()
}
export default async (ctx, inject) => { export default async (ctx, inject) => {
const nuxtApp = { const nuxtApp = {
vueApp: { vueApp: {
component: Vue.component.bind(Vue), component: (id, definition) => runOnceWith(definition, () => Vue.component(id, definition)),
config: { config: {
globalProperties: {} globalProperties: {}
}, },
directive: Vue.directive.bind(Vue), directive: (id, definition) => runOnceWith(definition, () => Vue.directive(id, definition)),
mixin: Vue.mixin.bind(Vue), mixin: mixin => runOnceWith(mixin, () => Vue.mixin(mixin)),
mount: () => { }, mount: () => { },
provide: inject, provide: inject,
unmount: () => { }, unmount: () => { },
use (vuePlugin) { use (vuePlugin) {
vuePlugin.install(this) runOnceWith(vuePlugin, () => vuePlugin.install(this))
}, },
version: Vue.version version: Vue.version
}, },