mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
feat(bridge): add useNuxtApp
and defineNuxtPlugin
composables (#576)
This commit is contained in:
parent
c5979d9fb5
commit
3bf856830b
@ -1,4 +1,4 @@
|
|||||||
import { useNuxt, addPluginTemplate } from '@nuxt/kit'
|
import { useNuxt, addPlugin, addPluginTemplate } from '@nuxt/kit'
|
||||||
import { resolve } from 'upath'
|
import { resolve } from 'upath'
|
||||||
import { distDir } from './dirs'
|
import { distDir } from './dirs'
|
||||||
|
|
||||||
@ -14,6 +14,11 @@ export function setupCAPIBridge (_options: any) {
|
|||||||
nuxt.options.alias['@vue/composition-api'] = require.resolve('@vue/composition-api/dist/vue-composition-api.mjs')
|
nuxt.options.alias['@vue/composition-api'] = require.resolve('@vue/composition-api/dist/vue-composition-api.mjs')
|
||||||
const capiPluginPath = resolve(distDir, 'runtime/capi.plugin.mjs')
|
const capiPluginPath = resolve(distDir, 'runtime/capi.plugin.mjs')
|
||||||
addPluginTemplate({ filename: 'capi.plugin.mjs', src: capiPluginPath })
|
addPluginTemplate({ filename: 'capi.plugin.mjs', src: capiPluginPath })
|
||||||
|
|
||||||
|
// Add support for useNuxtApp
|
||||||
|
addPlugin(resolve(distDir, 'runtime/app.plugin.mjs'))
|
||||||
|
|
||||||
|
// Register Composition API before loading the rest of app
|
||||||
nuxt.hook('webpack:config', (configs) => {
|
nuxt.hook('webpack:config', (configs) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
configs.forEach(config => config.entry.app.unshift(capiPluginPath))
|
configs.forEach(config => config.entry.app.unshift(capiPluginPath))
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
const mock = () => () => { throw new Error('not implemented') }
|
|
||||||
|
|
||||||
export const defineNuxtPlugin = mock()
|
|
||||||
export const defineNuxtComponent = mock()
|
|
||||||
export const useNuxtApp = mock()
|
|
27
packages/bridge/src/runtime/app.plugin.mjs
Normal file
27
packages/bridge/src/runtime/app.plugin.mjs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { createHooks } from 'hookable/dist/index.mjs'
|
||||||
|
import { setNuxtInstance } from '#app'
|
||||||
|
|
||||||
|
export default (ctx, inject) => {
|
||||||
|
const nuxt = {
|
||||||
|
provide: inject,
|
||||||
|
globalName: 'nuxt',
|
||||||
|
payload: process.client ? ctx.nuxtState : ctx.ssrContext.nuxt,
|
||||||
|
isHydrating: ctx.isHMR,
|
||||||
|
legacyNuxt: ctx.app
|
||||||
|
}
|
||||||
|
nuxt.hooks = createHooks()
|
||||||
|
nuxt.hook = nuxt.hooks.hook
|
||||||
|
nuxt.callHook = nuxt.hooks.callHook
|
||||||
|
|
||||||
|
if (!Array.isArray(ctx.app.created)) {
|
||||||
|
ctx.app.created = [ctx.app.created]
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.app.created.push(function () {
|
||||||
|
nuxt.legacyApp = this
|
||||||
|
})
|
||||||
|
|
||||||
|
setNuxtInstance(nuxt)
|
||||||
|
|
||||||
|
inject('_nuxtApp', nuxt)
|
||||||
|
}
|
59
packages/bridge/src/runtime/app.ts
Normal file
59
packages/bridge/src/runtime/app.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import type { Hookable } from 'hookable'
|
||||||
|
// @ts-ignore
|
||||||
|
import type { Vue } from 'vue/types/vue'
|
||||||
|
import type { ComponentOptions } from 'vue'
|
||||||
|
import { defineComponent, getCurrentInstance } from './composables'
|
||||||
|
|
||||||
|
export const defineNuxtComponent = defineComponent
|
||||||
|
|
||||||
|
export interface RuntimeNuxtHooks { }
|
||||||
|
|
||||||
|
export interface NuxtAppCompat {
|
||||||
|
legacyNuxt: Vue
|
||||||
|
legacyApp: ComponentOptions<Vue>
|
||||||
|
|
||||||
|
globalName: string
|
||||||
|
|
||||||
|
hooks: Hookable<RuntimeNuxtHooks>
|
||||||
|
hook: NuxtAppCompat['hooks']['hook']
|
||||||
|
callHook: NuxtAppCompat['hooks']['callHook']
|
||||||
|
|
||||||
|
[key: string]: any
|
||||||
|
|
||||||
|
ssrContext?: Record<string, any>
|
||||||
|
payload: {
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
|
||||||
|
provide: (name: string, value: any) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Context {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
$_nuxtApp: NuxtAppCompat
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentNuxtInstance: NuxtAppCompat | null
|
||||||
|
|
||||||
|
export const setNuxtInstance = (nuxt: NuxtAppCompat | null) => {
|
||||||
|
currentNuxtInstance = nuxt
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defineNuxtPlugin = plugin => (ctx: Context) => {
|
||||||
|
setNuxtInstance(ctx.$_nuxtApp)
|
||||||
|
plugin(ctx.$_nuxtApp)
|
||||||
|
setNuxtInstance(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useNuxtApp = () => {
|
||||||
|
const vm = getCurrentInstance()
|
||||||
|
|
||||||
|
if (!vm) {
|
||||||
|
if (!currentNuxtInstance) {
|
||||||
|
throw new Error('nuxt instance unavailable')
|
||||||
|
}
|
||||||
|
return currentNuxtInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
return vm?.proxy.$_nuxtApp
|
||||||
|
}
|
@ -68,7 +68,6 @@ export function createNuxt (options: CreateOptions) {
|
|||||||
const nuxt: NuxtApp = {
|
const nuxt: NuxtApp = {
|
||||||
provide: undefined,
|
provide: undefined,
|
||||||
globalName: 'nuxt',
|
globalName: 'nuxt',
|
||||||
state: {},
|
|
||||||
payload: {},
|
payload: {},
|
||||||
isHydrating: process.client,
|
isHydrating: process.client,
|
||||||
...options
|
...options
|
||||||
|
Loading…
Reference in New Issue
Block a user