mirror of https://github.com/vuejs/core.git
perf(runtime-vapor): optimize `setDOMProp` on static tag + key (#294)
This commit is contained in:
parent
842f94cc73
commit
0196e1a499
|
@ -186,7 +186,7 @@ export function render(_ctx) {
|
|||
_delegate(n0, "click", () => _ctx.handleClick)
|
||||
_setInheritAttrs(["id"])
|
||||
_renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.count, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.count))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -7,7 +7,19 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["foo-bar"])
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id, true))
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["innerHTML"])
|
||||
_renderEffect(() => _setAttr(n0, "innerHTML", _ctx.foo))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -19,7 +31,43 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["foo-bar"])
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar, true))
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _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';
|
||||
const t0 = _template("<progress></progress>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setAttr(n0, "value", _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["textContent"])
|
||||
_renderEffect(() => _setAttr(n0, "textContent", _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setAttr(n0, "value", _ctx.foo))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -31,7 +79,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id, true))
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -56,19 +104,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .prop modifier (shortband) w/ no expression 1`] = `
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, 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, true))
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -80,7 +116,67 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["innerHTML"])
|
||||
_renderEffect(() => _setHtml(n0, _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "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';
|
||||
const t0 = _template("<progress></progress>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setDOMProp(n0, "value", _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["textContent"])
|
||||
_renderEffect(() => _setText(n0, _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setValue(n0, _ctx.foo))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -92,7 +188,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -109,6 +205,18 @@ export function render(_ctx) {
|
|||
}"
|
||||
`;
|
||||
|
||||
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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["innerHTML"])
|
||||
_renderEffect(() => _setHtml(n0, _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
@ -116,7 +224,91 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "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';
|
||||
const t0 = _template("<progress></progress>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setDOMProp(n0, "value", _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["textContent"])
|
||||
_renderEffect(() => _setText(n0, _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setValue(n0, _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["innerHTML"])
|
||||
_renderEffect(() => _setHtml(n0, _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';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["textContent"])
|
||||
_renderEffect(() => _setText(n0, _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';
|
||||
const t0 = _template("<input>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setValue(n0, _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';
|
||||
const t0 = _template("<progress></progress>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["value"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "value", _ctx.foo))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -128,11 +320,11 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["id", "title", "lang", "dir", "tabindex"])
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.id, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "title", _ctx.title, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "dir", _ctx.dir, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex, true))
|
||||
_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))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -144,11 +336,11 @@ const t0 = _template("<math></math>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["autofucus", "dir", "displaystyle", "mathcolor", "tabindex"])
|
||||
_renderEffect(() => _setDOMProp(n0, "autofucus", _ctx.autofucus, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "dir", _ctx.dir, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "displaystyle", _ctx.displaystyle, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "mathcolor", _ctx.mathcolor, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex, true))
|
||||
_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))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -160,9 +352,9 @@ const t0 = _template("<svg></svg>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["id", "lang", "tabindex"])
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.id, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.id))
|
||||
_renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang))
|
||||
_renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -214,7 +406,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["id"])
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.id, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.id))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -250,7 +442,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["camel-case"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase, true))
|
||||
_renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -262,7 +454,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(["id"])
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.id, true))
|
||||
_renderEffect(() => _setDOMProp(n0, "id", _ctx.id))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -52,8 +52,8 @@ export function render(_ctx) {
|
|||
const n0 = _createFor(() => (_ctx.items), (_ctx0) => {
|
||||
const n2 = t0()
|
||||
_setInheritAttrs(["item", "index"])
|
||||
_renderEffect(() => _setDynamicProp(n2, "item", _ctx0[0].value, true))
|
||||
_renderEffect(() => _setDynamicProp(n2, "index", _ctx0[1].value, true))
|
||||
_renderEffect(() => _setDynamicProp(n2, "item", _ctx0[0].value))
|
||||
_renderEffect(() => _setDynamicProp(n2, "index", _ctx0[1].value))
|
||||
return n2
|
||||
})
|
||||
return n0
|
||||
|
|
|
@ -6,7 +6,7 @@ const t0 = _template("<div></div>")
|
|||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setDOMProp(n0, "id", _ctx.foo, true)
|
||||
_setDOMProp(n0, "id", _ctx.foo)
|
||||
_setInheritAttrs(["id"])
|
||||
return n0
|
||||
}"
|
||||
|
|
|
@ -74,7 +74,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDOMProp(n0, "id", _ctx.id, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "id", _ctx.id)')
|
||||
})
|
||||
|
||||
test('no expression', () => {
|
||||
|
@ -104,7 +104,7 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
},
|
||||
})
|
||||
expect(code).contains('_setDOMProp(n0, "id", _ctx.id, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "id", _ctx.id)')
|
||||
})
|
||||
|
||||
test('no expression (shorthand)', () => {
|
||||
|
@ -126,9 +126,7 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
},
|
||||
})
|
||||
expect(code).contains(
|
||||
'_setDynamicProp(n0, "camel-case", _ctx.camelCase, true)',
|
||||
)
|
||||
expect(code).contains('_setDynamicProp(n0, "camel-case", _ctx.camelCase)')
|
||||
})
|
||||
|
||||
test('dynamic arg', () => {
|
||||
|
@ -288,7 +286,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id, true)')
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id)')
|
||||
})
|
||||
|
||||
test('.camel modifier w/ no expression', () => {
|
||||
|
@ -312,7 +310,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar)')
|
||||
})
|
||||
|
||||
test('.camel modifier w/ dynamic arg', () => {
|
||||
|
@ -370,7 +368,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
|
||||
})
|
||||
|
||||
test('.prop modifier w/ no expression', () => {
|
||||
|
@ -394,7 +392,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)')
|
||||
})
|
||||
|
||||
test('.prop modifier w/ dynamic arg', () => {
|
||||
|
@ -451,10 +449,10 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
|
||||
})
|
||||
|
||||
test('.prop modifier (shortband) w/ no expression', () => {
|
||||
test('.prop modifier (shorthand) w/ no expression', () => {
|
||||
const { ir, code } = compileWithVBind(`<div .fooBar />`)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -475,7 +473,55 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "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)')
|
||||
})
|
||||
|
||||
test('.prop modifier (shorthand) w/ innerHTML', () => {
|
||||
const { code } = compileWithVBind(`<div .innerHTML="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setHtml(n0, _ctx.foo)')
|
||||
})
|
||||
|
||||
test('.prop modifier w/ textContent', () => {
|
||||
const { code } = compileWithVBind(`<div :textContent.prop="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setText(n0, _ctx.foo)')
|
||||
})
|
||||
|
||||
test('.prop modifier (shorthand) w/ textContent', () => {
|
||||
const { code } = compileWithVBind(`<div .textContent="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setText(n0, _ctx.foo)')
|
||||
})
|
||||
|
||||
test('.prop modifier w/ value', () => {
|
||||
const { code } = compileWithVBind(`<div :value.prop="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setValue(n0, _ctx.foo)')
|
||||
})
|
||||
|
||||
test('.prop modifier (shorthand) w/ value', () => {
|
||||
const { code } = compileWithVBind(`<div .value="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setValue(n0, _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)')
|
||||
})
|
||||
|
||||
test('.prop modifier (shorthand) w/ progress value', () => {
|
||||
const { code } = compileWithVBind(`<progress .value="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDOMProp(n0, "value", _ctx.foo)')
|
||||
})
|
||||
|
||||
test('.attr modifier', () => {
|
||||
|
@ -499,7 +545,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id, true)')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id)')
|
||||
})
|
||||
|
||||
test('.attr modifier w/ no expression', () => {
|
||||
|
@ -524,7 +570,31 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.fooBar, true)')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _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)')
|
||||
})
|
||||
|
||||
test('.attr modifier w/ textContent', () => {
|
||||
const { code } = compileWithVBind(`<div :textContent.attr="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setAttr(n0, "textContent", _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)')
|
||||
})
|
||||
|
||||
test('.attr modifier w/ progress value', () => {
|
||||
const { code } = compileWithVBind(`<progress :value.attr="foo" />`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setAttr(n0, "value", _ctx.foo)')
|
||||
})
|
||||
|
||||
test('attributes must be set as attribute', () => {
|
||||
|
@ -561,11 +631,11 @@ describe('compiler v-bind', () => {
|
|||
`)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDOMProp(n0, "id", _ctx.id, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "title", _ctx.title, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex, true)')
|
||||
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)')
|
||||
})
|
||||
|
||||
test('SVG global attributes should set as dom prop', () => {
|
||||
|
@ -574,9 +644,9 @@ describe('compiler v-bind', () => {
|
|||
`)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDOMProp(n0, "id", _ctx.id, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "id", _ctx.id)')
|
||||
expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang)')
|
||||
expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)')
|
||||
})
|
||||
|
||||
test('MathML global attributes should set as dom prop', () => {
|
||||
|
@ -585,13 +655,43 @@ describe('compiler v-bind', () => {
|
|||
`)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDOMProp(n0, "autofucus", _ctx.autofucus, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir, true)')
|
||||
expect(code).contains(
|
||||
'_setDOMProp(n0, "displaystyle", _ctx.displaystyle, true)',
|
||||
)
|
||||
expect(code).contains('_setDOMProp(n0, "mathcolor", _ctx.mathcolor, true)')
|
||||
expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex, true)')
|
||||
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)')
|
||||
})
|
||||
|
||||
test(':innerHTML', () => {
|
||||
const { code } = compileWithVBind(`
|
||||
<div :innerHTML="foo"/>
|
||||
`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setHtml(n0, _ctx.foo)')
|
||||
})
|
||||
|
||||
test(':textContext', () => {
|
||||
const { code } = compileWithVBind(`
|
||||
<div :textContent="foo"/>
|
||||
`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setText(n0, _ctx.foo)')
|
||||
})
|
||||
|
||||
test(':value', () => {
|
||||
const { code } = compileWithVBind(`
|
||||
<input :value="foo"/>
|
||||
`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setValue(n0, _ctx.foo)')
|
||||
})
|
||||
|
||||
test(':value w/ progress', () => {
|
||||
const { code } = compileWithVBind(`
|
||||
<progress :value="foo"/>
|
||||
`)
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDynamicProp(n0, "value", _ctx.foo)')
|
||||
})
|
||||
|
||||
test('number value', () => {
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
} from './utils'
|
||||
import {
|
||||
attributeCache,
|
||||
canSetValueDirectly,
|
||||
isHTMLGlobalAttr,
|
||||
isHTMLTag,
|
||||
isMathMLGlobalAttr,
|
||||
|
@ -44,39 +45,7 @@ export function genSetProp(
|
|||
tag,
|
||||
} = oper
|
||||
|
||||
const keyName = key.content
|
||||
const tagName = tag.toUpperCase()
|
||||
const attrCacheKey = `${tagName}_${keyName}`
|
||||
|
||||
let helperName: VaporHelper
|
||||
let omitKey = false
|
||||
if (keyName === 'class') {
|
||||
helperName = 'setClass'
|
||||
omitKey = true
|
||||
} else if (keyName === 'style') {
|
||||
helperName = 'setStyle'
|
||||
omitKey = true
|
||||
} else if (modifier) {
|
||||
helperName = modifier === '.' ? 'setDOMProp' : 'setAttr'
|
||||
} else if (
|
||||
attributeCache[attrCacheKey] === undefined
|
||||
? (attributeCache[attrCacheKey] = shouldSetAsAttr(
|
||||
tag.toUpperCase(),
|
||||
keyName,
|
||||
))
|
||||
: attributeCache[attrCacheKey]
|
||||
) {
|
||||
helperName = 'setAttr'
|
||||
} else if (
|
||||
(isHTMLTag(tag) && isHTMLGlobalAttr(keyName)) ||
|
||||
(isSVGTag(tag) && isSvgGlobalAttr(keyName)) ||
|
||||
(isMathMLTag(tag) && isMathMLGlobalAttr(keyName))
|
||||
) {
|
||||
helperName = 'setDOMProp'
|
||||
} else {
|
||||
helperName = 'setDynamicProp'
|
||||
}
|
||||
|
||||
const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier)
|
||||
return [
|
||||
NEWLINE,
|
||||
...genCall(
|
||||
|
@ -84,7 +53,10 @@ export function genSetProp(
|
|||
`n${oper.element}`,
|
||||
omitKey ? false : genExpression(key, context),
|
||||
genPropValue(values, context),
|
||||
oper.root && 'true',
|
||||
// only `setClass` and `setStyle` need merge inherit attr
|
||||
oper.root && (helperName === 'setClass' || helperName === 'setStyle')
|
||||
? 'true'
|
||||
: undefined,
|
||||
),
|
||||
]
|
||||
}
|
||||
|
@ -196,3 +168,70 @@ export function genSetInheritAttrs(
|
|||
if (value == null) return []
|
||||
return [NEWLINE, ...genCall(vaporHelper('setInheritAttrs'), value)]
|
||||
}
|
||||
|
||||
function getRuntimeHelper(
|
||||
tag: string,
|
||||
keyName: string,
|
||||
modifier: '.' | '^' | undefined,
|
||||
) {
|
||||
const tagName = tag.toUpperCase()
|
||||
let helperName: VaporHelper
|
||||
let omitKey = false
|
||||
|
||||
if (modifier) {
|
||||
if (modifier === '.') {
|
||||
const helper = getSpecialHelper(keyName, tagName)
|
||||
if (helper) {
|
||||
helperName = helper.name
|
||||
omitKey = helper.omitKey
|
||||
} else {
|
||||
helperName = 'setDOMProp'
|
||||
omitKey = false
|
||||
}
|
||||
} else {
|
||||
helperName = 'setAttr'
|
||||
}
|
||||
} else {
|
||||
const attrCacheKey = `${tagName}_${keyName}`
|
||||
const helper = getSpecialHelper(keyName, tagName)
|
||||
if (helper) {
|
||||
helperName = helper.name
|
||||
omitKey = helper.omitKey
|
||||
} else if (
|
||||
attributeCache[attrCacheKey] === undefined
|
||||
? (attributeCache[attrCacheKey] = shouldSetAsAttr(tagName, keyName))
|
||||
: attributeCache[attrCacheKey]
|
||||
) {
|
||||
helperName = 'setAttr'
|
||||
} else if (
|
||||
(isHTMLTag(tag) && isHTMLGlobalAttr(keyName)) ||
|
||||
(isSVGTag(tag) && isSvgGlobalAttr(keyName)) ||
|
||||
(isMathMLTag(tag) && isMathMLGlobalAttr(keyName))
|
||||
) {
|
||||
helperName = 'setDOMProp'
|
||||
} else {
|
||||
helperName = 'setDynamicProp'
|
||||
}
|
||||
}
|
||||
return { helperName, omitKey }
|
||||
}
|
||||
|
||||
const specialHelpers: Record<string, { name: VaporHelper; omitKey: boolean }> =
|
||||
{
|
||||
class: { name: 'setClass', omitKey: true },
|
||||
style: { name: 'setStyle', omitKey: true },
|
||||
innerHTML: { name: 'setHtml', omitKey: true },
|
||||
textContent: { name: 'setText', omitKey: true },
|
||||
}
|
||||
|
||||
const getSpecialHelper = (
|
||||
keyName: string,
|
||||
tagName: string,
|
||||
): { name: VaporHelper; omitKey: boolean } | null => {
|
||||
// special case for 'value' property
|
||||
if (keyName === 'value' && canSetValueDirectly(tagName)) {
|
||||
return { name: 'setValue', omitKey: true }
|
||||
}
|
||||
|
||||
return specialHelpers[keyName] || null
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
setDynamicProps,
|
||||
setHtml,
|
||||
setText,
|
||||
setValue,
|
||||
} from '../../src/dom/prop'
|
||||
import { setStyle } from '../../src/dom/style'
|
||||
import {
|
||||
|
@ -239,43 +240,32 @@ describe('patchProp', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('setDOMProp', () => {
|
||||
test('should set DOM property', () => {
|
||||
const el = document.createElement('div')
|
||||
setDOMProp(el, 'textContent', null)
|
||||
expect(el.textContent).toBe('')
|
||||
setDOMProp(el, 'textContent', 'foo')
|
||||
expect(el.textContent).toBe('foo')
|
||||
|
||||
setDOMProp(el, 'innerHTML', null)
|
||||
expect(el.innerHTML).toBe('')
|
||||
setDOMProp(el, 'innerHTML', '<p>bar</p>')
|
||||
expect(el.innerHTML).toBe('<p>bar</p>')
|
||||
})
|
||||
|
||||
describe('setValue', () => {
|
||||
test('should set value prop', () => {
|
||||
const el = document.createElement('input')
|
||||
setDOMProp(el, 'value', 'foo')
|
||||
setValue(el, 'foo')
|
||||
expect(el.value).toBe('foo')
|
||||
setDOMProp(el, 'value', null)
|
||||
setValue(el, null)
|
||||
expect(el.value).toBe('')
|
||||
expect(el.getAttribute('value')).toBe(null)
|
||||
const obj = {}
|
||||
setDOMProp(el, 'value', obj)
|
||||
setValue(el, obj)
|
||||
expect(el.value).toBe(obj.toString())
|
||||
expect((el as any)._value).toBe(obj)
|
||||
|
||||
const option = document.createElement('option')
|
||||
setDOMProp(option, 'textContent', 'foo')
|
||||
setText(option, 'foo')
|
||||
expect(option.value).toBe('foo')
|
||||
expect(option.getAttribute('value')).toBe(null)
|
||||
|
||||
setDOMProp(option, 'value', 'bar')
|
||||
setValue(option, 'bar')
|
||||
expect(option.textContent).toBe('foo')
|
||||
expect(option.value).toBe('bar')
|
||||
expect(option.getAttribute('value')).toBe('bar')
|
||||
})
|
||||
})
|
||||
|
||||
describe('setDOMProp', () => {
|
||||
test('should be boolean prop', () => {
|
||||
const el = document.createElement('select')
|
||||
setDOMProp(el, 'multiple', '')
|
||||
|
@ -455,6 +445,8 @@ describe('patchProp', () => {
|
|||
describe('setText', () => {
|
||||
test('should set textContent', () => {
|
||||
const el = document.createElement('div')
|
||||
setText(el, null)
|
||||
expect(el.textContent).toBe('')
|
||||
setText(el, 'foo')
|
||||
expect(el.textContent).toBe('foo')
|
||||
setText(el, 'bar')
|
||||
|
@ -465,6 +457,8 @@ describe('patchProp', () => {
|
|||
describe('setHtml', () => {
|
||||
test('should set innerHTML', () => {
|
||||
const el = document.createElement('div')
|
||||
setHtml(el, null)
|
||||
expect(el.innerHTML).toBe('')
|
||||
setHtml(el, '<p>foo</p>')
|
||||
expect(el.innerHTML).toBe('<p>foo</p>')
|
||||
setHtml(el, '<p>bar</p>')
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
attributeCache,
|
||||
canSetValueDirectly,
|
||||
includeBooleanAttr,
|
||||
isArray,
|
||||
isFunction,
|
||||
|
@ -50,43 +51,29 @@ export function setAttr(el: Element, key: string, value: any): void {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
// #4956: <option> value will fallback to its text content so we need to
|
||||
// compare against its attribute value instead.
|
||||
const oldValue = el.tagName === 'OPTION' ? el.getAttribute('value') : el.value
|
||||
const newValue = value == null ? '' : value
|
||||
if (oldValue !== newValue) {
|
||||
el.value = newValue
|
||||
}
|
||||
if (value == null) {
|
||||
el.removeAttribute('value')
|
||||
}
|
||||
}
|
||||
|
||||
export function setDOMProp(el: any, key: string, value: any): void {
|
||||
const oldVal = recordPropMetadata(el, key, value)
|
||||
if (value === oldVal) return
|
||||
|
||||
if (key === 'innerHTML' || key === 'textContent') {
|
||||
// TODO special checks
|
||||
// if (prevChildren) {
|
||||
// unmountChildren(prevChildren, parentComponent, parentSuspense)
|
||||
// }
|
||||
el[key] = value == null ? '' : value
|
||||
return
|
||||
}
|
||||
|
||||
const tag = el.tagName
|
||||
|
||||
if (
|
||||
key === 'value' &&
|
||||
tag !== 'PROGRESS' &&
|
||||
// custom elements may use _value internally
|
||||
!tag.includes('-')
|
||||
) {
|
||||
// store value as _value as well since
|
||||
// non-string values will be stringified.
|
||||
el._value = value
|
||||
// #4956: <option> value will fallback to its text content so we need to
|
||||
// compare against its attribute value instead.
|
||||
const oldValue = tag === 'OPTION' ? el.getAttribute('value') : el.value
|
||||
const newValue = value == null ? '' : value
|
||||
if (oldValue !== newValue) {
|
||||
el.value = newValue
|
||||
}
|
||||
if (value == null) {
|
||||
el.removeAttribute(key)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let needRemove = false
|
||||
if (value === '' || value == null) {
|
||||
const type = typeof el[key]
|
||||
|
@ -113,7 +100,7 @@ export function setDOMProp(el: any, key: string, value: any): void {
|
|||
// do not warn if value is auto-coerced from nullish values
|
||||
if (__DEV__ && !needRemove) {
|
||||
warn(
|
||||
`Failed setting prop "${key}" on <${tag.toLowerCase()}>: ` +
|
||||
`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
|
||||
`value ${value} is invalid.`,
|
||||
e,
|
||||
)
|
||||
|
@ -138,6 +125,22 @@ export function setDynamicProp(el: Element, key: string, value: any): void {
|
|||
? ((key = key.slice(1)), false)
|
||||
: shouldSetAsProp(el, key, value, isSVG)
|
||||
) {
|
||||
if (key === 'innerHTML') {
|
||||
setHtml(el, value)
|
||||
return
|
||||
}
|
||||
|
||||
if (key === 'textContent') {
|
||||
setText(el, value)
|
||||
return
|
||||
}
|
||||
|
||||
const tag = el.tagName
|
||||
if (key === 'value' && canSetValueDirectly(tag)) {
|
||||
setValue(el, value)
|
||||
return
|
||||
}
|
||||
|
||||
setDOMProp(el, key, value)
|
||||
} else {
|
||||
// TODO special case for <input v-model type="checkbox">
|
||||
|
@ -220,7 +223,7 @@ export function setText(el: Node, ...values: any[]): void {
|
|||
export function setHtml(el: Element, value: any): void {
|
||||
const oldVal = recordPropMetadata(el, 'innerHTML', value)
|
||||
if (value !== oldVal) {
|
||||
el.innerHTML = value
|
||||
el.innerHTML = value == null ? '' : value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,7 @@ export {
|
|||
setHtml,
|
||||
setClass,
|
||||
setAttr,
|
||||
setValue,
|
||||
setDOMProp,
|
||||
setDynamicProp,
|
||||
setDynamicProps,
|
||||
|
|
|
@ -227,3 +227,11 @@ export function genCacheKey(source: string, options: any): string {
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
export function canSetValueDirectly(tagName: string): boolean {
|
||||
return (
|
||||
tagName !== 'PROGRESS' &&
|
||||
// custom elements may use _value internally
|
||||
!tagName.includes('-')
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue