From: Evan You Date: Wed, 11 Dec 2024 06:27:54 +0000 (+0800) Subject: chore: Merge branch 'main' into vapor X-Git-Tag: v3.6.0-alpha.1~16^2~160 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=64e007eabee0e168ff4d0d628c1177dacd1109a7;p=thirdparty%2Fvuejs%2Fcore.git chore: Merge branch 'main' into vapor --- 64e007eabee0e168ff4d0d628c1177dacd1109a7 diff --cc packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 426fd4e1fe,843b58e00f..c4551d506c --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compile > bindings 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { @@@ -148,7 -152,7 +149,7 @@@ export function render(_ctx, $props, $e `; exports[`compile > directives > v-pre > should not affect siblings after it 1`] = ` - "import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { resolveComponent as _resolveComponent, createComponent as _createComponent, createTextNode as _createTextNode, insert as _insert, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, createTextNode as _createTextNode, insert as _insert, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
{{ bar }}
") const t1 = _template("
") @@@ -156,10 -160,11 +157,11 @@@ export function render(_ctx, $props, $e const _component_Comp = _resolveComponent("Comp") const n0 = t0() const n3 = t1() - const n1 = _createComponent(_component_Comp) + const n1 = _createComponentWithFallback(_component_Comp) const n2 = _createTextNode(() => [_ctx.bar]) _insert([n1, n2], n3) - _renderEffect(() => _setDOMProp(n3, "id", _ctx.foo)) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n3, "id", (_foo = _ctx.foo))) return [n0, n3] }" `; @@@ -174,15 -179,22 +176,21 @@@ export function render(_ctx) `; exports[`compile > dynamic root nodes and interpolation 1`] = ` - "import { delegate as _delegate, renderEffect as _renderEffect, setText as _setText, setDOMProp as _setDOMProp, delegateEvents as _delegateEvents, template as _template } from 'vue'; -"import { delegate as _delegate, setInheritAttrs as _setInheritAttrs, setText as _setText, setDOMProp as _setDOMProp, renderEffect as _renderEffect, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; ++"import { delegate as _delegate, setText as _setText, setDOMProp as _setDOMProp, renderEffect as _renderEffect, delegateEvents as _delegateEvents, template as _template } from 'vue'; const t0 = _template("") _delegateEvents("click") export function render(_ctx) { const n0 = t0() _delegate(n0, "click", () => _ctx.handleClick) - _renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) - _renderEffect(() => _setDOMProp(n0, "id", _ctx.count)) - _setInheritAttrs(["id"]) + let _count + _renderEffect(() => { + if(_count !== _ctx.count) { + _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count) + _setDOMProp(n0, "id", _ctx.count) + _count = _ctx.count + } + }) return n0 }" `; @@@ -195,11 -207,13 +203,12 @@@ exports[`compile > expression parsing `; exports[`compile > expression parsing > v-bind 1`] = ` -"((_ctx) => { +" const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true)) - _setInheritAttrs(true) + let _key_value, _foo, _key_value_foo + _renderEffect(() => (_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true))) return n0 -})()" +" `; exports[`compile > fragment 1`] = ` diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index 54558eddc0,db2dbaa575..96cca1703d --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: children transform > children & sibling references 1`] = ` - "import { next as _next, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { next as _next, createTextNode as _createTextNode, insert as _insert, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { next as _next, createTextNode as _createTextNode, insert as _insert, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("

") export function render(_ctx) { diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap index 50bd8d6e54,2b5ab36802..0aabad8075 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap @@@ -293,12 -297,14 +293,13 @@@ export function render(_ctx) `; exports[`compiler: element transform > props merging: class 1`] = ` - "import { renderEffect as _renderEffect, setClass as _setClass, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setClass as _setClass, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setClass as _setClass, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setClass(n0, ["foo", { bar: _ctx.isBar }], true)) - _setInheritAttrs(["class"]) + let _isBar + _renderEffect(() => _isBar !== _ctx.isBar && _setClass(n0, ["foo", { bar: (_isBar = _ctx.isBar) }], true)) return n0 }" `; @@@ -321,7 -327,7 +322,7 @@@ export function render(_ctx) `; exports[`compiler: element transform > props merging: style 1`] = ` - "import { renderEffect as _renderEffect, setStyle as _setStyle, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setStyle as _setStyle, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setStyle as _setStyle, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -342,51 -350,59 +343,55 @@@ export function render(_ctx) `; exports[`compiler: element transform > v-bind="obj" 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true)) - _setInheritAttrs(true) + let _obj + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj], true))) return n0 }" `; exports[`compiler: element transform > v-bind="obj" after static prop 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true)) - _setInheritAttrs(true) + let _obj + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj], true))) return n0 }" `; exports[`compiler: element transform > v-bind="obj" before static prop 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true)) - _setInheritAttrs(true) + let _obj + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj, { id: "foo" }], true))) return n0 }" `; exports[`compiler: element transform > v-bind="obj" between static props 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true)) - _setInheritAttrs(true) + let _obj + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true))) return n0 }" `; exports[`compiler: element transform > v-on="obj" 1`] = ` - "import { renderEffect as _renderEffect, setDynamicEvents as _setDynamicEvents, template as _template } from 'vue'; -"import { setDynamicEvents as _setDynamicEvents, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicEvents as _setDynamicEvents, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/transformRef.spec.ts.snap index bf50a8e82a,bf50a8e82a..a59b17d942 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformRef.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformRef.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: template ref transform > dynamic ref 1`] = ` --"import { renderEffect as _renderEffect, setRef as _setRef, template as _template } from 'vue/vapor'; ++"import { renderEffect as _renderEffect, setRef as _setRef, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -10,10 -10,10 +10,10 @@@ _renderEffect(() => r0 = _setRef(n0, _ctx.foo, r0)) return n0 }" --`; ++` exports[`compiler: template ref transform > ref + v-for 1`] = ` --"import { setRef as _setRef, createFor as _createFor, template as _template } from 'vue/vapor'; ++"import { setRef as _setRef, createFor as _createFor, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -24,10 -24,10 +24,10 @@@ }) return n0 }" --`; ++` exports[`compiler: template ref transform > ref + v-if 1`] = ` --"import { setRef as _setRef, createIf as _createIf, template as _template } from 'vue/vapor'; ++"import { setRef as _setRef, createIf as _createIf, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -38,10 -38,10 +38,10 @@@ }) return n0 }" --`; ++` exports[`compiler: template ref transform > static ref 1`] = ` --"import { setRef as _setRef, template as _template } from 'vue/vapor'; ++"import { setRef as _setRef, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -49,4 -49,4 +49,4 @@@ _setRef(n0, "foo") return n0 }" --`; ++` diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap index 776ba351b1,efada2de91..15b9a5431f --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: template ref transform > dynamic ref 1`] = ` - "import { renderEffect as _renderEffect, setRef as _setRef, template as _template } from 'vue'; -"import { setRef as _setRef, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setRef as _setRef, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap index 41da9defd3,f40057f386..5710d104e5 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@@ -1,336 -1,401 +1,371 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler v-bind > .attr modifier 1`] = ` - "import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id)) - _setInheritAttrs(["foo-bar"]) + let _id + _renderEffect(() => _id !== _ctx.id && _setAttr(n0, "foo-bar", (_id = _ctx.id))) return n0 }" `; exports[`compiler v-bind > .attr modifier w/ innerHTML 1`] = ` - "import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setAttr(n0, "innerHTML", _ctx.foo)) - _setInheritAttrs(["innerHTML"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "innerHTML", (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .attr modifier w/ no expression 1`] = ` - "import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar)) - _setInheritAttrs(["foo-bar"]) + let _fooBar + _renderEffect(() => _fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", (_fooBar = _ctx.fooBar))) return n0 }" `; exports[`compiler v-bind > .attr modifier w/ progress value 1`] = ` - "import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setAttr(n0, "value", _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .attr modifier w/ textContent 1`] = ` - "import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setAttr(n0, "textContent", _ctx.foo)) - _setInheritAttrs(["textContent"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "textContent", (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .attr modifier w/ value 1`] = ` - "import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setAttr(n0, "value", _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .camel modifier 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id)) - _setInheritAttrs(["fooBar"]) + let _id + _renderEffect(() => _id !== _ctx.id && (_id = _setDynamicProp(n0, "fooBar", _id, _ctx.id))) return n0 }" `; exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, camelize as _camelize, template as _template } from 'vue'; -"import { camelize as _camelize } from 'vue'; -import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { camelize as _camelize, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true)) - _setInheritAttrs(true) + let _foo, _id, _foo_id + _renderEffect(() => (_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize(_ctx.foo)]: _ctx.id }], true))) return n0 }" `; exports[`compiler v-bind > .camel modifier w/ no expression 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar)) - _setInheritAttrs(["fooBar"]) + let _fooBar + _renderEffect(() => _fooBar !== _ctx.fooBar && (_fooBar = _setDynamicProp(n0, "fooBar", _fooBar, _ctx.fooBar))) return n0 }" `; exports[`compiler v-bind > .prop modifier (shorthand) 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id)) - _setInheritAttrs(["fooBar"]) + let _id + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))) return n0 }" `; exports[`compiler v-bind > .prop modifier (shorthand) w/ innerHTML 1`] = ` - "import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setHtml(n0, _ctx.foo)) - _setInheritAttrs(["innerHTML"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .prop modifier (shorthand) w/ no expression 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar)) - _setInheritAttrs(["fooBar"]) + let _fooBar + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) return n0 }" `; exports[`compiler v-bind > .prop modifier (shorthand) w/ progress value 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "value", _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .prop modifier (shorthand) w/ textContent 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setText(n0, _ctx.foo)) - _setInheritAttrs(["textContent"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .prop modifier (shorthand) w/ value 1`] = ` - "import { renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setValue(n0, _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .prop modifier 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id)) - _setInheritAttrs(["fooBar"]) + let _id + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))) return n0 }" `; exports[`compiler v-bind > .prop modifier w/ dynamic arg 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true)) - _setInheritAttrs(true) + let _fooBar, _id, _fooBar_id + _renderEffect(() => (_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + _ctx.fooBar]: _ctx.id }], true))) return n0 }" `; exports[`compiler v-bind > .prop modifier w/ innerHTML 1`] = ` - "import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setHtml(n0, _ctx.foo)) - _setInheritAttrs(["innerHTML"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .prop modifier w/ no expression 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar)) - _setInheritAttrs(["fooBar"]) + let _fooBar + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) return n0 }" `; exports[`compiler v-bind > .prop modifier w/ progress value 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "value", _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .prop modifier w/ textContent 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setText(n0, _ctx.foo)) - _setInheritAttrs(["textContent"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > .prop modifier w/ value 1`] = ` - "import { renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setValue(n0, _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > :innerHTML 1`] = ` - "import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setHtml(n0, _ctx.foo)) - _setInheritAttrs(["innerHTML"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > :textContext 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setText(n0, _ctx.foo)) - _setInheritAttrs(["textContent"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > :value 1`] = ` - "import { renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setValue(n0, _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" `; exports[`compiler v-bind > :value w/ progress 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProp(n0, "value", _ctx.foo)) - _setInheritAttrs(["value"]) + let _foo + _renderEffect(() => _foo !== _ctx.foo && (_foo = _setDynamicProp(n0, "value", _foo, _ctx.foo))) return n0 }" `; exports[`compiler v-bind > HTML global attributes should set as dom prop 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) - _renderEffect(() => _setDOMProp(n0, "title", _ctx.title)) - _renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang)) - _renderEffect(() => _setDOMProp(n0, "dir", _ctx.dir)) - _renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex)) - _setInheritAttrs(["id", "title", "lang", "dir", "tabindex"]) + let _id, _title, _lang, _dir, _tabindex + _renderEffect(() => { + _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id)) + _title !== _ctx.title && _setDOMProp(n0, "title", (_title = _ctx.title)) + _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang)) + _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir)) + _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex)) + }) return n0 }" `; exports[`compiler v-bind > MathML global attributes should set as dom prop 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "autofucus", _ctx.autofucus)) - _renderEffect(() => _setDOMProp(n0, "dir", _ctx.dir)) - _renderEffect(() => _setDOMProp(n0, "displaystyle", _ctx.displaystyle)) - _renderEffect(() => _setDOMProp(n0, "mathcolor", _ctx.mathcolor)) - _renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex)) - _setInheritAttrs(["autofucus", "dir", "displaystyle", "mathcolor", "tabindex"]) + let _autofucus, _dir, _displaystyle, _mathcolor, _tabindex + _renderEffect(() => { + _autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus)) + _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir)) + _displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle)) + _mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor)) + _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex)) + }) return n0 }" `; exports[`compiler v-bind > SVG global attributes should set as dom prop 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) - _renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang)) - _renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex)) - _setInheritAttrs(["id", "lang", "tabindex"]) + let _id, _lang, _tabindex + _renderEffect(() => { + _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id)) + _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang)) + _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex)) + }) return n0 }" `; exports[`compiler v-bind > attributes must be set as attribute 1`] = ` - "import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue'; -"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") const t1 = _template("") const t2 = _template("") @@@ -370,56 -440,78 +410,73 @@@ export function render(_ctx) `; exports[`compiler v-bind > basic 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) - _setInheritAttrs(["id"]) + let _id + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) return n0 }" `; + exports[`compiler v-bind > bind member expression 1`] = ` -"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; + const t0 = _template("
") + + export function render(_ctx) { + const n0 = t0() + let _obj + _renderEffect(() => _obj !== _ctx.obj.count.bar && _setDOMProp(n0, "id", (_obj = _ctx.obj.count.bar))) + return [n0, n1] + }" + `; + exports[`compiler v-bind > dynamic arg 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true)) - _setInheritAttrs(true) + let _id, _title, _id_title + _renderEffect(() => (_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true))) return n0 }" `; exports[`compiler v-bind > dynamic arg w/ static attribute 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true)) - _setInheritAttrs(true) + let _id + _renderEffect(() => _id !== _ctx.id && (_id = _setDynamicProps(n0, _id, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true))) return n0 }" `; exports[`compiler v-bind > no expression (shorthand) 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase)) - _setInheritAttrs(["camel-case"]) + let _camelCase + _renderEffect(() => _camelCase !== _ctx.camelCase && (_camelCase = _setDynamicProp(n0, "camel-case", _camelCase, _ctx.camelCase))) return n0 }" `; exports[`compiler v-bind > no expression 1`] = ` - "import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) - _setInheritAttrs(["id"]) + let _id + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) return n0 }" `; diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap index 0ef33b31fe,580b41046a..22da321e46 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: v-for > array de-structured value 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -15,7 -15,7 +15,7 @@@ `; exports[`compiler: v-for > basic v-for 1`] = ` - "import { delegate as _delegate, renderEffect as _renderEffect, setText as _setText, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue'; -"import { delegate as _delegate, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; ++"import { delegate as _delegate, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue'; const t0 = _template("
") _delegateEvents("click") @@@ -31,7 -31,7 +31,7 @@@ export function render(_ctx) `; exports[`compiler: v-for > function params w/ prefixIdentifiers: false 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, createFor as _createFor, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -45,14 -45,17 +45,16 @@@ `; exports[`compiler: v-for > multi effect 1`] = ` - "import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, createFor as _createFor, template as _template } from 'vue'; -"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue/vapor'; ++"import { setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { const n0 = _createFor(() => (_ctx.items), (_ctx0) => { const n2 = t0() - _renderEffect(() => _setDynamicProp(n2, "item", _ctx0[0].value)) - _renderEffect(() => _setDynamicProp(n2, "index", _ctx0[1].value)) - _setInheritAttrs(["item", "index"]) + _renderEffect(() => { + _setDynamicProp(n2, "item", _ctx0[0].value) + _setDynamicProp(n2, "index", _ctx0[1].value) + }) return n2 }) return n0 @@@ -60,7 -63,7 +62,7 @@@ `; exports[`compiler: v-for > nested v-for 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, createFor as _createFor, insert as _insert, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, insert as _insert, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, insert as _insert, template as _template } from 'vue'; const t0 = _template("") const t1 = _template("
") @@@ -80,7 -83,7 +82,7 @@@ export function render(_ctx) `; exports[`compiler: v-for > object de-structured value 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -94,7 -97,7 +96,7 @@@ `; exports[`compiler: v-for > v-for aliases w/ complex expressions 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap index 110fea9161,34b621bc61..72e0319185 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`v-html > should convert v-html to innerHTML 1`] = ` - "import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue'; -"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { @@@ -12,7 -13,7 +13,7 @@@ `; exports[`v-html > should raise error and ignore children when v-html is present 1`] = ` - "import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue'; -"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index 6638062fc8,42cb0a4d26..a0ffcdf392 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: v-if > basic v-if 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, createIf as _createIf, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -15,7 -16,7 +16,7 @@@ `; exports[`compiler: v-if > comment between branches 1`] = ` - "import { createIf as _createIf, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { createIf as _createIf, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { createIf as _createIf, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") const t1 = _template("") const t2 = _template("

") @@@ -60,7 -62,7 +62,7 @@@ export function render(_ctx) `; exports[`compiler: v-if > template v-if 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, createIf as _createIf, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue'; const t0 = _template("
") const t1 = _template("hello") const t2 = _template("

") diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap index 8a6b1cabc3,0b38516621..1d73b32cb6 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap @@@ -235,14 -246,16 +235,15 @@@ export function render(_ctx) `; exports[`compiler: vModel transform > should support w/ dynamic v-bind 1`] = ` - "import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue'; -"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("") export function render(_ctx) { const n0 = t0() _withDirectives(n0, [[_vModelDynamic, () => _ctx.model]]) _delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event)) - _renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true)) - _setInheritAttrs(true) + let _obj + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj], true))) return n0 }" `; diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap index bca6a53ad0,8657e0611f..43510808bc --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap @@@ -13,7 -13,7 +13,7 @@@ export function render(_ctx) `; exports[`v-on > dynamic arg 1`] = ` - "import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue'; -"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -28,7 -29,7 +29,7 @@@ `; exports[`v-on > dynamic arg with complex exp prefixing 1`] = ` - "import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue'; -"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -43,7 -45,7 +45,7 @@@ `; exports[`v-on > dynamic arg with prefixing 1`] = ` - "import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue'; -"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -372,7 -375,7 +375,7 @@@ export function render(_ctx) `; exports[`v-on > should transform click.middle 2`] = ` - "import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue'; -"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -402,7 -406,7 +406,7 @@@ export function render(_ctx) `; exports[`v-on > should transform click.right 2`] = ` - "import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue'; -"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@@ -431,7 -436,7 +436,7 @@@ export function render(_ctx) `; exports[`v-on > should wrap both for dynamic key event w/ left/right modifiers 1`] = ` - "import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue'; -"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { diff --cc packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap index 506913184a,1b98a024ce..93acfaab78 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap @@@ -1,7 -1,7 +1,7 @@@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`v-text > should convert v-text to textContent 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { @@@ -12,7 -13,7 +13,7 @@@ `; exports[`v-text > should raise error and ignore children when v-text is present 1`] = ` - "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue'; -"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; ++"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { diff --cc packages/compiler-vapor/src/generate.ts index a134882351,14bc78fd02..bbcff0728c --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@@ -2,7 -2,7 +2,13 @@@ import type CodegenOptions as BaseCodegenOptions, BaseCodegenResult, } from '@vue/compiler-dom' - import type { BlockIRNode, CoreHelper, RootIRNode, VaporHelper } from './ir' -import type { BlockIRNode, IREffect, RootIRNode, VaporHelper } from './ir' ++import type { ++ BlockIRNode, ++ CoreHelper, ++ IREffect, ++ RootIRNode, ++ VaporHelper, ++} from './ir' import { extend, remove } from '@vue/shared' import { genBlockContent } from './generators/block' import { genTemplates } from './generators/template' diff --cc packages/compiler-vapor/src/generators/html.ts index 269ef1d6ad,9175ae3729..4eea9faa0b --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@@ -7,13 -8,11 +8,11 @@@ export function genSetHtml oper: SetHtmlIRNode, context: CodegenContext, ): CodeFragment[] { - const { helper } = context - return [ - NEWLINE, - ...genCall( - helper('setHtml'), - `n${oper.element}`, - genExpression(oper.value, context), - ), - ] - const { vaporHelper, shouldCacheRenderEffectDeps } = context ++ const { helper, shouldCacheRenderEffectDeps } = context + const { value, element } = oper + let html = genExpression(value, context) + if (shouldCacheRenderEffectDeps()) { + processValues(context, [html]) + } - return [NEWLINE, ...genCall(vaporHelper('setHtml'), `n${element}`, html)] ++ return [NEWLINE, ...genCall(helper('setHtml'), `n${element}`, html)] } diff --cc packages/compiler-vapor/src/generators/operation.ts index 0a830e4bf2,8dc196e59c..6554b5e777 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@@ -76,9 -78,33 +76,33 @@@ export function genEffects effects: IREffect[], context: CodegenContext, ): CodeFragment[] { - const [frag, push] = buildCodeFragment() - for (const effect of effects) { - push(...genEffect(effect, context)) - const { vaporHelper } = context ++ const { helper } = context + const [frag, push, unshift] = buildCodeFragment() + const declareNames = new Set() + let operationsCount = 0 + for (let i = 0; i < effects.length; i++) { + const effect = (context.processingRenderEffect = effects[i]) + operationsCount += effect.operations.length + const frags = genEffect(effect, context, declareNames) + const needSemi = frag[frag.length - 1] === ')' && frags[0] === '(' + i > 0 && push(NEWLINE) + push(needSemi ? ';' : undefined, ...frags) + } + + const newLineCount = frag.filter(frag => frag === NEWLINE).length + if (newLineCount > 1 || operationsCount > 1) { + unshift(`{`, INDENT_START, NEWLINE) + push(INDENT_END, NEWLINE, '}') + } + + if (effects.length) { - unshift(NEWLINE, `${vaporHelper('renderEffect')}(() => `) ++ unshift(NEWLINE, `${helper('renderEffect')}(() => `) + push(`)`) + } + + // declare variables: let _foo, _bar + if (declareNames.size) { + frag.splice(1, 0, `let ${[...declareNames].join(', ')}`, NEWLINE) } return frag } diff --cc packages/compiler-vapor/src/generators/prop.ts index a9597f0cac,3a0964dd16..fef5e09875 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@@ -43,15 -45,24 +44,24 @@@ export function genSetProp prop: { key, values, modifier }, tag, } = oper - const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) + const propValue = genPropValue(values, context) + const { prevValueName, shouldWrapInParentheses } = processPropValues( + context, + helperName, + [propValue], + ) return [ NEWLINE, + ...(prevValueName + ? [shouldWrapInParentheses ? `(` : undefined, `${prevValueName} = `] + : []), ...genCall( - [vaporHelper(helperName), null], + [helper(helperName), null], `n${oper.element}`, omitKey ? false : genExpression(key, context), - genPropValue(values, context), + ...(prevValueName ? [`${prevValueName}`] : []), + propValue, // only `setClass` and `setStyle` need merge inherit attr oper.root && (helperName === 'setClass' || helperName === 'setStyle') ? 'true' @@@ -65,25 -77,32 +76,32 @@@ export function genDynamicProps oper: SetDynamicPropsIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + const { helper } = context + const values = oper.props.map(props => + Array.isArray(props) + ? genLiteralObjectProps(props, context) // static and dynamic arg props + : props.kind === IRDynamicPropsKind.ATTRIBUTE + ? genLiteralObjectProps([props], context) // dynamic arg props + : genExpression(props.value, context), + ) // v-bind="" + const { prevValueName, shouldWrapInParentheses } = processPropValues( + context, + 'setDynamicProps', + values, + ) return [ NEWLINE, + ...(prevValueName + ? [shouldWrapInParentheses ? `(` : undefined, `${prevValueName} = `] + : []), ...genCall( - vaporHelper('setDynamicProps'), + helper('setDynamicProps'), `n${oper.element}`, - genMulti( - DELIMITERS_ARRAY, - ...oper.props.map( - props => - Array.isArray(props) - ? genLiteralObjectProps(props, context) // static and dynamic arg props - : props.kind === IRDynamicPropsKind.ATTRIBUTE - ? genLiteralObjectProps([props], context) // dynamic arg props - : genExpression(props.value, context), // v-bind="" - ), - ), + ...(prevValueName ? [`${prevValueName}`] : []), + genMulti(DELIMITERS_ARRAY, ...values), oper.root && 'true', ), + ...(prevValueName && shouldWrapInParentheses ? [`)`] : []), ] } diff --cc packages/compiler-vapor/src/generators/text.ts index 86437bc91c,7eaaaa7fce..30ace31a7b --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@@ -13,16 -14,13 +14,13 @@@ export function genSetText oper: SetTextIRNode, context: CodegenContext, ): CodeFragment[] { - const { helper } = context - const { vaporHelper, shouldCacheRenderEffectDeps } = context ++ const { helper, shouldCacheRenderEffectDeps } = context const { element, values } = oper - return [ - NEWLINE, - ...genCall( - helper('setText'), - `n${element}`, - ...values.map(value => genExpression(value, context)), - ), - ] + const texts = values.map(value => genExpression(value, context)) + if (shouldCacheRenderEffectDeps()) { + processValues(context, texts) + } - return [NEWLINE, ...genCall(vaporHelper('setText'), `n${element}`, ...texts)] ++ return [NEWLINE, ...genCall(helper('setText'), `n${element}`, ...texts)] } export function genCreateTextNode( diff --cc packages/runtime-vapor/__tests__/dom/prop.spec.ts index 513abe525e,6f6666e4c4..d0fa57c4ea --- a/packages/runtime-vapor/__tests__/dom/prop.spec.ts +++ b/packages/runtime-vapor/__tests__/dom/prop.spec.ts @@@ -10,9 -10,11 +10,8 @@@ import setValue, } from '../../src/dom/prop' import { setStyle } from '../../src/dom/style' -import { - ComponentInternalInstance, - setCurrentInstance, -} from '../../src/component' -import { getCurrentScope } from '@vue/reactivity' +import { VaporComponentInstance } from '../../src/component' +import { currentInstance, simpleSetCurrentInstance } from '@vue/runtime-dom' - import { getMetadata, recordPropMetadata } from '../../src/componentMetadata' let removeComponentInstance = NOOP beforeEach(() => { diff --cc packages/runtime-vapor/src/component.ts index 7c99de6994,89f8ccc881..06c7444145 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@@ -1,79 -1,100 +1,85 @@@ -import { EffectScope, isRef } from '@vue/reactivity' -import { EMPTY_OBJ, isArray, isBuiltInTag, isFunction } from '@vue/shared' -import type { Block } from './block' import { + type ComponentInternalOptions, type ComponentPropsOptions, + EffectScope, + type EmitFn, + type EmitsOptions, + ErrorCodes, + type GenericAppContext, + type GenericComponentInstance, + type LifecycleHook, type NormalizedPropsOptions, - type NormalizedRawProps, + type ObjectEmitsOptions, + type SuspenseBoundary, + callWithErrorHandling, + currentInstance, + endMeasure, + expose, + nextUid, + popWarningContext, + pushWarningContext, + queuePostFlushCb, + registerHMR, + simpleSetCurrentInstance, + startMeasure, + unregisterHMR, + warn, +} from '@vue/runtime-dom' +import { type Block, insert, isBlock, remove } from './block' +import { + markRaw, + pauseTracking, + proxyRefs, + resetTracking, +} from '@vue/reactivity' - import { EMPTY_OBJ, invokeArrayFns, isFunction, isString } from '@vue/shared' ++import { ++ EMPTY_OBJ, ++ extend, ++ invokeArrayFns, ++ isFunction, ++ isString, ++} from '@vue/shared' +import { + type DynamicPropsSource, type RawProps, - initProps, + getPropsProxyHandlers, + hasFallthroughAttrs, normalizePropsOptions, + resolveDynamicProps, + setupPropsValidation, } from './componentProps' +import { renderEffect } from './renderEffect' +import { emit, normalizeEmitsOptions } from './componentEmits' +import { setStyle } from './dom/style' - import { setClass, setDynamicProp } from './dom/prop' ++import { setClass, setDynamicProp, setDynamicProps } from './dom/prop' import { - type EmitFn, - type EmitsOptions, - type ObjectEmitsOptions, - emit, - normalizeEmitsOptions, -} from './componentEmits' -import { type RawSlots, type StaticSlots, initSlots } from './componentSlots' -import { VaporLifecycleHooks } from './enums' -import { warn } from './warning' -import { - type AppConfig, - type AppContext, - createAppContext, -} from './apiCreateVaporApp' -import type { Data } from '@vue/runtime-shared' - -export type Component = FunctionalComponent | ObjectComponent - -export type SetupFn = (props: any, ctx: SetupContext) => Block | Data | void -export type FunctionalComponent = SetupFn & - Omit & { + type DynamicSlotSource, + type RawSlots, + type Slot, + type StaticSlots, + dynamicSlotsProxyHandlers, + getSlot, +} from './componentSlots' +import { hmrReload, hmrRerender } from './hmr' + +export { currentInstance } from '@vue/runtime-dom' + +export type VaporComponent = FunctionalVaporComponent | ObjectVaporComponent + +export type VaporSetupFn = ( + props: any, + ctx: Pick, +) => Block | Record | undefined + +export type FunctionalVaporComponent = VaporSetupFn & + Omit & { displayName?: string - } - -export class SetupContext { - attrs: Data - emit: EmitFn - slots: Readonly - expose: (exposed?: Record) => void - - constructor(instance: ComponentInternalInstance) { - this.attrs = instance.attrs - this.emit = instance.emit as EmitFn - this.slots = instance.slots - this.expose = (exposed = {}) => { - instance.exposed = exposed - } - } -} - -export function createSetupContext( - instance: ComponentInternalInstance, -): SetupContext { - if (__DEV__) { - // We use getters in dev in case libs like test-utils overwrite instance - // properties (overwrites should not be done in prod) - return Object.freeze({ - get attrs() { - return getAttrsProxy(instance) - }, - get slots() { - return getSlotsProxy(instance) - }, - get emit() { - return (event: string, ...args: any[]) => instance.emit(event, ...args) - }, - expose: (exposed?: Record) => { - if (instance.exposed) { - warn(`expose() should be called only once per setup().`) - } - if (exposed != null) { - let exposedType: string = typeof exposed - if (exposedType === 'object') { - if (isArray(exposed)) { - exposedType = 'array' - } else if (isRef(exposed)) { - exposedType = 'ref' - } - } - if (exposedType !== 'object') { - warn( - `expose() should be passed a plain object, received ${exposedType}.`, - ) - } - } - instance.exposed = exposed || {} - }, - }) as SetupContext - } else { - return new SetupContext(instance) - } -} + } & SharedInternalOptions -export interface ObjectComponent extends ComponentInternalOptions { - setup?: SetupFn +export interface ObjectVaporComponent + extends ComponentInternalOptions, + SharedInternalOptions { + setup?: VaporSetupFn inheritAttrs?: boolean props?: ComponentPropsOptions emits?: EmitsOptions @@@ -89,309 -104,217 +95,310 @@@ vapor?: boolean } -// Note: can't mark this whole interface internal because some public interfaces -// extend it. -export interface ComponentInternalOptions { +interface SharedInternalOptions { /** - * @internal + * Cached normalized props options. + * In vapor mode there are no mixins so normalized options can be cached + * directly on the component */ - __scopeId?: string + __propsOptions?: NormalizedPropsOptions /** - * @internal + * Cached normalized props proxy handlers. */ - __cssModules?: Data + __propsHandlers?: [ProxyHandler | null, ProxyHandler] /** - * @internal + * Cached normalized emits options. */ - __hmrId?: string - /** - * Compat build only, for bailing out of certain compatibility behavior - */ - __isBuiltIn?: boolean - /** - * This one should be exposed so that devtools can make use of it - */ - __file?: string - /** - * name inferred from filename - */ - __name?: string + __emitsOptions?: ObjectEmitsOptions +} + +// In TypeScript, it is actually impossible to have a record type with only +// specific properties that have a different type from the indexed type. +// This makes our rawProps / rawSlots shape difficult to satisfy when calling +// `createComponent` - luckily this is not user-facing, so we don't need to be +// 100% strict. Here we use intentionally wider types to make `createComponent` +// more ergonomic in tests and internal call sites, where we immediately cast +// them into the stricter types. +export type LooseRawProps = Record< + string, + (() => unknown) | DynamicPropsSource[] +> & { + $?: DynamicPropsSource[] } -type LifecycleHook = TFn[] | null +type LooseRawSlots = Record & { + $?: DynamicSlotSource[] +} + +export function createComponent( + component: VaporComponent, + rawProps?: LooseRawProps | null, + rawSlots?: LooseRawSlots | null, + isSingleRoot?: boolean, + appContext?: GenericAppContext, +): VaporComponentInstance { + // check if we are the single root of the parent + // if yes, inject parent attrs as dynamic props source + if ( + isSingleRoot && + component.inheritAttrs !== false && + isVaporComponent(currentInstance) && + currentInstance.hasFallthrough + ) { + const attrs = currentInstance.attrs + if (rawProps) { + ;((rawProps as RawProps).$ || ((rawProps as RawProps).$ = [])).push( + () => attrs, + ) + } else { + rawProps = { $: [() => attrs] } as RawProps + } + } -export let currentInstance: ComponentInternalInstance | null = null + const instance = new VaporComponentInstance( + component, + rawProps as RawProps, + rawSlots as RawSlots, + appContext, + ) -export const getCurrentInstance: () => ComponentInternalInstance | null = () => - currentInstance + if (__DEV__) { + pushWarningContext(instance) + startMeasure(instance, `init`) + } -export const setCurrentInstance = (instance: ComponentInternalInstance) => { const prev = currentInstance - currentInstance = instance - return (): void => { - currentInstance = prev + simpleSetCurrentInstance(instance) + pauseTracking() + + const setupFn = isFunction(component) ? component : component.setup + const setupResult = setupFn + ? callWithErrorHandling(setupFn, instance, ErrorCodes.SETUP_FUNCTION, [ + instance.props, + instance, + ]) || EMPTY_OBJ + : EMPTY_OBJ + + if (__DEV__ && !isBlock(setupResult)) { + if (isFunction(component)) { + warn(`Functional vapor component must return a block directly.`) + instance.block = [] + } else if (!component.render) { + warn( + `Vapor component setup() returned non-block value, and has no render function.`, + ) + instance.block = [] + } else { + instance.devtoolsRawSetupState = setupResult + instance.setupState = proxyRefs(setupResult) + devRender(instance) + + // HMR + if (component.__hmrId) { + registerHMR(instance) + instance.isSingleRoot = isSingleRoot + instance.hmrRerender = hmrRerender.bind(null, instance) + instance.hmrReload = hmrReload.bind(null, instance) + } + } + } else { + // in prod result can only be block + instance.block = setupResult as Block } -} -export const unsetCurrentInstance = (): void => { - currentInstance && currentInstance.scope.off() - currentInstance = null + // single root, inherit attrs + if ( + instance.hasFallthrough && + component.inheritAttrs !== false && + instance.block instanceof Element && + Object.keys(instance.attrs).length + ) { ++ let prevProps: any + renderEffect(() => { - for (const key in instance.attrs) { - setDynamicProp(instance.block as Element, key, instance.attrs[key]) - } ++ setDynamicProps(instance.block as Element, prevProps, [ ++ (prevProps = extend({}, instance.attrs)), ++ ]) + }) + } + + resetTracking() + simpleSetCurrentInstance(prev, instance) + + if (__DEV__) { + popWarningContext() + endMeasure(instance, 'init') + } + + return instance } -const emptyAppContext = createAppContext() +/** + * dev only + */ +export function devRender(instance: VaporComponentInstance): void { + instance.block = + callWithErrorHandling( + instance.type.render!, + instance, + ErrorCodes.RENDER_FUNCTION, + [ + instance.setupState, + instance.props, + instance.emit, + instance.attrs, + instance.slots, + ], + ) || [] +} -let uid = 0 -export class ComponentInternalInstance { - vapor = true +const emptyContext: GenericAppContext = { + app: null as any, + config: {}, + provides: /*@__PURE__*/ Object.create(null), +} +export class VaporComponentInstance implements GenericComponentInstance { + vapor: true uid: number - appContext: AppContext - - type: Component - block: Block | null - container: ParentNode - parent: ComponentInternalInstance | null - root: ComponentInternalInstance + type: VaporComponent + parent: GenericComponentInstance | null + children: VaporComponentInstance[] // TODO handle vdom children + appContext: GenericAppContext - provides: Data + block: Block scope: EffectScope - comps: Set - scopeIds: string[] - rawProps: NormalizedRawProps - propsOptions: NormalizedPropsOptions - emitsOptions: ObjectEmitsOptions | null + rawProps: RawProps + rawSlots: RawSlots + + props: Record + attrs: Record + propsDefaults: Record | null + + slots: StaticSlots - // state - setupState: Data - setupContext: SetupContext | null - props: Data emit: EmitFn emitted: Record | null - attrs: Data - /** - * - `undefined` : no props - * - `false` : all props are static - * - `string[]` : list of props are dynamic - * - `true` : all props as dynamic - */ - dynamicAttrs?: string[] | boolean - slots: StaticSlots - refs: Data - // exposed properties via expose() - exposed?: Record - attrsProxy?: Data - slotsProxy?: StaticSlots + expose: (exposed: Record) => void + exposed: Record | null + exposeProxy: Record | null + + // for useTemplateRef() + refs: Record + // for provide / inject + provides: Record + // for useId + ids: [string, number, number] + // for suspense + suspense: SuspenseBoundary | null + + hasFallthrough: boolean - // lifecycle + // lifecycle hooks isMounted: boolean isUnmounted: boolean + isDeactivated: boolean isUpdating: boolean - // TODO: registory of provides, lifecycles, ... - /** - * @internal - */ - // [VaporLifecycleHooks.BEFORE_MOUNT]: LifecycleHook; - bm: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.MOUNTED]: LifecycleHook; - m: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.BEFORE_UPDATE]: LifecycleHook; - bu: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.UPDATED]: LifecycleHook; - u: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.BEFORE_UNMOUNT]: LifecycleHook; - bum: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.UNMOUNTED]: LifecycleHook; - um: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.RENDER_TRACKED]: LifecycleHook; - rtc: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.RENDER_TRIGGERED]: LifecycleHook; - rtg: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.ACTIVATED]: LifecycleHook; - a: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.DEACTIVATED]: LifecycleHook; - da: LifecycleHook - /** - * @internal - */ - // [VaporLifecycleHooks.ERROR_CAPTURED]: LifecycleHook - ec: LifecycleHook + + bc?: LifecycleHook // LifecycleHooks.BEFORE_CREATE + c?: LifecycleHook // LifecycleHooks.CREATED + bm?: LifecycleHook // LifecycleHooks.BEFORE_MOUNT + m?: LifecycleHook // LifecycleHooks.MOUNTED + bu?: LifecycleHook // LifecycleHooks.BEFORE_UPDATE + u?: LifecycleHook // LifecycleHooks.UPDATED + um?: LifecycleHook // LifecycleHooks.BEFORE_UNMOUNT + bum?: LifecycleHook // LifecycleHooks.UNMOUNTED + da?: LifecycleHook // LifecycleHooks.DEACTIVATED + a?: LifecycleHook // LifecycleHooks.ACTIVATED + rtg?: LifecycleHook // LifecycleHooks.RENDER_TRACKED + rtc?: LifecycleHook // LifecycleHooks.RENDER_TRIGGERED + ec?: LifecycleHook // LifecycleHooks.ERROR_CAPTURED + sp?: LifecycleHook<() => Promise> // LifecycleHooks.SERVER_PREFETCH + + // dev only + setupState?: Record + devtoolsRawSetupState?: any + hmrRerender?: () => void + hmrReload?: (newComp: VaporComponent) => void + propsOptions?: NormalizedPropsOptions + emitsOptions?: ObjectEmitsOptions | null + isSingleRoot?: boolean constructor( - component: Component, - rawProps: RawProps | null, - slots: RawSlots | null, - once: boolean = false, - // application root node only - appContext?: AppContext, + comp: VaporComponent, + rawProps?: RawProps | null, + rawSlots?: RawSlots | null, + appContext?: GenericAppContext, ) { - this.uid = uid++ - const parent = (this.parent = currentInstance) - this.root = parent ? parent.root : this - const _appContext = (this.appContext = - (parent ? parent.appContext : appContext) || emptyAppContext) - this.block = null - this.container = null! - this.root = null! + this.vapor = true + this.uid = nextUid() + this.type = comp + this.parent = currentInstance // TODO proper parent source when inside vdom instance + this.children = [] + + if (currentInstance) { + if (isVaporComponent(currentInstance)) { + currentInstance.children.push(this) + } + this.appContext = currentInstance.appContext + this.provides = currentInstance.provides + this.ids = currentInstance.ids + } else { + this.appContext = appContext || emptyContext + this.provides = Object.create(this.appContext.provides) + this.ids = ['', 0, 0] + } + + this.block = null! // to be set this.scope = new EffectScope(true) - this.provides = parent - ? parent.provides - : Object.create(_appContext.provides) - this.type = component - this.comps = new Set() - this.scopeIds = [] - this.rawProps = null! - this.propsOptions = normalizePropsOptions(component) - this.emitsOptions = normalizeEmitsOptions(component) - - // state - this.setupState = EMPTY_OBJ - this.setupContext = null - this.props = EMPTY_OBJ + this.emit = emit.bind(null, this) - this.emitted = null - this.attrs = EMPTY_OBJ - this.slots = EMPTY_OBJ + this.expose = expose.bind(null, this) this.refs = EMPTY_OBJ + this.emitted = + this.exposed = + this.exposeProxy = + this.propsDefaults = + this.suspense = + null + + this.isMounted = + this.isUnmounted = + this.isUpdating = + this.isDeactivated = + false + + // init props + this.rawProps = rawProps || EMPTY_OBJ + this.hasFallthrough = hasFallthroughAttrs(comp, rawProps) + if (rawProps || comp.props) { + const [propsHandlers, attrsHandlers] = getPropsProxyHandlers(comp) + this.attrs = new Proxy(this, attrsHandlers) + this.props = comp.props + ? new Proxy(this, propsHandlers!) + : isFunction(comp) + ? this.attrs + : EMPTY_OBJ + } else { + this.props = this.attrs = EMPTY_OBJ + } - // lifecycle - this.isMounted = false - this.isUnmounted = false - this.isUpdating = false - this[VaporLifecycleHooks.BEFORE_MOUNT] = null - this[VaporLifecycleHooks.MOUNTED] = null - this[VaporLifecycleHooks.BEFORE_UPDATE] = null - this[VaporLifecycleHooks.UPDATED] = null - this[VaporLifecycleHooks.BEFORE_UNMOUNT] = null - this[VaporLifecycleHooks.UNMOUNTED] = null - this[VaporLifecycleHooks.RENDER_TRACKED] = null - this[VaporLifecycleHooks.RENDER_TRIGGERED] = null - this[VaporLifecycleHooks.ACTIVATED] = null - this[VaporLifecycleHooks.DEACTIVATED] = null - this[VaporLifecycleHooks.ERROR_CAPTURED] = null - - initProps(this, rawProps, !isFunction(component), once) - initSlots(this, slots) + // init slots + this.rawSlots = rawSlots || EMPTY_OBJ + this.slots = rawSlots + ? rawSlots.$ + ? new Proxy(rawSlots, dynamicSlotsProxyHandlers) + : rawSlots + : EMPTY_OBJ + + if (__DEV__) { + // validate props + if (rawProps) setupPropsValidation(this) + // cache normalized options for dev only emit check + this.propsOptions = normalizePropsOptions(comp) + this.emitsOptions = normalizeEmitsOptions(comp) + } } } @@@ -402,101 -336,79 +409,106 @@@ export function isVaporComponent } /** - * Dev-only + * Used when a component cannot be resolved at compile time + * and needs rely on runtime resolution - where it might fallback to a plain + * element if the resolution fails. */ -export function getAttrsProxy(instance: ComponentInternalInstance): Data { - return ( - instance.attrsProxy || - (instance.attrsProxy = new Proxy(instance.attrs, { - get(target, key: string) { - return target[key] - }, - set() { - warn(`setupContext.attrs is readonly.`) - return false - }, - deleteProperty() { - warn(`setupContext.attrs is readonly.`) - return false - }, - })) - ) -} +export function createComponentWithFallback( + comp: VaporComponent | string, + rawProps: RawProps | null | undefined, + rawSlots: RawSlots | null | undefined, + isSingleRoot?: boolean, +): HTMLElement | VaporComponentInstance { + if (!isString(comp)) { + return createComponent(comp, rawProps, rawSlots, isSingleRoot) + } -/** - * Dev-only - */ -export function getSlotsProxy( - instance: ComponentInternalInstance, -): StaticSlots { - return ( - instance.slotsProxy || - (instance.slotsProxy = new Proxy(instance.slots, { - get(target, key: string) { - return target[key] - }, - })) - ) -} + // eslint-disable-next-line no-restricted-globals + const el = document.createElement(comp) + + if (rawProps) { ++ let prevProps: any, prevStyle: any + renderEffect(() => { + let classes: unknown[] | undefined + let styles: unknown[] | undefined + const resolved = resolveDynamicProps(rawProps) + for (const key in resolved) { + const value = resolved[key] - if (key === 'class') (classes ||= []).push(value) - else if (key === 'style') (styles ||= []).push(value) - else setDynamicProp(el, key, value) ++ if (key === 'class') { ++ ;(classes ||= []).push(value) ++ } else if (key === 'style') { ++ ;(styles ||= []).push(value) ++ } else if (value !== prevProps) { ++ setDynamicProp(el, key, prevProps, (prevProps = value)) ++ } + } - if (classes) setClass(el, classes) - if (styles) setStyle(el, styles) ++ if (classes) setClass(el, classes, isSingleRoot) ++ if (styles) setStyle(el, prevStyle, (prevStyle = styles), isSingleRoot) + }) + } -export function getComponentName( - Component: Component, -): string | false | undefined { - return isFunction(Component) - ? Component.displayName || Component.name - : Component.name || Component.__name + if (rawSlots) { + if (rawSlots.$) { + // TODO dynamic slot fragment + } else { + insert(getSlot(rawSlots, 'default')!(), el) + } + } + + return el } -export function formatComponentName( - instance: ComponentInternalInstance | null, - Component: Component, - isRoot = false, -): string { - let name = getComponentName(Component) - if (!name && Component.__file) { - const match = Component.__file.match(/([^/\\]+)\.\w+$/) - if (match) { - name = match[1] - } +export function mountComponent( + instance: VaporComponentInstance, + parent: ParentNode, + anchor?: Node | null | 0, +): void { + if (__DEV__) { + startMeasure(instance, `mount`) + } + if (!instance.isMounted) { + if (instance.bm) invokeArrayFns(instance.bm) + insert(instance.block, parent, anchor) + if (instance.m) queuePostFlushCb(() => invokeArrayFns(instance.m!)) + instance.isMounted = true + } else { + insert(instance.block, parent, anchor) } + if (__DEV__) { + endMeasure(instance, `mount`) + } +} - if (!name && instance && instance.parent) { - // try to infer the name based on reverse resolution - const inferFromRegistry = (registry: Record | undefined) => { - for (const key in registry) { - if (registry[key] === Component) { - return key - } - } +export function unmountComponent( + instance: VaporComponentInstance, + parent?: ParentNode, +): void { + if (instance.isMounted && !instance.isUnmounted) { + if (__DEV__ && instance.type.__hmrId) { + unregisterHMR(instance) + } + if (instance.bum) invokeArrayFns(instance.bum) + instance.scope.stop() + for (const c of instance.children) { + unmountComponent(c) + } + if (parent) remove(instance.block, parent) + if (instance.um) { + queuePostFlushCb(() => invokeArrayFns(instance.um!)) } - name = inferFromRegistry(instance.appContext.components) + instance.isUnmounted = true + } else if (parent) { + remove(instance.block, parent) } - - return name ? classify(name) : isRoot ? `App` : `Anonymous` } -const classifyRE = /(?:^|[-_])(\w)/g -const classify = (str: string): string => - str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '') +export function getExposed( + instance: GenericComponentInstance, +): Record | undefined { + if (instance.exposed) { + return ( + instance.exposeProxy || + (instance.exposeProxy = proxyRefs(markRaw(instance.exposed))) + ) + } +} diff --cc packages/runtime-vapor/src/dom/prop.ts index 12b7f2a9da,e43cff1d93..192d14e393 --- a/packages/runtime-vapor/src/dom/prop.ts +++ b/packages/runtime-vapor/src/dom/prop.ts @@@ -12,15 -12,11 +12,10 @@@ import shouldSetAsAttr, toDisplayString, } from '@vue/shared' -import { warn } from '../warning' import { setStyle } from './style' - import { - MetadataKind, - getMetadata, - recordPropMetadata, - } from '../componentMetadata' import { on } from './event' -import type { Data } from '@vue/runtime-shared' import { currentInstance } from '../component' +import { warn } from '@vue/runtime-dom' export function mergeInheritAttr(key: string, value: any): unknown { const instance = currentInstance! @@@ -152,7 -137,7 +136,6 @@@ export function setDynamicProps args: any[], root?: boolean, ): void { - const oldProps = getMetadata(el)[MetadataKind.prop] - // const oldProps = getMetadata(el)[MetadataKind.prop] if (root) { args.unshift(currentInstance!.attrs) } diff --cc packages/runtime-vapor/src/dom/style.ts index c0a0844da9,213dfec4b7..c5d431b5dd --- a/packages/runtime-vapor/src/dom/style.ts +++ b/packages/runtime-vapor/src/dom/style.ts @@@ -6,17 -6,18 +6,18 @@@ import isString, normalizeStyle, } from '@vue/shared' -import { warn } from '../warning' +import { warn } from '@vue/runtime-dom' - import { recordPropMetadata } from '../componentMetadata' import { mergeInheritAttr } from './prop' - export function setStyle(el: HTMLElement, value: any, root?: boolean): void { - const prev = recordPropMetadata( - el, - 'style', - (value = normalizeStyle(root ? mergeInheritAttr('style', value) : value)), - ) + export function setStyle( + el: HTMLElement, + prev: any, + value: any, + root?: boolean, + ): any { + value = normalizeStyle(root ? mergeInheritAttr('style', value) : value) patchStyle(el, prev, value) + return value } // TODO copied from packages/runtime-dom/src/modules/style.ts