diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap
index b469ea52d..da9a78950 100644
--- a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap
+++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap
@@ -5,11 +5,12 @@ exports[`comile > bindings 1`] = `
import { template, setText } from 'vue/vapor'
const t0 = template(\`
\`)
export function render() {
-const root = t0()
+const n0 = t0()
watchEffect(() => {
setText(n0, undefined, count.value)
})
-return root
+return n0
+
}"
`;
@@ -18,11 +19,12 @@ exports[`comile > directives > v-bind > simple expression 1`] = `
import { template, setAttr } from 'vue/vapor'
const t0 = template(\`\`)
export function render() {
-const root = t0()
+const n0 = t0()
watchEffect(() => {
setAttr(n0, \\"id\\", undefined, id.value)
})
-return root
+return n0
+
}"
`;
@@ -31,11 +33,12 @@ exports[`comile > directives > v-html > no expression 1`] = `
import { template, setHtml } from 'vue/vapor'
const t0 = template(\`\`)
export function render() {
-const root = t0()
+const n0 = t0()
watchEffect(() => {
setHtml(n0, undefined, \\"\\")
})
-return root
+return n0
+
}"
`;
@@ -44,11 +47,12 @@ exports[`comile > directives > v-html > simple expression 1`] = `
import { template, setHtml } from 'vue/vapor'
const t0 = template(\`\`)
export function render() {
-const root = t0()
+const n0 = t0()
watchEffect(() => {
setHtml(n0, undefined, code.value)
})
-return root
+return n0
+
}"
`;
@@ -57,11 +61,12 @@ exports[`comile > directives > v-on > simple expression 1`] = `
import { template, on } from 'vue/vapor'
const t0 = template(\`\`)
export function render() {
-const root = t0()
+const n0 = t0()
watchEffect(() => {
on(n0, \\"click\\", handleClick)
})
-return root
+return n0
+
}"
`;
@@ -69,13 +74,14 @@ exports[`comile > directives > v-once 1`] = `
"import { template, children, insert, setText, setAttr } from 'vue/vapor'
const t0 = template(\`
\`)
export function render() {
-const root = t0()
-const { 1: [n2],} = children(root)
+const n0 = t0()
+const { 1: [n2],} = children(n0)
const n1 = document.createTextNode(msg.value)
insert(n1, n0, 0 /* InsertPosition.FIRST */)
setText(n1, undefined, msg.value)
setAttr(n2, \\"class\\", undefined, clz.value)
-return root
+return n0
+
}"
`;
@@ -84,11 +90,12 @@ exports[`comile > directives > v-text > no expression 1`] = `
import { template, setText } from 'vue/vapor'
const t0 = template(\`\`)
export function render() {
-const root = t0()
+const n0 = t0()
watchEffect(() => {
setText(n0, undefined, \\"\\")
})
-return root
+return n0
+
}"
`;
@@ -97,11 +104,12 @@ exports[`comile > directives > v-text > simple expression 1`] = `
import { template, setText } from 'vue/vapor'
const t0 = template(\`\`)
export function render() {
-const root = t0()
+const n0 = t0()
watchEffect(() => {
setText(n0, undefined, str.value)
})
-return root
+return n0
+
}"
`;
@@ -109,7 +117,8 @@ exports[`comile > static template 1`] = `
"import { template } from 'vue/vapor'
const t0 = template(\`\`)
export function render() {
-const root = t0()
-return root
+const n0 = t0()
+return n0
+
}"
`;
diff --git a/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap
index 4a4d7c6ce..fdf4d1cd9 100644
--- a/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap
+++ b/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap
@@ -3,8 +3,8 @@
exports[`fixtures 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
import { watchEffect } from 'vue'
-import { template, insert, setText, on, setHtml } from 'vue/vapor'
-const t0 = template(\`Counter
Count:
Double:
once:
{{ count }}
\`)
+import { template, children, insert, setText, on, setHtml } from 'vue/vapor'
+const t0 = template(\`Counter
Count:
Double:
once:
{{ count }}
\`)
import { ref, computed } from 'vue'
const html = 'HTML'
@@ -19,7 +19,8 @@ const increment = () => count.value++
return (() => {
-const root = t0()
+const n8 = t0()
+const { 1: [n0], 2: [n2], 3: [n4], 4: [n5], 6: [n6],} = children(n8)
const n1 = document.createTextNode(count.value)
insert(n1, n0)
const n3 = document.createTextNode(double.value)
@@ -39,7 +40,8 @@ on(n4, \\"click\\", increment)
watchEffect(() => {
setHtml(n5, undefined, html)
})
-return root
+return n8
+
})();
}
diff --git a/packages/compiler-vapor/__tests__/fixtures/counter.vue b/packages/compiler-vapor/__tests__/fixtures/counter.vue
index c780b459d..d09cfd2e0 100644
--- a/packages/compiler-vapor/__tests__/fixtures/counter.vue
+++ b/packages/compiler-vapor/__tests__/fixtures/counter.vue
@@ -10,12 +10,14 @@ const html = 'HTML'
- Counter
- Count: {{ count }}
- Double: {{ double }}
-
-
-
- once: {{ count }}
- {{ count }}
+
+
Counter
+
Count: {{ count }}
+
Double: {{ double }}
+
+
+
+
once: {{ count }}
+
{{ count }}
+
diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts
index e2ed01b73..ff4c497ff 100644
--- a/packages/compiler-vapor/src/generate.ts
+++ b/packages/compiler-vapor/src/generate.ts
@@ -27,29 +27,32 @@ export function generate(
vaporHelpers.add('template')
}
- // TODO multiple-template
- code += `const root = t0()\n`
- if (ir.children[0] && Object.keys(ir.children[0].children).length) {
- code += `const {${genChildren(ir.children[0].children)}} = children(root)\n`
- vaporHelpers.add('children')
- }
+ for (const [, { id, children }] of Object.entries(ir.children)) {
+ code += `const n${id} = t0()\n`
- for (const operation of ir.operation) {
- code += genOperation(operation)
- }
+ if (Object.keys(children).length) {
+ code += `const {${genChildren(children)}} = children(n${id})\n`
+ vaporHelpers.add('children')
+ }
- for (const [_expr, operations] of Object.entries(ir.effect)) {
- // TODO don't use watchEffect from vue/core, implement `effect` function in runtime-vapor package
- let scope = `watchEffect(() => {\n`
- helpers.add('watchEffect')
- for (const operation of operations) {
- scope += genOperation(operation)
+ for (const operation of ir.operation) {
+ code += genOperation(operation)
}
- scope += '})\n'
- code += scope
- }
- code += 'return root'
+ for (const [_expr, operations] of Object.entries(ir.effect)) {
+ // TODO don't use watchEffect from vue/core, implement `effect` function in runtime-vapor package
+ let scope = `watchEffect(() => {\n`
+ helpers.add('watchEffect')
+ for (const operation of operations) {
+ scope += genOperation(operation)
+ }
+ scope += '})\n'
+ code += scope
+ }
+
+ // TODO multiple-template
+ code += `return n${id}\n`
+ }
if (vaporHelpers.size)
preamble =
diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts
index 3ce7ff375..28a6eac70 100644
--- a/packages/compiler-vapor/src/transform.ts
+++ b/packages/compiler-vapor/src/transform.ts
@@ -121,7 +121,7 @@ function createContext(
if (ctx.once) {
return ctx.registerOpration(operation)
}
- parent.registerEffect(expr, operation)
+ return parent.registerEffect(expr, operation)
},
}
return ctx
@@ -168,6 +168,9 @@ function transformChildren(
const isFirst = i === 0
const isLast = i === children.length - 1
+ // TODO: multiple root elements
+ if (root) child.store = true
+
switch (node.type) {
case 1 satisfies NodeTypes.ELEMENT: {
transformElement(child as TransformContext)
diff --git a/playground/src/App-root.vue b/playground/src/App-root.vue
new file mode 100644
index 000000000..74531c510
--- /dev/null
+++ b/playground/src/App-root.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/playground/src/main.ts b/playground/src/main.ts
index c458e0959..261042c33 100644
--- a/playground/src/main.ts
+++ b/playground/src/main.ts
@@ -1,9 +1,11 @@
import { render } from 'vue/vapor'
-import App from './App.vue'
-render(() => {
- // @ts-expect-error
- const returned = App.setup({}, { expose() {} })
- // @ts-expect-error
- return App.render(returned)
-}, '#app')
+const modules = import.meta.glob('./*.vue')
+const mod = (modules['.' + location.pathname] || modules['./App.vue'])()
+
+mod.then(({ default: m }) => {
+ render(() => {
+ const returned = m.setup({}, { expose() {} })
+ return m.render(returned)
+ }, '#app')
+})