diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap
index 373b0795b..215ab9036 100644
--- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap
+++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap
@@ -1,13 +1,13 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`compiler: children transform > children & sibling references 1`] = `
-"import { child as _child, nextn as _nextn, next as _next, createTextNode as _createTextNode, insert as _insert, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
+"import { child as _child, nthChild as _nthChild, next as _next, createTextNode as _createTextNode, insert as _insert, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("
", true)
export function render(_ctx) {
const n4 = t0()
const n0 = _child(n4)
- const n3 = _nextn(n0, 2)
+ const n3 = _nthChild(n4, 2)
const n2 = _next(n3)
const x0 = _child(n0)
const n1 = _createTextNode()
@@ -22,6 +22,19 @@ export function render(_ctx) {
}"
`;
+exports[`compiler: children transform > efficient find 1`] = `
+"import { child as _child, nthChild as _nthChild, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
+const t0 = _template("", true)
+
+export function render(_ctx) {
+ const n1 = t0()
+ const n0 = _nthChild(n1, 2)
+ const x0 = _child(n0)
+ _renderEffect(() => _setText(x0, _toDisplayString(_ctx.msg)))
+ return n1
+}"
+`;
+
exports[`compiler: children transform > efficient traversal 1`] = `
"import { child as _child, next as _next, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("", true)
diff --git a/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts
index 39b1da072..152911dcd 100644
--- a/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts
+++ b/packages/compiler-vapor/__tests__/transforms/transformChildren.spec.ts
@@ -46,4 +46,16 @@ describe('compiler: children transform', () => {
)
expect(code).toMatchSnapshot()
})
+
+ test('efficient find', () => {
+ const { code } = compileWithElementTransform(
+ ``,
+ )
+ expect(code).contains(`const n0 = _nthChild(n1, 2)`)
+ expect(code).toMatchSnapshot()
+ })
})
diff --git a/packages/compiler-vapor/src/generators/template.ts b/packages/compiler-vapor/src/generators/template.ts
index 68d4c20b3..0c27a9192 100644
--- a/packages/compiler-vapor/src/generators/template.ts
+++ b/packages/compiler-vapor/src/generators/template.ts
@@ -70,7 +70,7 @@ export function genChildren(
if (offset === 1) {
push(...genCall(helper('next'), prev[0]))
} else {
- push(...genCall(helper('nextn'), prev[0], String(offset)))
+ push(...genCall(helper('nthChild'), from, String(offset)))
}
} else {
if (newPath.length === 1 && newPath[0] === 0) {
@@ -113,7 +113,7 @@ export function genChildren(
if (i === 1) {
init = genCall(helper('next'), init)
} else if (i > 1) {
- init = genCall(helper('nextn'), init, String(i))
+ init = genCall(helper('nthChild'), resolvedFrom, String(i))
}
}
push(...init!)
diff --git a/packages/runtime-vapor/__tests__/dom/template.spec.ts b/packages/runtime-vapor/__tests__/dom/template.spec.ts
index f34702362..85de30987 100644
--- a/packages/runtime-vapor/__tests__/dom/template.spec.ts
+++ b/packages/runtime-vapor/__tests__/dom/template.spec.ts
@@ -1,5 +1,5 @@
import { template } from '../../src/dom/template'
-import { child, next, nextn } from '../../src/dom/node'
+import { child, next, nthChild } from '../../src/dom/node'
describe('api: template', () => {
test('create element', () => {
@@ -18,6 +18,17 @@ describe('api: template', () => {
expect(root.$root).toBe(true)
})
+ test('nthChild', () => {
+ const t = template('')
+ const root = t()
+ const span = nthChild(root, 0)
+ const b = nthChild(span, 0)
+ const p = nthChild(root, 1)
+ expect(span).toBe(root.firstChild)
+ expect(b).toBe(root.firstChild!.firstChild)
+ expect(p).toBe(root.firstChild!.nextSibling)
+ })
+
test('next', () => {
const t = template('')
const root = t()
@@ -26,7 +37,7 @@ describe('api: template', () => {
expect(span).toBe(root.childNodes[0])
expect(b).toBe(root.childNodes[1])
- expect(nextn(span, 2)).toBe(root.childNodes[2])
+ expect(nthChild(root, 2)).toBe(root.childNodes[2])
expect(next(b)).toBe(root.childNodes[2])
})
})
diff --git a/packages/runtime-vapor/src/dom/node.ts b/packages/runtime-vapor/src/dom/node.ts
index f620acb63..83bc32c57 100644
--- a/packages/runtime-vapor/src/dom/node.ts
+++ b/packages/runtime-vapor/src/dom/node.ts
@@ -19,14 +19,11 @@ export function child(node: ParentNode): Node {
}
/*! #__NO_SIDE_EFFECTS__ */
-export function next(node: Node): Node {
- return node.nextSibling!
+export function nthChild(node: Node, i: number): Node {
+ return node.childNodes[i]
}
/*! #__NO_SIDE_EFFECTS__ */
-export function nextn(node: Node, offset: number = 1): Node {
- for (let i = 0; i < offset; i++) {
- node = node.nextSibling!
- }
- return node
+export function next(node: Node): Node {
+ return node.nextSibling!
}
diff --git a/packages/runtime-vapor/src/index.ts b/packages/runtime-vapor/src/index.ts
index e4b783916..40a847ba8 100644
--- a/packages/runtime-vapor/src/index.ts
+++ b/packages/runtime-vapor/src/index.ts
@@ -10,7 +10,7 @@ export { createComponent, createComponentWithFallback } from './component'
export { renderEffect } from './renderEffect'
export { createSlot } from './componentSlots'
export { template } from './dom/template'
-export { createTextNode, child, next, nextn } from './dom/node'
+export { createTextNode, child, nthChild, next } from './dom/node'
export {
setText,
setHtml,