mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
feat(nuxt): expose refresh
on islands and server components (#24261)
This commit is contained in:
parent
1711c33be4
commit
17b5ed9ad8
@ -50,3 +50,9 @@ Every slot is interactive since the parent component is the one providing it.
|
|||||||
Some slots are reserved to `NuxtIsland` for special cases.
|
Some slots are reserved to `NuxtIsland` for special cases.
|
||||||
|
|
||||||
- `#fallback`: Specify the content to be rendered before the island loads (if the component is lazy) or if `NuxtIsland` fails to fetch the component.
|
- `#fallback`: Specify the content to be rendered before the island loads (if the component is lazy) or if `NuxtIsland` fails to fetch the component.
|
||||||
|
|
||||||
|
## Ref
|
||||||
|
|
||||||
|
- `refresh()`
|
||||||
|
- **type**: `() => Promise<void>`
|
||||||
|
- **description**: force refetch the server component by refetching it.
|
||||||
|
@ -46,7 +46,7 @@ export default defineComponent({
|
|||||||
default: () => undefined
|
default: () => undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async setup (props, { slots }) {
|
async setup (props, { slots, expose }) {
|
||||||
const error = ref<unknown>(null)
|
const error = ref<unknown>(null)
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
@ -160,6 +160,10 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expose({
|
||||||
|
refresh: () => fetchComponent(true)
|
||||||
|
})
|
||||||
|
|
||||||
if (import.meta.hot) {
|
if (import.meta.hot) {
|
||||||
import.meta.hot.on(`nuxt-server-component:${props.name}`, () => {
|
import.meta.hot.on(`nuxt-server-component:${props.name}`, () => {
|
||||||
fetchComponent(true)
|
fetchComponent(true)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { defineComponent, h } from 'vue'
|
import { defineComponent, h, ref } from 'vue'
|
||||||
import NuxtIsland from '#app/components/nuxt-island'
|
import NuxtIsland from '#app/components/nuxt-island'
|
||||||
|
|
||||||
/*@__NO_SIDE_EFFECTS__*/
|
/*@__NO_SIDE_EFFECTS__*/
|
||||||
@ -7,12 +7,19 @@ export const createServerComponent = (name: string) => {
|
|||||||
name,
|
name,
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: { lazy: Boolean },
|
props: { lazy: Boolean },
|
||||||
setup (props, { attrs, slots }) {
|
setup (props, { attrs, slots, expose }) {
|
||||||
|
const islandRef = ref<null | typeof NuxtIsland>(null)
|
||||||
|
|
||||||
|
expose({
|
||||||
|
refresh: () => islandRef.value?.refresh()
|
||||||
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
return h(NuxtIsland, {
|
return h(NuxtIsland, {
|
||||||
name,
|
name,
|
||||||
lazy: props.lazy,
|
lazy: props.lazy,
|
||||||
props: attrs
|
props: attrs,
|
||||||
|
ref: islandRef
|
||||||
}, slots)
|
}, slots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it, vi } from 'vitest'
|
import { describe, expect, it, vi } from 'vitest'
|
||||||
import { h } from 'vue'
|
import { h, nextTick } from 'vue'
|
||||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||||
import { createServerComponent } from '../../packages/nuxt/src/components/runtime/server-component'
|
import { createServerComponent } from '../../packages/nuxt/src/components/runtime/server-component'
|
||||||
import { createSimpleRemoteIslandProvider } from '../fixtures/remote-provider'
|
import { createSimpleRemoteIslandProvider } from '../fixtures/remote-provider'
|
||||||
@ -65,4 +65,35 @@ describe('runtime server component', () => {
|
|||||||
|
|
||||||
await server.close()
|
await server.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('force refresh', async () => {
|
||||||
|
let count = 0
|
||||||
|
const stubFetch = vi.fn(() => {
|
||||||
|
count++
|
||||||
|
return {
|
||||||
|
id: '123',
|
||||||
|
html: `<div>${count}</div>`,
|
||||||
|
state: {},
|
||||||
|
head: {
|
||||||
|
link: [],
|
||||||
|
style: []
|
||||||
|
},
|
||||||
|
json() {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
vi.stubGlobal('fetch', stubFetch)
|
||||||
|
|
||||||
|
const component = await mountSuspended(createServerComponent('dummyName'))
|
||||||
|
expect(fetch).toHaveBeenCalledOnce()
|
||||||
|
|
||||||
|
expect(component.html()).toBe('<div>1</div>')
|
||||||
|
|
||||||
|
await component.vm.$.exposed!.refresh()
|
||||||
|
expect(fetch).toHaveBeenCalledTimes(2)
|
||||||
|
await nextTick()
|
||||||
|
expect(component.html()).toBe('<div>2</div>')
|
||||||
|
vi.mocked(fetch).mockRestore()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user