mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 21:25:11 +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.
|
||||
|
||||
- `#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
|
||||
}
|
||||
},
|
||||
async setup (props, { slots }) {
|
||||
async setup (props, { slots, expose }) {
|
||||
const error = ref<unknown>(null)
|
||||
const config = useRuntimeConfig()
|
||||
const nuxtApp = useNuxtApp()
|
||||
@ -160,6 +160,10 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
expose({
|
||||
refresh: () => fetchComponent(true)
|
||||
})
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.on(`nuxt-server-component:${props.name}`, () => {
|
||||
fetchComponent(true)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { defineComponent, h } from 'vue'
|
||||
import { defineComponent, h, ref } from 'vue'
|
||||
import NuxtIsland from '#app/components/nuxt-island'
|
||||
|
||||
/*@__NO_SIDE_EFFECTS__*/
|
||||
@ -7,12 +7,19 @@ export const createServerComponent = (name: string) => {
|
||||
name,
|
||||
inheritAttrs: false,
|
||||
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 h(NuxtIsland, {
|
||||
name,
|
||||
lazy: props.lazy,
|
||||
props: attrs
|
||||
props: attrs,
|
||||
ref: islandRef
|
||||
}, slots)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { h } from 'vue'
|
||||
import { h, nextTick } from 'vue'
|
||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||
import { createServerComponent } from '../../packages/nuxt/src/components/runtime/server-component'
|
||||
import { createSimpleRemoteIslandProvider } from '../fixtures/remote-provider'
|
||||
@ -65,4 +65,35 @@ describe('runtime server component', () => {
|
||||
|
||||
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