// 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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx, $props, $emit, $attrs, $slots) {
const n0 = t0()
- _renderEffect(() => _setText(n0, "count is ", _ctx.count, "."))
+ let _count
+ _renderEffect(() => _count !== _ctx.count && _setText(n0, "count is ", (_count = _ctx.count), "."))
return n0
}"
`;
`;
exports[`compile > directives > v-pre > should not affect siblings after it 1`] = `
-"import { resolveComponent as _resolveComponent, createComponent as _createComponent, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"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';
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
const t1 = _template("<div></div>")
const n1 = _createComponent(_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]
}"
`;
`;
exports[`compile > dynamic root nodes and interpolation 1`] = `
-"import { delegate as _delegate, setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, setDOMProp as _setDOMProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
+"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';
const t0 = _template("<button></button>")
_delegateEvents("click")
const n0 = t0()
_delegate(n0, "click", () => _ctx.handleClick)
_setInheritAttrs(["id"])
- _renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
- _renderEffect(() => _setDOMProp(n0, "id", _ctx.count))
+ 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
}"
`;
"((_ctx) => {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [{ [key.value+1]: _unref(foo)[key.value+1]() }], 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
})()"
`;
})
expect(code).matchSnapshot()
expect(code).contains('key.value+1')
- expect(code).contains('_unref(foo)[key.value+1]()')
+ expect(code).contains(
+ '(_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true))',
+ )
})
// TODO: add more test for expression parsing (v-on, v-slot, v-for)
// 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/vapor';
+"import { next as _next, createTextNode as _createTextNode, insert as _insert, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div><p></p> <!><p></p></div>")
export function render(_ctx) {
const n2 = n3.nextSibling
const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "])
_insert(n1, n4, n3)
- _renderEffect(() => _setText(n0, _ctx.first))
- _renderEffect(() => _setText(n2, _ctx.forth))
+ let _first, _forth
+ _renderEffect(() => {
+ _first !== _ctx.first && _setText(n0, (_first = _ctx.first))
+ _forth !== _ctx.forth && _setText(n2, (_forth = _ctx.forth))
+ })
return n4
}"
`;
`;
exports[`compiler: element transform > props merging: class 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setClass as _setClass, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setClass as _setClass, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["class"])
- _renderEffect(() => _setClass(n0, ["foo", { bar: _ctx.isBar }], true))
+ let _isBar
+ _renderEffect(() => _isBar !== _ctx.isBar && _setClass(n0, ["foo", { bar: (_isBar = _ctx.isBar) }], true))
return n0
}"
`;
`;
exports[`compiler: element transform > props merging: style 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setStyle as _setStyle, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setStyle as _setStyle, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
`;
exports[`compiler: element transform > v-bind="obj" 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [_ctx.obj], 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [_ctx.obj, { id: "foo" }], 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], 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/vapor';
+"import { setDynamicEvents as _setDynamicEvents, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
// 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 { setRef as _setRef, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`compiler v-bind > .attr modifier 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["foo-bar"])
- _renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["innerHTML"])
- _renderEffect(() => _setAttr(n0, "innerHTML", _ctx.foo))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["foo-bar"])
- _renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<progress></progress>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setAttr(n0, "value", _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .attr modifier w/ textContent 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["textContent"])
- _renderEffect(() => _setAttr(n0, "textContent", _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "textContent", (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .attr modifier w/ value 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setAttr(n0, "value", _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .camel modifier 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["fooBar"])
- _renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id))
+ 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 { camelize as _camelize } from 'vue';
-import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["fooBar"])
- _renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["fooBar"])
- _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["innerHTML"])
- _renderEffect(() => _setHtml(n0, _ctx.foo))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["fooBar"])
- _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<progress></progress>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setDOMProp(n0, "value", _ctx.foo))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["textContent"])
- _renderEffect(() => _setText(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .prop modifier (shorthand) w/ value 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setValue(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .prop modifier 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["fooBar"])
- _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["innerHTML"])
- _renderEffect(() => _setHtml(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .prop modifier w/ no expression 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["fooBar"])
- _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<progress></progress>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setDOMProp(n0, "value", _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .prop modifier w/ textContent 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["textContent"])
- _renderEffect(() => _setText(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > .prop modifier w/ value 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setValue(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > :innerHTML 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["innerHTML"])
- _renderEffect(() => _setHtml(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > :textContext 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["textContent"])
- _renderEffect(() => _setText(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > :value 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<input>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setValue(n0, _ctx.foo))
+ let _foo
+ _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo)))
return n0
}"
`;
exports[`compiler v-bind > :value w/ progress 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<progress></progress>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["value"])
- _renderEffect(() => _setDynamicProp(n0, "value", _ctx.foo))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["id", "title", "lang", "dir", "tabindex"])
- _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))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<math></math>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["autofucus", "dir", "displaystyle", "mathcolor", "tabindex"])
- _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))
+ 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<svg></svg>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["id", "lang", "tabindex"])
- _renderEffect(() => _setDOMProp(n0, "id", _ctx.id))
- _renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang))
- _renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.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/vapor';
+"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
const t1 = _template("<input>")
const t2 = _template("<textarea></textarea>")
const n4 = t4()
const n5 = t5()
const n6 = t6()
- _renderEffect(() => _setAttr(n0, "spellcheck", _ctx.spellcheck))
- _renderEffect(() => _setAttr(n0, "draggable", _ctx.draggable))
- _renderEffect(() => _setAttr(n0, "translate", _ctx.translate))
- _renderEffect(() => _setAttr(n0, "form", _ctx.form))
- _renderEffect(() => _setAttr(n1, "list", _ctx.list))
- _renderEffect(() => _setAttr(n2, "type", _ctx.type))
- _renderEffect(() => {
- _setAttr(n3, "width", _ctx.width)
- _setAttr(n4, "width", _ctx.width)
- _setAttr(n5, "width", _ctx.width)
- _setAttr(n6, "width", _ctx.width)
- })
+ let _spellcheck, _draggable, _translate, _form, _list, _type, _width, _height
_renderEffect(() => {
- _setAttr(n3, "height", _ctx.height)
- _setAttr(n4, "height", _ctx.height)
- _setAttr(n5, "height", _ctx.height)
- _setAttr(n6, "height", _ctx.height)
+ _spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", (_spellcheck = _ctx.spellcheck))
+ _draggable !== _ctx.draggable && _setAttr(n0, "draggable", (_draggable = _ctx.draggable))
+ _translate !== _ctx.translate && _setAttr(n0, "translate", (_translate = _ctx.translate))
+ _form !== _ctx.form && _setAttr(n0, "form", (_form = _ctx.form))
+ _list !== _ctx.list && _setAttr(n1, "list", (_list = _ctx.list))
+ _type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type))
+ if(_width !== _ctx.width) {
+ _setAttr(n3, "width", _ctx.width)
+ _setAttr(n4, "width", _ctx.width)
+ _setAttr(n5, "width", _ctx.width)
+ _setAttr(n6, "width", _ctx.width)
+ _width = _ctx.width
+ }
+ if(_height !== _ctx.height) {
+ _setAttr(n3, "height", _ctx.height)
+ _setAttr(n4, "height", _ctx.height)
+ _setAttr(n5, "height", _ctx.height)
+ _setAttr(n6, "height", _ctx.height)
+ _height = _ctx.height
+ }
})
return [n0, n1, n2, n3, n4, n5, n6]
}"
`;
exports[`compiler v-bind > basic 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["id"])
- _renderEffect(() => _setDOMProp(n0, "id", _ctx.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';
+const t0 = _template("<div></div>")
+
+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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], 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 { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["camel-case"])
- _renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase))
+ let _camelCase
+ _renderEffect(() => _camelCase !== _ctx.camelCase && (_camelCase = _setDynamicProp(n0, "camel-case", _camelCase, _ctx.camelCase)))
return n0
}"
`;
exports[`compiler v-bind > no expression 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setInheritAttrs(["id"])
- _renderEffect(() => _setDOMProp(n0, "id", _ctx.id))
+ let _id
+ _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id)))
return n0
}"
`;
// 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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
`;
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/vapor';
+"import { delegate as _delegate, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
_delegateEvents("click")
`;
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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
`;
exports[`compiler: v-for > multi effect 1`] = `
-"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, createFor as _createFor, template as _template } from 'vue/vapor';
+"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = _createFor(() => (_ctx.items), (_ctx0) => {
const n2 = t0()
_setInheritAttrs(["item", "index"])
- _renderEffect(() => _setDynamicProp(n2, "item", _ctx0[0].value))
- _renderEffect(() => _setDynamicProp(n2, "index", _ctx0[1].value))
+ _renderEffect(() => {
+ _setDynamicProp(n2, "item", _ctx0[0].value)
+ _setDynamicProp(n2, "index", _ctx0[1].value)
+ })
return n2
})
return n0
`;
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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, insert as _insert, template as _template } from 'vue/vapor';
const t0 = _template("<span></span>")
const t1 = _template("<div></div>")
`;
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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
`;
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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
// 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/vapor';
+"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx, $props, $emit, $attrs, $slots) {
const n0 = t0()
- _renderEffect(() => _setHtml(n0, _ctx.code))
+ let _code
+ _renderEffect(() => _code !== _ctx.code && _setHtml(n0, (_code = _ctx.code)))
return n0
}"
`;
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/vapor';
+"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
- _renderEffect(() => _setHtml(n0, _ctx.test))
+ let _test
+ _renderEffect(() => _test !== _ctx.test && _setHtml(n0, (_test = _ctx.test)))
return n0
}"
`;
// 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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = _createIf(() => (_ctx.ok), () => {
const n2 = t0()
- _renderEffect(() => _setText(n2, _ctx.msg))
+ let _msg
+ _renderEffect(() => _msg !== _ctx.msg && _setText(n2, (_msg = _ctx.msg)))
return n2
})
return n0
`;
exports[`compiler: v-if > comment between branches 1`] = `
-"import { createIf as _createIf, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
+"import { createIf as _createIf, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
const t1 = _template("<!--foo-->")
const t2 = _template("<p></p>")
const n11 = t4()
return [n10, n11]
}))
- _renderEffect(() => _setText(n13, _ctx.text))
+ let _text
+ _renderEffect(() => _text !== _ctx.text && _setText(n13, (_text = _ctx.text)))
return [n0, n13]
}"
`;
`;
exports[`compiler: v-if > template v-if 1`] = `
-"import { renderEffect as _renderEffect, setText as _setText, createIf as _createIf, template as _template } from 'vue/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
const t1 = _template("hello")
const t2 = _template("<p></p>")
const n2 = t0()
const n3 = t1()
const n4 = t2()
- _renderEffect(() => _setText(n4, _ctx.msg))
+ let _msg
+ _renderEffect(() => _msg !== _ctx.msg && _setText(n4, (_msg = _ctx.msg)))
return [n2, n3, n4]
})
return n0
`;
exports[`compiler: vModel transform > should support w/ dynamic v-bind 1`] = `
-"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
+"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';
const t0 = _template("<input>")
export function render(_ctx) {
_withDirectives(n0, [[_vModelDynamic, () => _ctx.model]])
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
_setInheritAttrs(true)
- _renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true))
+ let _obj
+ _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj], true)))
return n0
}"
`;
`;
exports[`v-on > dynamic arg 1`] = `
-"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor';
+"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => {
+
_on(n0, _ctx.event, () => _ctx.handler, {
effect: true
})
`;
exports[`v-on > dynamic arg with complex exp prefixing 1`] = `
-"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor';
+"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => {
+
_on(n0, _ctx.event(_ctx.foo), () => _ctx.handler, {
effect: true
})
`;
exports[`v-on > dynamic arg with prefixing 1`] = `
-"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor';
+"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => {
+
_on(n0, _ctx.event, () => _ctx.handler, {
effect: true
})
`;
exports[`v-on > should transform click.middle 2`] = `
-"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor';
+"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => {
+
_on(n0, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), () => _ctx.test, {
modifiers: ["middle"],
effect: true
`;
exports[`v-on > should transform click.right 2`] = `
-"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor';
+"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => {
+
_on(n0, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), () => _ctx.test, {
modifiers: ["right"],
keys: ["right"],
`;
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/vapor';
+"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => {
+
_on(n0, _ctx.e, () => _ctx.test, {
modifiers: ["left"],
keys: ["left"],
// 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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx, $props, $emit, $attrs, $slots) {
const n0 = t0()
- _renderEffect(() => _setText(n0, _ctx.str))
+ let _str
+ _renderEffect(() => _str !== _ctx.str && _setText(n0, (_str = _ctx.str)))
return n0
}"
`;
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/vapor';
+"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
- _renderEffect(() => _setText(n0, _ctx.test))
+ let _test
+ _renderEffect(() => _test !== _ctx.test && _setText(n0, (_test = _ctx.test)))
return n0
}"
`;
],
},
])
- expect(code).contains('_setDynamicProps(n0, [_ctx.obj], true)')
+ expect(code).contains(
+ '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj], true))',
+ )
})
test('v-bind="obj" after static prop', () => {
},
])
expect(code).contains(
- '_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true)',
+ '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj], true))',
)
})
},
])
expect(code).contains(
- '_setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true)',
+ '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj, { id: "foo" }], true))',
)
})
},
])
expect(code).contains(
- '_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true)',
+ '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true))',
)
})
})
expect(code).matchSnapshot()
- expect(code).contains('_setDOMProp(n0, "id", _ctx.id)')
+ expect(code).contains(
+ '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))',
+ )
})
test('no expression', () => {
],
},
})
- expect(code).contains('_setDOMProp(n0, "id", _ctx.id)')
+ expect(code).contains(
+ '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))',
+ )
})
test('no expression (shorthand)', () => {
],
},
})
- expect(code).contains('_setDynamicProp(n0, "camel-case", _ctx.camelCase)')
+ expect(code).contains(
+ '_camelCase !== _ctx.camelCase && (_camelCase = _setDynamicProp(n0, "camel-case", _camelCase, _ctx.camelCase))',
+ )
})
test('dynamic arg', () => {
],
})
expect(code).contains(
- '_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true)',
+ '(_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true))',
)
})
],
})
expect(code).contains(
- '_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true)',
+ '_id !== _ctx.id && (_id = _setDynamicProps(n0, _id, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true))',
)
})
})
expect(code).matchSnapshot()
- expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id)')
+ expect(code).contains(
+ '_id !== _ctx.id && (_id = _setDynamicProp(n0, "fooBar", _id, _ctx.id))',
+ )
})
test('.camel modifier w/ no expression', () => {
},
})
expect(code).contains('renderEffect')
- expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar)')
+ expect(code).contains(
+ '_fooBar !== _ctx.fooBar && (_fooBar = _setDynamicProp(n0, "fooBar", _fooBar, _ctx.fooBar))',
+ )
})
test('.camel modifier w/ dynamic arg', () => {
expect(code).matchSnapshot()
expect(code).contains('renderEffect')
expect(code).contains(
- `_setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true)`,
+ `(_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize(_ctx.foo)]: _ctx.id }], true))`,
)
})
},
})
expect(code).contains('renderEffect')
- expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
+ expect(code).contains(
+ '_id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))',
+ )
})
test('.prop modifier w/ no expression', () => {
},
})
expect(code).contains('renderEffect')
- expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)')
+ expect(code).contains(
+ '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))',
+ )
})
test('.prop modifier w/ dynamic arg', () => {
})
expect(code).contains('renderEffect')
expect(code).contains(
- `_setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true)`,
+ `(_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + _ctx.fooBar]: _ctx.id }], true))`,
)
})
},
})
expect(code).contains('renderEffect')
- expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
+ expect(code).contains(
+ '_id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))',
+ )
})
test('.prop modifier (shorthand) w/ no expression', () => {
},
})
expect(code).contains('renderEffect')
- expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)')
+ expect(code).contains(
+ '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))',
+ )
})
test('.prop modifier w/ innerHTML', () => {
const { code } = compileWithVBind(`<div :innerHTML.prop="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setHtml(n0, _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))',
+ )
})
test('.prop modifier (shorthand) w/ innerHTML', () => {
const { code } = compileWithVBind(`<div .innerHTML="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setHtml(n0, _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))',
+ )
})
test('.prop modifier w/ textContent', () => {
const { code } = compileWithVBind(`<div :textContent.prop="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setText(n0, _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))',
+ )
})
test('.prop modifier (shorthand) w/ textContent', () => {
const { code } = compileWithVBind(`<div .textContent="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setText(n0, _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))',
+ )
})
test('.prop modifier w/ value', () => {
const { code } = compileWithVBind(`<div :value.prop="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setValue(n0, _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))',
+ )
})
test('.prop modifier (shorthand) w/ value', () => {
const { code } = compileWithVBind(`<div .value="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setValue(n0, _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))',
+ )
})
test('.prop modifier w/ progress value', () => {
const { code } = compileWithVBind(`<progress :value.prop="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setDOMProp(n0, "value", _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))',
+ )
})
test('.prop modifier (shorthand) w/ progress value', () => {
const { code } = compileWithVBind(`<progress .value="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setDOMProp(n0, "value", _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))',
+ )
})
test('.attr modifier', () => {
},
})
expect(code).contains('renderEffect')
- expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id)')
+ expect(code).contains(
+ '_id !== _ctx.id && _setAttr(n0, "foo-bar", (_id = _ctx.id))',
+ )
})
test('.attr modifier w/ no expression', () => {
})
expect(code).contains('renderEffect')
- expect(code).contains('_setAttr(n0, "foo-bar", _ctx.fooBar)')
+ expect(code).contains(
+ '_fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", (_fooBar = _ctx.fooBar))',
+ )
})
test('.attr modifier w/ innerHTML', () => {
const { code } = compileWithVBind(`<div :innerHTML.attr="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setAttr(n0, "innerHTML", _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setAttr(n0, "innerHTML", (_foo = _ctx.foo))',
+ )
})
test('.attr modifier w/ textContent', () => {
const { code } = compileWithVBind(`<div :textContent.attr="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setAttr(n0, "textContent", _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setAttr(n0, "textContent", (_foo = _ctx.foo))',
+ )
})
test('.attr modifier w/ value', () => {
const { code } = compileWithVBind(`<div :value.attr="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setAttr(n0, "value", _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))',
+ )
})
test('.attr modifier w/ progress value', () => {
const { code } = compileWithVBind(`<progress :value.attr="foo" />`)
expect(code).matchSnapshot()
- expect(code).contains('_setAttr(n0, "value", _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))',
+ )
})
test('attributes must be set as attribute', () => {
`)
expect(code).matchSnapshot()
- expect(code).contains('_setAttr(n0, "spellcheck", _ctx.spellcheck)')
- expect(code).contains('_setAttr(n0, "draggable", _ctx.draggable)')
- expect(code).contains('_setAttr(n0, "translate", _ctx.translate)')
- expect(code).contains('_setAttr(n0, "form", _ctx.form)')
- expect(code).contains('_setAttr(n1, "list", _ctx.list)')
- expect(code).contains('_setAttr(n2, "type", _ctx.type)')
+ expect(code).contains(
+ '_spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", (_spellcheck = _ctx.spellcheck))',
+ )
+ expect(code).contains(
+ '_draggable !== _ctx.draggable && _setAttr(n0, "draggable", (_draggable = _ctx.draggable))',
+ )
+ expect(code).contains(
+ '_translate !== _ctx.translate && _setAttr(n0, "translate", (_translate = _ctx.translate))',
+ )
+ expect(code).contains(
+ '_form !== _ctx.form && _setAttr(n0, "form", (_form = _ctx.form))',
+ )
+ expect(code).contains(
+ '_list !== _ctx.list && _setAttr(n1, "list", (_list = _ctx.list))',
+ )
+ expect(code).contains(
+ '_type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type))',
+ )
+ expect(code).contains('if(_width !== _ctx.width) {')
+ expect(code).contains('if(_height !== _ctx.height) {')
+ expect(code).contains('_height = _ctx.height')
+ expect(code).contains('_height = _ctx.height')
expect(code).contains('_setAttr(n3, "width", _ctx.width)')
expect(code).contains('_setAttr(n3, "height", _ctx.height)')
expect(code).contains('_setAttr(n4, "width", _ctx.width)')
expect(code).contains('_setAttr(n4, "height", _ctx.height)')
expect(code).contains('_setAttr(n5, "width", _ctx.width)')
expect(code).contains('_setAttr(n5, "height", _ctx.height)')
- expect(code).contains('_setAttr(n6, "width", _ctx.width)')
- expect(code).contains('_setAttr(n6, "height", _ctx.height)')
+ expect(code).contains(' _setAttr(n6, "width", _ctx.width)')
})
test('HTML global attributes should set as dom prop', () => {
`)
expect(code).matchSnapshot()
- expect(code).contains('_setDOMProp(n0, "id", _ctx.id)')
- expect(code).contains('_setDOMProp(n0, "title", _ctx.title)')
- expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang)')
- expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir)')
- expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)')
+ expect(code).contains(
+ '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))',
+ )
+ expect(code).contains(
+ '_title !== _ctx.title && _setDOMProp(n0, "title", (_title = _ctx.title))',
+ )
+ expect(code).contains(
+ '_lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))',
+ )
+ expect(code).contains(
+ '_dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))',
+ )
+ expect(code).contains(
+ '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))',
+ )
})
test('SVG global attributes should set as dom prop', () => {
`)
expect(code).matchSnapshot()
- expect(code).contains('_setDOMProp(n0, "id", _ctx.id)')
- expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang)')
- expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)')
+ expect(code).contains(
+ '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))',
+ )
+ expect(code).contains(
+ '_lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))',
+ )
+ expect(code).contains(
+ '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))',
+ )
})
test('MathML global attributes should set as dom prop', () => {
`)
expect(code).matchSnapshot()
- expect(code).contains('_setDOMProp(n0, "autofucus", _ctx.autofucus)')
- expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir)')
- expect(code).contains('_setDOMProp(n0, "displaystyle", _ctx.displaystyle)')
- expect(code).contains('_setDOMProp(n0, "mathcolor", _ctx.mathcolor)')
- expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)')
+ expect(code).contains(
+ '_autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus))',
+ )
+ expect(code).contains(
+ '_dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))',
+ )
+ expect(code).contains(
+ '_displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle))',
+ )
+ expect(code).contains(
+ '_mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor))',
+ )
+ expect(code).contains(
+ '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))',
+ )
})
test(':innerHTML', () => {
<div :innerHTML="foo"/>
`)
expect(code).matchSnapshot()
- expect(code).contains('_setHtml(n0, _ctx.foo)')
+ expect(code).contains('let _foo')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))',
+ )
})
test(':textContext', () => {
<div :textContent="foo"/>
`)
expect(code).matchSnapshot()
- expect(code).contains('_setText(n0, _ctx.foo)')
+ expect(code).contains('let _foo')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))',
+ )
})
test(':value', () => {
<input :value="foo"/>
`)
expect(code).matchSnapshot()
- expect(code).contains('_setValue(n0, _ctx.foo)')
+ expect(code).contains('let _foo')
+ expect(code).contains(
+ '_foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))',
+ )
})
test(':value w/ progress', () => {
<progress :value="foo"/>
`)
expect(code).matchSnapshot()
- expect(code).contains('_setDynamicProp(n0, "value", _ctx.foo)')
+ expect(code).contains(
+ '_foo !== _ctx.foo && (_foo = _setDynamicProp(n0, "value", _foo, _ctx.foo))',
+ )
+ })
+
+ test('bind member expression', () => {
+ const { code } = compileWithVBind(`
+ <div :id="obj.count.bar"></div>/>
+ `)
+ expect(code).matchSnapshot()
+ expect(code).contains(
+ '_obj !== _ctx.obj.count.bar && _setDOMProp(n0, "id", (_obj = _ctx.obj.count.bar))',
+ )
})
test('number value', () => {
CodegenOptions as BaseCodegenOptions,
BaseCodegenResult,
} from '@vue/compiler-dom'
-import type { BlockIRNode, RootIRNode, VaporHelper } from './ir'
+import type { BlockIRNode, IREffect, RootIRNode, VaporHelper } from './ir'
import { extend, remove } from '@vue/shared'
import { genBlockContent } from './generators/block'
import { genTemplates } from './generators/template'
delegates: Set<string> = new Set<string>()
+ processingRenderEffect: IREffect | undefined = undefined
+ allRenderEffectSeenNames: Record<string, number> = Object.create(null)
+ shouldCacheRenderEffectDeps = (): boolean => {
+ // only need to generate effect deps when it's not nested in v-for
+ return !!(
+ this.processingRenderEffect && !this.processingRenderEffect.inVFor
+ )
+ }
+
identifiers: Record<string, string[]> = Object.create(null)
block: BlockIRNode
-import { isGloballyAllowed } from '@vue/shared'
+import { isArray, isGloballyAllowed } from '@vue/shared'
import {
BindingTypes,
NewlineType,
)
if (i === ids.length - 1 && end < content.length) {
- push([content.slice(end), NewlineType.Unknown])
+ const rest = content.slice(end)
+ const last = frag[frag.length - 1]
+ if (hasMemberExpression && isArray(last)) {
+ // merge rest content into the last identifier's generated name
+ last[0] += rest
+ } else {
+ push([rest, NewlineType.Unknown])
+ }
}
})
import type { SetHtmlIRNode } from '../ir'
import { genExpression } from './expression'
import { type CodeFragment, NEWLINE, genCall } from './utils'
+import { processValues } from './prop'
export function genSetHtml(
oper: SetHtmlIRNode,
context: CodegenContext,
): CodeFragment[] {
- const { vaporHelper } = context
- return [
- NEWLINE,
- ...genCall(
- vaporHelper('setHtml'),
- `n${oper.element}`,
- genExpression(oper.value, context),
- ),
- ]
+ const { vaporHelper, shouldCacheRenderEffectDeps } = context
+ const { value, element } = oper
+ let html = genExpression(value, context)
+ if (shouldCacheRenderEffectDeps()) {
+ processValues(context, [html])
+ }
+ return [NEWLINE, ...genCall(vaporHelper('setHtml'), `n${element}`, html)]
}
effects: IREffect[],
context: CodegenContext,
): CodeFragment[] {
- const [frag, push] = buildCodeFragment()
- for (const effect of effects) {
- push(...genEffect(effect, context))
+ const { vaporHelper } = context
+ const [frag, push, unshift] = buildCodeFragment()
+ const declareNames = new Set<string>()
+ 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')}(() => `)
+ push(`)`)
+ }
+
+ // declare variables: let _foo, _bar
+ if (declareNames.size) {
+ frag.splice(1, 0, `let ${[...declareNames].join(', ')}`, NEWLINE)
}
return frag
}
export function genEffect(
{ operations }: IREffect,
context: CodegenContext,
+ allDeclareNames: Set<string>,
): CodeFragment[] {
- const { vaporHelper } = context
- const [frag, push] = buildCodeFragment(
- NEWLINE,
- `${vaporHelper('renderEffect')}(() => `,
- )
+ const { processingRenderEffect } = context
+ const [frag, push] = buildCodeFragment()
+ const { declareNames, earlyCheckExps } = processingRenderEffect!
+ const operationsExps = genOperations(operations, context)
- const [operationsExps, pushOps] = buildCodeFragment()
- operations.forEach(op => pushOps(...genOperation(op, context)))
+ if (declareNames.size) {
+ allDeclareNames.add([...declareNames].join(', '))
+ }
const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length
if (newlineCount > 1) {
- push('{', INDENT_START, ...operationsExps, INDENT_END, NEWLINE, '})')
+ // multiline check expression: if (_foo !== _ctx.foo || _bar !== _ctx.bar) {
+ const checkExpsStart: CodeFragment[] =
+ earlyCheckExps.length > 0
+ ? [`if(`, ...earlyCheckExps.join(' || '), `) {`, INDENT_START]
+ : []
+ const checkExpsEnd: CodeFragment[] =
+ earlyCheckExps.length > 0 ? [INDENT_END, NEWLINE, '}'] : []
+ // assignment: _foo = _ctx.foo; _bar = _ctx.bar
+ const assignmentExps: CodeFragment[] =
+ earlyCheckExps.length > 0
+ ? [NEWLINE, ...earlyCheckExps.map(c => c.replace('!==', '=')).join(';')]
+ : []
+ push(
+ ...checkExpsStart,
+ ...operationsExps,
+ ...assignmentExps,
+ ...checkExpsEnd,
+ )
} else {
- push(...operationsExps.filter(frag => frag !== NEWLINE), ')')
+ // single line check expression: (_foo !== _ctx.foo || _bar !== _ctx.bar) &&
+ const multiple = earlyCheckExps.length > 1
+ const checkExps: CodeFragment[] =
+ earlyCheckExps.length > 0
+ ? [
+ multiple ? `(` : undefined,
+ ...earlyCheckExps.join(' || '),
+ multiple ? `)` : undefined,
+ ' && ',
+ ]
+ : []
+ push(...checkExps, ...operationsExps.filter(frag => frag !== NEWLINE))
}
return frag
import {
attributeCache,
canSetValueDirectly,
+ isArray,
isHTMLGlobalAttr,
isHTMLTag,
isMathMLGlobalAttr,
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],
`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'
: undefined,
),
+ ...(prevValueName && shouldWrapInParentheses ? [`)`] : []),
]
}
context: CodegenContext,
): CodeFragment[] {
const { vaporHelper } = 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'),
`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 ? [`)`] : []),
]
}
return specialHelpers[keyName] || null
}
+
+// those runtime helpers will return the prevValue
+const helpersNeedCachedReturnValue = [
+ 'setStyle',
+ 'setDynamicProp',
+ 'setDynamicProps',
+]
+
+function processPropValues(
+ context: CodegenContext,
+ helperName: string,
+ values: CodeFragment[][],
+): { prevValueName: string | undefined; shouldWrapInParentheses: boolean } {
+ const { shouldCacheRenderEffectDeps, processingRenderEffect } = context
+ // single-line render effect and the operation needs cache return a value,
+ // the expression needs to be wrapped in parentheses.
+ // e.g. _foo === _ctx.foo && (_foo = _setStyle(...))
+ let shouldWrapInParentheses: boolean = false
+ let prevValueName
+ if (shouldCacheRenderEffectDeps()) {
+ const needReturnValue = helpersNeedCachedReturnValue.includes(helperName)
+ processValues(context, values, !needReturnValue)
+ const { declareNames } = processingRenderEffect!
+ // if the operation needs to cache the return value and has multiple declareNames,
+ // combine them into a single name as the return value name.
+ if (declareNames.size > 0 && needReturnValue) {
+ prevValueName = [...declareNames].join('')
+ declareNames.add(prevValueName)
+ }
+ shouldWrapInParentheses = processingRenderEffect!.operations.length === 1
+ }
+ return { prevValueName, shouldWrapInParentheses }
+}
+
+export function processValues(
+ context: CodegenContext,
+ values: CodeFragment[][],
+ needRewrite: boolean = true,
+): string[] {
+ const allCheckExps: string[] = []
+ values.forEach(value => {
+ const checkExps = processValue(context, value, needRewrite)
+ if (checkExps) allCheckExps.push(...checkExps, ' && ')
+ })
+
+ return allCheckExps.length > 0
+ ? (context.processingRenderEffect!.earlyCheckExps = [
+ ...new Set(allCheckExps),
+ ])
+ : []
+}
+
+function processValue(
+ context: CodegenContext,
+ values: CodeFragment[],
+ needRewrite: boolean = true,
+): string[] | undefined {
+ const { processingRenderEffect, allRenderEffectSeenNames } = context
+ const { declareNames, rewrittenNames, earlyCheckExps, operations } =
+ processingRenderEffect!
+
+ const isSingleLine = operations.length === 1
+ for (const frag of values) {
+ if (!isArray(frag)) continue
+ // [code, newlineIndex, loc, name] -> [(_name = code), newlineIndex, loc, name]
+ const [newName, , , rawName] = frag
+ if (rawName) {
+ let name = rawName.replace(/[^\w]/g, '_')
+ if (rewrittenNames.has(name)) continue
+ rewrittenNames.add(name)
+
+ name = `_${name}`
+ if (declareNames.has(name)) continue
+
+ if (allRenderEffectSeenNames[name] === undefined)
+ allRenderEffectSeenNames[name] = 0
+ else name += ++allRenderEffectSeenNames[name]
+
+ declareNames.add(name)
+ earlyCheckExps.push(`${name} !== ${newName}`)
+
+ if (needRewrite && isSingleLine) {
+ // replace the original code fragment with the assignment expression
+ frag[0] = `(${name} = ${newName})`
+ }
+ }
+ }
+
+ if (earlyCheckExps.length > 0) {
+ return [[...new Set(earlyCheckExps)].join(' && ')]
+ }
+}
genCall,
genMulti,
} from './utils'
+import { processValues } from './prop'
export function genSetText(
oper: SetTextIRNode,
context: CodegenContext,
): CodeFragment[] {
- const { vaporHelper } = context
+ const { vaporHelper, shouldCacheRenderEffectDeps } = context
const { element, values } = oper
- return [
- NEWLINE,
- ...genCall(
- vaporHelper('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)]
}
export function genCreateTextNode(
export function buildCodeFragment(
...frag: CodeFragment[]
-): [CodeFragment[], (...items: CodeFragment[]) => number] {
+): [
+ CodeFragment[],
+ (...items: CodeFragment[]) => number,
+ (...items: CodeFragment[]) => number,
+] {
const push = frag.push.bind(frag)
- return [frag, push]
+ const unshift = frag.unshift.bind(frag)
+ return [frag, push, unshift]
}
export type CodeFragmentDelimiters = [
export interface IREffect {
expressions: SimpleExpressionNode[]
+ identifiers: string[]
operations: OperationNode[]
+ declareNames: Set<string>
+ rewrittenNames: Set<string>
+ earlyCheckExps: string[]
+ inVFor: boolean
}
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> &
type CompilerCompatOptions,
type ElementNode,
ElementTypes,
+ type ExpressionNode,
NodeTypes,
type RootNode,
type SimpleExpressionNode,
defaultOnError,
defaultOnWarn,
isVSlot,
+ walkIdentifiers,
} from '@vue/compiler-dom'
-import { EMPTY_OBJ, NOOP, extend, isArray, isString } from '@vue/shared'
+import {
+ EMPTY_OBJ,
+ NOOP,
+ extend,
+ isArray,
+ isString,
+ looseEqual,
+} from '@vue/shared'
import {
type BlockIRNode,
DynamicFlag,
if (this.inVOnce || expressions.length === 0) {
return this.registerOperation(...operations)
}
+ const ids = new Set<string>()
+ expressions.forEach(exp => extractIdentifiers(ids, exp))
const existing = this.block.effect.find(e =>
- isSameExpression(e.expressions, expressions),
+ looseEqual(e.identifiers, Array.from(ids)),
)
if (existing) {
existing.operations.push(...operations)
this.block.effect.push({
expressions,
operations,
+ earlyCheckExps: [],
+ declareNames: new Set<string>(),
+ rewrittenNames: new Set<string>(),
+ inVFor: this.inVFor > 0,
+ identifiers: Array.from(ids),
})
}
-
- function isSameExpression(
- a: SimpleExpressionNode[],
- b: SimpleExpressionNode[],
- ) {
- if (a.length !== b.length) return false
- return a.every((exp, i) => exp.content === b[i].content)
- }
}
registerOperation(...node: OperationNode[]): void {
this.block.operation.push(...node)
}
}
}
+
+function extractIdentifiers(ids: Set<string>, node: ExpressionNode) {
+ if (node.ast) {
+ walkIdentifiers(node.ast, n => ids.add(n.name), true)
+ } else if (node.ast === null) {
+ ids.add((node as SimpleExpressionNode).content)
+ }
+}
inheritAttrs: false,
setup(props, { attrs }) {
const el = document.createElement('div')
- renderEffect(() => setDynamicProps(el, [attrs]))
+ let prev: any
+ renderEffect(() => (prev = setDynamicProps(el, prev, [attrs])))
return el
},
})
const n0 = createComponent(Wrapper, null, {
default: () => {
const n0 = template('<div>')() as HTMLDivElement
- renderEffect(() => setDynamicProps(n0, [attrs], true))
+ let prev: any
+ renderEffect(
+ () => (prev = setDynamicProps(n0, prev, [attrs], true)),
+ )
return n0
},
})
ComponentInternalInstance,
setCurrentInstance,
} from '../../src/component'
-import { getMetadata, recordPropMetadata } from '../../src/componentMetadata'
import { getCurrentScope } from '@vue/reactivity'
let removeComponentInstance = NOOP
})
describe('patchProp', () => {
- describe('recordPropMetadata', () => {
- test('should record prop metadata', () => {
- const node = {} as Node // the node is just a key
- let prev = recordPropMetadata(node, 'class', 'foo')
- expect(prev).toBeUndefined()
- prev = recordPropMetadata(node, 'class', 'bar')
- expect(prev).toBe('foo')
- prev = recordPropMetadata(node, 'style', 'color: red')
- expect(prev).toBeUndefined()
- prev = recordPropMetadata(node, 'style', 'color: blue')
- expect(prev).toBe('color: red')
-
- expect(getMetadata(node)).toEqual([
- { class: 'bar', style: 'color: blue' },
- {},
- ])
- })
-
- test('should have different metadata for different nodes', () => {
- const node1 = {} as Node
- const node2 = {} as Node
- recordPropMetadata(node1, 'class', 'foo')
- recordPropMetadata(node2, 'class', 'bar')
- expect(getMetadata(node1)).toEqual([{ class: 'foo' }, {}])
- expect(getMetadata(node2)).toEqual([{ class: 'bar' }, {}])
- })
- })
-
describe('setClass', () => {
test('should set class', () => {
const el = document.createElement('div')
describe('setStyle', () => {
test('should set style', () => {
const el = document.createElement('div')
- setStyle(el, 'color: red')
+ setStyle(el, '', 'color: red')
expect(el.style.cssText).toBe('color: red;')
})
test('should work with camelCase', () => {
const el = document.createElement('div')
- setStyle(el, { fontSize: '12px' })
+ setStyle(el, null, { fontSize: '12px' })
expect(el.style.cssText).toBe('font-size: 12px;')
})
test('shoud set style with object and array property', () => {
const el = document.createElement('div')
- setStyle(el, { color: 'red' })
+ let prev: any
+ prev = setStyle(el, prev, { color: 'red' })
expect(el.style.cssText).toBe('color: red;')
- setStyle(el, [{ color: 'blue' }, { fontSize: '12px' }])
+ setStyle(el, prev, [{ color: 'blue' }, { fontSize: '12px' }])
expect(el.style.cssText).toBe('color: blue; font-size: 12px;')
})
test('should remove if falsy value', () => {
const el = document.createElement('div')
- setStyle(el, { color: undefined, borderRadius: null })
+ let prev
+ prev = setStyle(el, prev, { color: undefined, borderRadius: null })
expect(el.style.cssText).toBe('')
- setStyle(el, { color: 'red' })
+ prev = setStyle(el, prev, { color: 'red' })
expect(el.style.cssText).toBe('color: red;')
- setStyle(el, { color: undefined, borderRadius: null })
+ setStyle(el, prev, { color: undefined, borderRadius: null })
expect(el.style.cssText).toBe('')
})
test('should work with !important', () => {
const el = document.createElement('div')
- setStyle(el, { color: 'red !important' })
+ setStyle(el, null, { color: 'red !important' })
expect(el.style.cssText).toBe('color: red !important;')
})
test('should work with camelCase and !important', () => {
const el = document.createElement('div')
- setStyle(el, { fontSize: '12px !important' })
+ setStyle(el, null, { fontSize: '12px !important' })
expect(el.style.cssText).toBe('font-size: 12px !important;')
})
test('should work with multiple entries', () => {
const el = document.createElement('div')
- setStyle(el, { color: 'red', marginRight: '10px' })
+ setStyle(el, null, { color: 'red', marginRight: '10px' })
expect(el.style.getPropertyValue('color')).toBe('red')
expect(el.style.getPropertyValue('margin-right')).toBe('10px')
})
test('should patch with falsy style value', () => {
const el = document.createElement('div')
- setStyle(el, { width: '100px' })
+ let prev: any
+ prev = setStyle(el, prev, { width: '100px' })
expect(el.style.cssText).toBe('width: 100px;')
- setStyle(el, { width: 0 })
+ prev = setStyle(el, prev, { width: 0 })
expect(el.style.cssText).toBe('width: 0px;')
})
test('should remove style attribute on falsy value', () => {
const el = document.createElement('div')
- setStyle(el, { width: '100px' })
+ let prev: any
+ prev = setStyle(el, prev, { width: '100px' })
expect(el.style.cssText).toBe('width: 100px;')
- setStyle(el, { width: undefined })
+ prev = setStyle(el, prev, { width: undefined })
expect(el.style.cssText).toBe('')
- setStyle(el, { width: '100px' })
+ prev = setStyle(el, prev, { width: '100px' })
expect(el.style.cssText).toBe('width: 100px;')
- setStyle(el, null)
+ setStyle(el, prev, null)
expect(el.hasAttribute('style')).toBe(false)
expect(el.style.cssText).toBe('')
})
test('should warn for trailing semicolons', () => {
const el = document.createElement('div')
- setStyle(el, { color: 'red;' })
+ setStyle(el, null, { color: 'red;' })
expect(
`Unexpected semicolon at the end of 'color' style value: 'red;'`,
).toHaveBeenWarned()
- setStyle(el, { '--custom': '100; ' })
+ setStyle(el, null, { '--custom': '100; ' })
expect(
`Unexpected semicolon at the end of '--custom' style value: '100; '`,
).toHaveBeenWarned()
test('should not warn for trailing semicolons', () => {
const el = document.createElement('div')
- setStyle(el, { '--custom': '100\\;' })
+ setStyle(el, null, { '--custom': '100\\;' })
expect(el.style.getPropertyValue('--custom')).toBe('100\\;')
})
test('should work with shorthand properties', () => {
const el = document.createElement('div')
- setStyle(el, { borderBottom: '1px solid red', border: '1px solid green' })
+ setStyle(el, null, {
+ borderBottom: '1px solid red',
+ border: '1px solid green',
+ })
expect(el.style.border).toBe('1px solid green')
expect(el.style.borderBottom).toBe('1px solid green')
})
test('should work with css custom properties', () => {
const el = mockElementWithStyle()
- setStyle(el as any, { '--theme': 'red' })
+ setStyle(el as any, null, { '--theme': 'red' })
expect(el.style.getPropertyValue('--theme')).toBe('red')
})
test('should auto vendor prefixing', () => {
const el = mockElementWithStyle()
- setStyle(el as any, { transition: 'all 1s' })
+ setStyle(el as any, null, { transition: 'all 1s' })
expect(el.style.WebkitTransition).toBe('all 1s')
})
test('should work with multiple values', () => {
const el = mockElementWithStyle()
- setStyle(el as any, { display: ['-webkit-box', '-ms-flexbox', 'flex'] })
+ setStyle(el as any, null, {
+ display: ['-webkit-box', '-ms-flexbox', 'flex'],
+ })
expect(el.style.display).toBe('flex')
})
})
describe('setDynamicProp', () => {
const element = document.createElement('div')
+ let prev: any
function setDynamicProp(
key: string,
value: any,
el = element.cloneNode(true) as HTMLElement,
) {
- _setDynamicProp(el, key, value)
+ prev = _setDynamicProp(el, key, prev, value)
return el
}
describe('setDynamicProps', () => {
test('basic set dynamic props', () => {
const el = document.createElement('div')
- setDynamicProps(el, [{ foo: 'val' }, { bar: 'val' }])
+ setDynamicProps(el, null, [{ foo: 'val' }, { bar: 'val' }])
expect(el.getAttribute('foo')).toBe('val')
expect(el.getAttribute('bar')).toBe('val')
})
test('should merge props', () => {
const el = document.createElement('div')
- setDynamicProps(el, [{ foo: 'val' }, { foo: 'newVal' }])
+ setDynamicProps(el, null, [{ foo: 'val' }, { foo: 'newVal' }])
expect(el.getAttribute('foo')).toBe('newVal')
})
test('should reset old props', () => {
const el = document.createElement('div')
-
- setDynamicProps(el, [{ foo: 'val' }])
+ let prev: any
+ prev = setDynamicProps(el, prev, [{ foo: 'val' }])
expect(el.attributes.length).toBe(1)
expect(el.getAttribute('foo')).toBe('val')
- setDynamicProps(el, [{ bar: 'val' }])
+ prev = setDynamicProps(el, prev, [{ bar: 'val' }])
expect(el.attributes.length).toBe(1)
expect(el.getAttribute('bar')).toBe('val')
expect(el.getAttribute('foo')).toBeNull()
test('should reset old modifier props', () => {
const el = document.createElement('div')
- setDynamicProps(el, [{ ['.foo']: 'val' }])
+ let prev: any
+ prev = setDynamicProps(el, prev, [{ ['.foo']: 'val' }])
expect((el as any).foo).toBe('val')
- setDynamicProps(el, [{ ['.bar']: 'val' }])
+ prev = setDynamicProps(el, prev, [{ ['.bar']: 'val' }])
expect((el as any).bar).toBe('val')
expect((el as any).foo).toBe('')
- setDynamicProps(el, [{ ['^foo']: 'val' }])
+ prev = setDynamicProps(el, prev, [{ ['^foo']: 'val' }])
expect(el.attributes.length).toBe(1)
expect(el.getAttribute('foo')).toBe('val')
- setDynamicProps(el, [{ ['^bar']: 'val' }])
+ prev = setDynamicProps(el, prev, [{ ['^bar']: 'val' }])
expect(el.attributes.length).toBe(1)
expect(el.getAttribute('bar')).toBe('val')
expect(el.getAttribute('foo')).toBeNull()
}
}
+ let prevAttrs = instance.attrs
renderEffect(() => {
for (const key in instance.attrs) {
if (dynamicAttrs && dynamicAttrs.includes(key)) continue
value = instance.attrs[key]
}
- setDynamicProp(element, key, value)
+ setDynamicProp(element, key, prevAttrs[key], value)
}
})
}
if (rawProps || Object.keys(instance.attrs).length) {
rawProps = [() => instance.attrs, ...normalizeRawProps(rawProps)]
+ let prevValue: any, prevStyle: any
renderEffect(() => {
let classes: unknown[] | undefined
let styles: unknown[] | undefined
const value = getter ? valueOrGetter() : valueOrGetter
if (key === 'class') (classes ||= []).push(value)
else if (key === 'style') (styles ||= []).push(value)
- else setDynamicProp(el, key, value)
+ else {
+ prevValue = setDynamicProp(el, key, prevValue, value)
+ }
},
)
if (classes) setClass(el, classes)
- if (styles) setStyle(el, styles)
+ if (styles) {
+ prevStyle = setStyle(el, prevStyle, styles)
+ }
})
}
return el.$$metadata || (el.$$metadata = [{}, {}])
}
-export function recordPropMetadata(el: Node, key: string, value: any): any {
- const metadata = getMetadata(el)[MetadataKind.prop]
- const prev = metadata[key]
- if (prev !== value) metadata[key] = value
- return prev
-}
-
export function recordEventMetadata(el: Node, key: string, value: any) {
const metadata = getMetadata(el)[MetadataKind.event]
const handlers = (metadata[key] ||= [])
} 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'
}
export function setClass(el: Element, value: any, root?: boolean): void {
- const prev = recordPropMetadata(
- el,
- 'class',
- (value = normalizeClass(root ? mergeInheritAttr('class', value) : value)),
- )
-
- if (value !== prev && (value || prev)) {
- el.className = value
- }
+ el.className = normalizeClass(root ? mergeInheritAttr('class', value) : value)
}
export function setAttr(el: Element, key: string, value: any): void {
- const oldVal = recordPropMetadata(el, key, value)
- if (value !== oldVal) {
- if (value != null) {
- el.setAttribute(key, value)
- } else {
- el.removeAttribute(key)
- }
+ if (value != null) {
+ el.setAttribute(key, value)
+ } else {
+ el.removeAttribute(key)
}
}
export function setValue(el: any, value: any): void {
- const oldVal = recordPropMetadata(el, 'value', value)
- if (value === oldVal) return
-
// store value as _value as well since
// non-string values will be stringified.
el._value = value
}
export function setDOMProp(el: any, key: string, value: any): void {
- const oldVal = recordPropMetadata(el, key, value)
- if (value === oldVal) return
-
let needRemove = false
if (value === '' || value == null) {
const type = typeof el[key]
needRemove && el.removeAttribute(key)
}
-export function setDynamicProp(el: Element, key: string, value: any): void {
+export function setDynamicProp(
+ el: Element,
+ key: string,
+ prev: any,
+ value: any,
+): any {
// TODO
const isSVG = false
if (key === 'class') {
setClass(el, value)
} else if (key === 'style') {
- setStyle(el as HTMLElement, value)
+ return setStyle(el as HTMLElement, prev, value)
} else if (isOn(key)) {
on(el, key[2].toLowerCase() + key.slice(3), () => value, { effect: true })
} else if (
export function setDynamicProps(
el: Element,
+ oldProps: any,
args: any[],
root?: boolean,
): void {
- const oldProps = getMetadata(el)[MetadataKind.prop]
+ // const oldProps = getMetadata(el)[MetadataKind.prop]
if (root) {
args.unshift(currentInstance!.attrs)
}
const props = args.length > 1 ? mergeProps(...args) : args[0]
- for (const key in oldProps) {
- // TODO should these keys be allowed as dynamic keys? The current logic of the runtime-core will throw an error
- if (key === 'textContent' || key === 'innerHTML') {
- continue
- }
+ if (oldProps) {
+ for (const key in oldProps) {
+ // TODO should these keys be allowed as dynamic keys? The current logic of the runtime-core will throw an error
+ if (key === 'textContent' || key === 'innerHTML') {
+ continue
+ }
- const hasNewValue = props[key] || props['.' + key] || props['^' + key]
- if (oldProps[key] && !hasNewValue) {
- setDynamicProp(el, key, null)
+ const oldValue = oldProps[key]
+ const hasNewValue = props[key] || props['.' + key] || props['^' + key]
+ if (oldValue && !hasNewValue) {
+ setDynamicProp(el, key, oldValue, null)
+ }
}
}
+ const prev = Object.create(null)
for (const key in props) {
- setDynamicProp(el, key, props[key])
+ setDynamicProp(
+ el,
+ key,
+ oldProps ? oldProps[key] : undefined,
+ (prev[key] = props[key]),
+ )
}
+
+ return prev
}
export function mergeProp(
}
export function setText(el: Node, ...values: any[]): void {
- const text = values.map(v => toDisplayString(v)).join('')
- const oldVal = recordPropMetadata(el, 'textContent', text)
- if (text !== oldVal) {
- el.textContent = text
- }
+ el.textContent = values.map(v => toDisplayString(v)).join('')
}
export function setHtml(el: Element, value: any): void {
- const oldVal = recordPropMetadata(el, 'innerHTML', value)
- if (value !== oldVal) {
- el.innerHTML = value == null ? '' : value
- }
+ el.innerHTML = value == null ? '' : value
}
// TODO copied from runtime-dom
normalizeStyle,
} from '@vue/shared'
import { warn } from '../warning'
-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