From 0d1df25f23bb6225860d7ec72411e0253f387a00 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 12 Dec 2024 22:34:35 +0800 Subject: [PATCH] wip(vapor): templateRef adjustments --- packages/compiler-vapor/src/generate.ts | 15 +- .../src/generators/operation.ts | 9 +- .../src/generators/templateRef.ts | 5 +- packages/compiler-vapor/src/ir/index.ts | 1 + packages/compiler-vapor/src/transform.ts | 1 + .../src/transforms/transformTemplateRef.ts | 2 + .../src/helpers/useTemplateRef.ts | 4 +- packages/runtime-dom/src/modules/style.ts | 5 +- .../runtime-vapor/__tests__/apiExpose.spec.ts | 20 +- .../__tests__/dom/templateRef.spec.ts | 172 ++++++++++-------- .../__tests__/errorHandling.spec.ts | 2 +- .../{dom/templateRef.ts => apiTemplateRef.ts} | 37 ++-- packages/runtime-vapor/src/component.ts | 5 +- packages/runtime-vapor/src/index.ts | 2 +- 14 files changed, 170 insertions(+), 110 deletions(-) rename packages/runtime-vapor/src/{dom/templateRef.ts => apiTemplateRef.ts} (74%) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index a13488235..5b8edd9ec 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -16,6 +16,7 @@ import { codeFragmentToString, genCall, } from './generators/utils' +import { setTemplateRefIdent } from './generators/templateRef' export type CodegenOptions = Omit @@ -110,19 +111,21 @@ export function generate( ', ', ) - if (inline) { - // push(`((${signature}) => {`) - } else { + if (!inline) { push(NEWLINE, `export function ${functionName}(${signature}) {`) } push(INDENT_START) + if (ir.hasTemplateRef) { + push( + NEWLINE, + `const ${setTemplateRefIdent} = ${context.helper('createTemplateRefSetter')}()`, + ) + } push(...genBlockContent(ir.block, context, true)) push(INDENT_END, NEWLINE) - if (inline) { - // push('})()') - } else { + if (!inline) { push('}') } diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index a82fc6e4d..50a307d67 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -67,9 +67,14 @@ export function genOperation( return genDeclareOldRef(oper) case IRNodeTypes.SLOT_OUTLET_NODE: return genSlotOutlet(oper, context) + case IRNodeTypes.WITH_DIRECTIVE: + return [] // TODO + default: + const exhaustiveCheck: never = oper + throw new Error( + `Unhandled operation type in genOperation: ${exhaustiveCheck}`, + ) } - - return [] } export function genEffects( diff --git a/packages/compiler-vapor/src/generators/templateRef.ts b/packages/compiler-vapor/src/generators/templateRef.ts index 3de2a96d4..a4d6d546e 100644 --- a/packages/compiler-vapor/src/generators/templateRef.ts +++ b/packages/compiler-vapor/src/generators/templateRef.ts @@ -3,16 +3,17 @@ import type { CodegenContext } from '../generate' import type { DeclareOldRefIRNode, SetTemplateRefIRNode } from '../ir' import { type CodeFragment, NEWLINE, genCall } from './utils' +export const setTemplateRefIdent = `_setTemplateRef` + export function genSetTemplateRef( oper: SetTemplateRefIRNode, context: CodegenContext, ): CodeFragment[] { - const { helper } = context return [ NEWLINE, oper.effect && `r${oper.element} = `, ...genCall( - helper('setRef'), + setTemplateRefIdent, // will be generated in root scope `n${oper.element}`, genExpression(oper.value, context), oper.effect ? `r${oper.element}` : oper.refFor ? 'void 0' : undefined, diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index f1ca98325..011387f67 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -63,6 +63,7 @@ export interface RootIRNode { component: Set directive: Set block: BlockIRNode + hasTemplateRef: boolean } export interface IfIRNode extends BaseIRNode { diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 69e681745..385580899 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -220,6 +220,7 @@ export function transform( component: new Set(), directive: new Set(), block: newBlock(node), + hasTemplateRef: false, } const context = new TransformContext(ir, node, options) diff --git a/packages/compiler-vapor/src/transforms/transformTemplateRef.ts b/packages/compiler-vapor/src/transforms/transformTemplateRef.ts index 8dbd9ae73..9fa7c09bf 100644 --- a/packages/compiler-vapor/src/transforms/transformTemplateRef.ts +++ b/packages/compiler-vapor/src/transforms/transformTemplateRef.ts @@ -15,6 +15,8 @@ export const transformTemplateRef: NodeTransform = (node, context) => { const dir = findProp(node, 'ref', false, true) if (!dir) return + context.ir.hasTemplateRef = true + let value: SimpleExpressionNode if (dir.type === NodeTypes.DIRECTIVE) { value = dir.exp || normalizeBindShorthand(dir.arg!, context) diff --git a/packages/runtime-core/src/helpers/useTemplateRef.ts b/packages/runtime-core/src/helpers/useTemplateRef.ts index 4cb10ea81..9540f25c4 100644 --- a/packages/runtime-core/src/helpers/useTemplateRef.ts +++ b/packages/runtime-core/src/helpers/useTemplateRef.ts @@ -1,5 +1,5 @@ import { type ShallowRef, readonly, shallowRef } from '@vue/reactivity' -import { getCurrentInstance } from '../component' +import { getCurrentGenericInstance } from '../component' import { warn } from '../warning' import { EMPTY_OBJ } from '@vue/shared' @@ -8,7 +8,7 @@ export const knownTemplateRefs: WeakSet = new WeakSet() export function useTemplateRef( key: Keys, ): Readonly> { - const i = getCurrentInstance() + const i = getCurrentGenericInstance() const r = shallowRef(null) if (i) { const refs = i.refs === EMPTY_OBJ ? (i.refs = {}) : i.refs diff --git a/packages/runtime-dom/src/modules/style.ts b/packages/runtime-dom/src/modules/style.ts index ac679e0e3..bcc64c712 100644 --- a/packages/runtime-dom/src/modules/style.ts +++ b/packages/runtime-dom/src/modules/style.ts @@ -7,7 +7,8 @@ import { } from '../directives/vShow' import { CSS_VAR_TEXT } from '../helpers/useCssVars' -type Style = string | Record | null | undefined +type Style = StyleValue | Record +type StyleValue = string | null | undefined const displayRE = /(^|;)\s*display\s*:/ @@ -70,7 +71,7 @@ const importantRE = /\s*!important$/ function setStyle( style: CSSStyleDeclaration, name: string, - val: string | string[], + val: StyleValue | StyleValue[], ) { if (isArray(val)) { val.forEach(v => setStyle(style, name, v)) diff --git a/packages/runtime-vapor/__tests__/apiExpose.spec.ts b/packages/runtime-vapor/__tests__/apiExpose.spec.ts index c521c3e39..03a7e7577 100644 --- a/packages/runtime-vapor/__tests__/apiExpose.spec.ts +++ b/packages/runtime-vapor/__tests__/apiExpose.spec.ts @@ -1,6 +1,6 @@ import { ref, shallowRef } from '@vue/reactivity' import { type VaporComponentInstance, createComponent } from '../src/component' -import { setRef } from '../src/dom/templateRef' +import { setRef } from '../src/apiTemplateRef' import { makeRender } from './_utils' import { currentInstance } from '@vue/runtime-dom' import { defineVaporComponent } from '../src/apiDefineComponent' @@ -8,7 +8,8 @@ import { defineVaporComponent } from '../src/apiDefineComponent' const define = makeRender() describe('api: expose', () => { - test.todo('via setup context + template ref', () => { + test('via setup context + template ref', () => { + let i: any const Child = defineVaporComponent({ setup(_, { expose }) { expose({ @@ -20,19 +21,20 @@ describe('api: expose', () => { }) const childRef = ref() define({ - render: () => { - const n0 = createComponent(Child) + setup: () => { + const n0 = (i = createComponent(Child)) + setRef(currentInstance as VaporComponentInstance, n0, childRef) return n0 }, }).render() - expect(childRef.value).toBeTruthy() + expect(childRef.value).toBe(i.exposeProxy) expect(childRef.value.foo).toBe(1) expect(childRef.value.bar).toBe(2) expect(childRef.value.baz).toBeUndefined() }) - test.todo('via setup context + template ref (expose empty)', () => { + test('via setup context + template ref (expose empty)', () => { let childInstance: VaporComponentInstance | null = null const Child = defineVaporComponent({ setup(_) { @@ -42,14 +44,14 @@ describe('api: expose', () => { }) const childRef = shallowRef() define({ - render: () => { + setup: () => { const n0 = createComponent(Child) - setRef(n0, childRef) + setRef(currentInstance as VaporComponentInstance, n0, childRef) return n0 }, }).render() - expect(childInstance!.exposed).toBeUndefined() + expect(childInstance!.exposed).toBeNull() expect(childRef.value).toBe(childInstance!) }) diff --git a/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts b/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts index 5fc64782e..1b912ed29 100644 --- a/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts +++ b/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts @@ -1,10 +1,10 @@ -import type { NodeRef } from '../../src/dom/templateRef' +import type { NodeRef } from '../../src/apiTemplateRef' import { createFor, createIf, + createTemplateRefSetter, insert, renderEffect, - setRef, setText, template, } from '../../src' @@ -19,7 +19,7 @@ import { const define = makeRender() -describe.todo('api: template ref', () => { +describe('api: template ref', () => { test('string ref mount', () => { const t0 = template('
') const el = ref(null) @@ -31,7 +31,7 @@ describe.todo('api: template ref', () => { }, render() { const n0 = t0() - setRef(n0 as Element, 'refKey') + createTemplateRefSetter()(n0 as Element, 'refKey') return n0 }, }) @@ -57,7 +57,7 @@ describe.todo('api: template ref', () => { const n0 = t0() let r0: NodeRef | undefined renderEffect(() => { - r0 = setRef(n0 as Element, refKey.value, r0) + r0 = createTemplateRefSetter()(n0 as Element, refKey.value, r0) }) return n0 }, @@ -72,7 +72,7 @@ describe.todo('api: template ref', () => { expect(fooEl.value).toBe(null) }) - it('string ref unmount', async () => { + it.todo('string ref unmount', async () => { const t0 = template('
') const el = ref(null) const toggle = ref(true) @@ -84,6 +84,7 @@ describe.todo('api: template ref', () => { } }, render() { + const setRef = createTemplateRefSetter() const n0 = createIf( () => toggle.value, () => { @@ -109,7 +110,7 @@ describe.todo('api: template ref', () => { const { render } = define({ render() { const n0 = t0() - setRef(n0 as Element, fn) + createTemplateRefSetter()(n0 as Element, fn) return n0 }, }) @@ -129,7 +130,7 @@ describe.todo('api: template ref', () => { const n0 = t0() let r0: NodeRef | undefined renderEffect(() => { - r0 = setRef(n0 as Element, fn.value, r0) + r0 = createTemplateRefSetter()(n0 as Element, fn.value, r0) }) return n0 }, @@ -148,7 +149,7 @@ describe.todo('api: template ref', () => { expect(fn2.mock.calls[0][0]).toBe(host.children[0]) }) - it('function ref unmount', async () => { + it.todo('function ref unmount', async () => { const fn = vi.fn() const toggle = ref(true) @@ -159,7 +160,7 @@ describe.todo('api: template ref', () => { () => toggle.value, () => { const n1 = t0() - setRef(n1 as Element, fn) + createTemplateRefSetter()(n1 as Element, fn) return n1 }, ) @@ -185,7 +186,7 @@ describe.todo('api: template ref', () => { }, render() { const n0 = t0() - setRef(n0 as Element, 'refKey') + createTemplateRefSetter()(n0 as Element, 'refKey') return n0 }, }) @@ -213,9 +214,9 @@ describe.todo('api: template ref', () => { const n0 = t0() const n1 = t1() const n2 = t2() - setRef(n0 as Element, 'refKey1') - setRef(n1 as Element, 'refKey2') - setRef(n2 as Element, 'refKey3') + createTemplateRefSetter()(n0 as Element, 'refKey1') + createTemplateRefSetter()(n1 as Element, 'refKey2') + createTemplateRefSetter()(n2 as Element, 'refKey3') return [n0, n1, n2] }, }) @@ -234,7 +235,7 @@ describe.todo('api: template ref', () => { const { render } = define({ render() { const n0 = t0() - setRef(n0 as Element, el) + createTemplateRefSetter()(n0 as Element, el) renderEffect(() => { setText(n0, el.value && el.value.getAttribute('id')) }) @@ -265,10 +266,18 @@ describe.todo('api: template ref', () => { let r0: NodeRef | undefined let r1: NodeRef | undefined renderEffect(() => { - r0 = setRef(n0 as Element, refToggle.value ? 'foo' : 'bar', r0) + r0 = createTemplateRefSetter()( + n0 as Element, + refToggle.value ? 'foo' : 'bar', + r0, + ) }) renderEffect(() => { - r1 = setRef(n1 as Element, refToggle.value ? 'bar' : 'foo', r1) + r1 = createTemplateRefSetter()( + n1 as Element, + refToggle.value ? 'bar' : 'foo', + r1, + ) }) watchEffect( () => { @@ -297,7 +306,7 @@ describe.todo('api: template ref', () => { }) // #1789 - test('toggle the same ref to different elements', async () => { + test.todo('toggle the same ref to different elements', async () => { const refToggle = ref(false) const spy = vi.fn() @@ -306,6 +315,7 @@ describe.todo('api: template ref', () => { const { render } = define({ render() { const instance = currentInstance! + const setRef = createTemplateRefSetter() const n0 = createIf( () => refToggle.value, () => { @@ -341,7 +351,7 @@ describe.todo('api: template ref', () => { }) // compiled output of v-for + template ref - test('ref in v-for', async () => { + test.todo('ref in v-for', async () => { const show = ref(true) const list = reactive([1, 2, 3]) const listRefs = ref([]) @@ -359,7 +369,12 @@ describe.todo('api: template ref', () => { () => list, state => { const n1 = t1() - setRef(n1 as Element, listRefs, undefined, true) + createTemplateRefSetter()( + n1 as Element, + listRefs, + undefined, + true, + ) renderEffect(() => { const [item] = state setText(n1, item) @@ -396,7 +411,7 @@ describe.todo('api: template ref', () => { expect(mapRefs()).toMatchObject(['2', '3', '4']) }) - test('named ref in v-for', async () => { + test.todo('named ref in v-for', async () => { const show = ref(true) const list = reactive([1, 2, 3]) const listRefs = ref([]) @@ -417,7 +432,12 @@ describe.todo('api: template ref', () => { () => list, state => { const n1 = t1() - setRef(n1 as Element, 'listRefs', undefined, true) + createTemplateRefSetter()( + n1 as Element, + 'listRefs', + undefined, + true, + ) renderEffect(() => { const [item] = state setText(n1, item) @@ -455,59 +475,67 @@ describe.todo('api: template ref', () => { }) // #6697 v-for ref behaves differently under production and development - test('named ref in v-for , should be responsive when rendering', async () => { - const list = ref([1, 2, 3]) - const listRefs = ref([]) + test.todo( + 'named ref in v-for , should be responsive when rendering', + async () => { + const list = ref([1, 2, 3]) + const listRefs = ref([]) - const t0 = template('
    ') - const t1 = template('
  • ') - const { render } = define({ - setup() { - return { listRefs } - }, - render() { - const n0 = t0() - const n1 = n0.firstChild - const n2 = n1!.nextSibling! - const n3 = createFor( - () => list.value, - state => { - const n4 = t1() - setRef(n4 as Element, 'listRefs', undefined, true) - renderEffect(() => { - const [item] = state - setText(n4, item) - }) - return n4 - }, - ) - insert(n3, n2 as unknown as ParentNode) - renderEffect(() => { - setText(n1!, String(listRefs.value)) - }) - return n0 - }, - }) + const t0 = template('
      ') + const t1 = template('
    • ') + const { render } = define({ + setup() { + return { listRefs } + }, + render() { + const n0 = t0() + const n1 = n0.firstChild + const n2 = n1!.nextSibling! + const n3 = createFor( + () => list.value, + state => { + const n4 = t1() + createTemplateRefSetter()( + n4 as Element, + 'listRefs', + undefined, + true, + ) + renderEffect(() => { + const [item] = state + setText(n4, item) + }) + return n4 + }, + ) + insert(n3, n2 as unknown as ParentNode) + renderEffect(() => { + setText(n1!, String(listRefs.value)) + }) + return n0 + }, + }) - const { host } = render() + const { host } = render() - await nextTick() - expect(String(listRefs.value)).toBe( - '[object HTMLLIElement],[object HTMLLIElement],[object HTMLLIElement]', - ) - expect(host.innerHTML).toBe( - '
      [object HTMLLIElement],[object HTMLLIElement],[object HTMLLIElement]
      • 1
      • 2
      • 3
      ', - ) + await nextTick() + expect(String(listRefs.value)).toBe( + '[object HTMLLIElement],[object HTMLLIElement],[object HTMLLIElement]', + ) + expect(host.innerHTML).toBe( + '
      [object HTMLLIElement],[object HTMLLIElement],[object HTMLLIElement]
      • 1
      • 2
      • 3
      ', + ) - list.value.splice(0, 1) - await nextTick() - expect(String(listRefs.value)).toBe( - '[object HTMLLIElement],[object HTMLLIElement]', - ) - expect(host.innerHTML).toBe( - '
      [object HTMLLIElement],[object HTMLLIElement]
      • 2
      • 3
      ', - ) - }) + list.value.splice(0, 1) + await nextTick() + expect(String(listRefs.value)).toBe( + '[object HTMLLIElement],[object HTMLLIElement]', + ) + expect(host.innerHTML).toBe( + '
      [object HTMLLIElement],[object HTMLLIElement]
      • 2
      • 3
      ', + ) + }, + ) // TODO: need to implement Component slots // test('string ref inside slots', async () => { @@ -523,7 +551,7 @@ describe.todo('api: template ref', () => { // spy(this.$refs.foo.tag) // }) // const n0 = createComponent(Child) - // setRef(n0, 'foo') + // createTemplateRefSetter()(n0, 'foo') // return n0 // }, // }) diff --git a/packages/runtime-vapor/__tests__/errorHandling.spec.ts b/packages/runtime-vapor/__tests__/errorHandling.spec.ts index d0f5d1c4c..2300cf9ff 100644 --- a/packages/runtime-vapor/__tests__/errorHandling.spec.ts +++ b/packages/runtime-vapor/__tests__/errorHandling.spec.ts @@ -9,7 +9,7 @@ import { import { createComponent, setRef, template } from '../src' import { makeRender } from './_utils' import type { VaporComponent } from '../src/component' -import type { RefEl } from '../src/dom/templateRef' +import type { RefEl } from '../src/apiTemplateRef' const define = makeRender() diff --git a/packages/runtime-vapor/src/dom/templateRef.ts b/packages/runtime-vapor/src/apiTemplateRef.ts similarity index 74% rename from packages/runtime-vapor/src/dom/templateRef.ts rename to packages/runtime-vapor/src/apiTemplateRef.ts index b17a7eea5..1e4984cf2 100644 --- a/packages/runtime-vapor/src/dom/templateRef.ts +++ b/packages/runtime-vapor/src/apiTemplateRef.ts @@ -4,7 +4,7 @@ import { currentInstance, getExposed, isVaporComponent, -} from '../component' +} from './component' import { type SchedulerJob, callWithErrorHandling, @@ -23,30 +23,41 @@ import { export type NodeRef = string | Ref | ((ref: Element) => void) export type RefEl = Element | VaporComponentInstance +export type setRefFn = ( + el: RefEl, + ref: NodeRef, + oldRef?: NodeRef, + refFor?: boolean, +) => NodeRef | undefined + +export function createTemplateRefSetter(): setRefFn { + const instance = currentInstance as VaporComponentInstance + return (...args) => setRef(instance, ...args) +} + /** * Function for handling a template ref */ export function setRef( + instance: VaporComponentInstance, el: RefEl, ref: NodeRef, oldRef?: NodeRef, refFor = false, ): NodeRef | undefined { - if (!currentInstance || currentInstance.isUnmounted) return + if (!instance || instance.isUnmounted) return - const setupState = currentInstance.setupState || {} + const setupState: any = __DEV__ ? instance.setupState || {} : null const refValue = isVaporComponent(el) ? getExposed(el) || el : el const refs = - currentInstance.refs === EMPTY_OBJ - ? (currentInstance.refs = {}) - : currentInstance.refs + instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs // dynamic ref changed. unset old ref if (oldRef != null && oldRef !== ref) { if (isString(oldRef)) { refs[oldRef] = null - if (hasOwn(setupState, oldRef)) { + if (__DEV__ && hasOwn(setupState, oldRef)) { setupState[oldRef] = null } } else if (isRef(oldRef)) { @@ -66,6 +77,7 @@ export function setRef( } invokeRefSetter(refValue) + // TODO this gets called repeatedly in renderEffect when it's dynamic ref? onScopeDispose(() => invokeRefSetter()) } else { const _isString = isString(ref) @@ -76,7 +88,7 @@ export function setRef( const doSet: SchedulerJob = () => { if (refFor) { existing = _isString - ? hasOwn(setupState, ref) + ? __DEV__ && hasOwn(setupState, ref) ? setupState[ref] : refs[ref] : ref.value @@ -85,7 +97,7 @@ export function setRef( existing = [refValue] if (_isString) { refs[ref] = existing - if (hasOwn(setupState, ref)) { + if (__DEV__ && hasOwn(setupState, ref)) { setupState[ref] = refs[ref] // if setupState[ref] is a reactivity ref, // the existing will also become reactivity too @@ -100,7 +112,7 @@ export function setRef( } } else if (_isString) { refs[ref] = refValue - if (hasOwn(setupState, ref)) { + if (__DEV__ && hasOwn(setupState, ref)) { setupState[ref] = refValue } } else if (_isRef) { @@ -112,13 +124,14 @@ export function setRef( doSet.id = -1 queuePostFlushCb(doSet) + // TODO this gets called repeatedly in renderEffect when it's dynamic ref? onScopeDispose(() => { queuePostFlushCb(() => { if (isArray(existing)) { remove(existing, refValue) } else if (_isString) { refs[ref] = null - if (hasOwn(setupState, ref)) { + if (__DEV__ && hasOwn(setupState, ref)) { setupState[ref] = null } } else if (_isRef) { @@ -127,7 +140,7 @@ export function setRef( }) }) } else if (__DEV__) { - // warn('Invalid template ref type:', ref, `(${typeof ref})`) + warn('Invalid template ref type:', ref, `(${typeof ref})`) } } return ref diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 069bb88b6..562037927 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -31,6 +31,7 @@ import { pauseTracking, proxyRefs, resetTracking, + unref, } from '@vue/reactivity' import { EMPTY_OBJ, invokeArrayFns, isFunction, isString } from '@vue/shared' import { @@ -485,7 +486,9 @@ export function getExposed( if (instance.exposed) { return ( instance.exposeProxy || - (instance.exposeProxy = proxyRefs(markRaw(instance.exposed))) + (instance.exposeProxy = new Proxy(markRaw(instance.exposed), { + get: (target, key) => unref(target[key as any]), + })) ) } } diff --git a/packages/runtime-vapor/src/index.ts b/packages/runtime-vapor/src/index.ts index 543544112..f9f2e5253 100644 --- a/packages/runtime-vapor/src/index.ts +++ b/packages/runtime-vapor/src/index.ts @@ -25,4 +25,4 @@ export { export { on, delegate, delegateEvents, setDynamicEvents } from './dom/event' export { createIf } from './apiCreateIf' export { createFor } from './apiCreateFor' -export { setRef } from './dom/templateRef' +export { createTemplateRefSetter } from './apiTemplateRef'