From: daiwei Date: Tue, 10 Jun 2025 08:30:51 +0000 (+0800) Subject: feat(runtime-vapor): add v-once support to createDynamicComponent X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d81c0b854a5fc4eeaa922891a07d5300e7979c3;p=thirdparty%2Fvuejs%2Fcore.git feat(runtime-vapor): add v-once support to createDynamicComponent --- diff --git a/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts b/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts index 2f6cd7b3f3..448bd2c315 100644 --- a/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts +++ b/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts @@ -1,4 +1,4 @@ -import { shallowRef } from '@vue/reactivity' +import { ref, shallowRef } from '@vue/reactivity' import { nextTick } from '@vue/runtime-dom' import { createDynamicComponent } from '../src' import { makeRender } from './_utils' @@ -54,4 +54,42 @@ describe('api: createDynamicComponent', () => { await nextTick() expect(html()).toBe('') }) + + test('with v-once', async () => { + const val = shallowRef(A) + + const { html } = define({ + setup() { + return createDynamicComponent(() => val.value, null, null, true, true) + }, + }).render() + + expect(html()).toBe('AAA') + + val.value = B + await nextTick() + expect(html()).toBe('AAA') // still AAA + }) + + test('fallback with v-once', async () => { + const val = shallowRef('button') + const id = ref(0) + const { html } = define({ + setup() { + return createDynamicComponent( + () => val.value, + { id: () => id.value }, + null, + true, + true, + ) + }, + }).render() + + expect(html()).toBe('') + + id.value++ + await nextTick() + expect(html()).toBe('') + }) }) diff --git a/packages/runtime-vapor/src/apiCreateDynamicComponent.ts b/packages/runtime-vapor/src/apiCreateDynamicComponent.ts index a8f55bab63..a1b1e3e98f 100644 --- a/packages/runtime-vapor/src/apiCreateDynamicComponent.ts +++ b/packages/runtime-vapor/src/apiCreateDynamicComponent.ts @@ -15,7 +15,8 @@ export function createDynamicComponent( const frag = __DEV__ ? new DynamicFragment('dynamic-component') : new DynamicFragment() - renderEffect(() => { + + const renderFn = () => { const value = getter() frag.update( () => @@ -28,6 +29,10 @@ export function createDynamicComponent( ), value, ) - }) + } + + if (once) renderFn() + else renderEffect(renderFn) + return frag } diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index a2b2342d93..27f14f7122 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -479,9 +479,10 @@ export function createComponentWithFallback( ;(el as any).$root = isSingleRoot if (rawProps) { - renderEffect(() => { + const setFn = () => setDynamicProps(el, [resolveDynamicProps(rawProps as RawProps)]) - }) + if (once) setFn() + else renderEffect(setFn) } if (rawSlots) {