mirror of https://github.com/vuejs/core.git
feat: prop and attr modifiers for v-bind (#79)
This commit is contained in:
parent
199b19f076
commit
775491e46d
|
@ -121,7 +121,7 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compile > directives > v-pre > self-closing v-pre 1`] = `
|
exports[`compile > directives > v-pre > self-closing v-pre 1`] = `
|
||||||
"import { template as _template, children as _children, createTextNode as _createTextNode, append as _append, renderEffect as _renderEffect, setText as _setText, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, createTextNode as _createTextNode, append as _append, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div><div><Comp></Comp></div>")
|
const t0 = _template("<div></div><div><Comp></Comp></div>")
|
||||||
|
@ -133,14 +133,14 @@ export function render(_ctx) {
|
||||||
_setText(n1, undefined, _ctx.bar)
|
_setText(n1, undefined, _ctx.bar)
|
||||||
})
|
})
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n2, "id", undefined, _ctx.foo)
|
_setDynamicProp(n2, "id", undefined, _ctx.foo)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compile > directives > v-pre > should not affect siblings after it 1`] = `
|
exports[`compile > directives > v-pre > should not affect siblings after it 1`] = `
|
||||||
"import { template as _template, children as _children, createTextNode as _createTextNode, append as _append, renderEffect as _renderEffect, setText as _setText, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, createTextNode as _createTextNode, append as _append, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div><div><Comp></Comp></div>")
|
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div><div><Comp></Comp></div>")
|
||||||
|
@ -152,7 +152,7 @@ export function render(_ctx) {
|
||||||
_setText(n1, undefined, _ctx.bar)
|
_setText(n1, undefined, _ctx.bar)
|
||||||
})
|
})
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n2, "id", undefined, _ctx.foo)
|
_setDynamicProp(n2, "id", undefined, _ctx.foo)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
|
@ -179,7 +179,7 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compile > dynamic root nodes and interpolation 1`] = `
|
exports[`compile > dynamic root nodes and interpolation 1`] = `
|
||||||
"import { template as _template, children as _children, createTextNode as _createTextNode, prepend as _prepend, insert as _insert, append as _append, on as _on, renderEffect as _renderEffect, setText as _setText, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, createTextNode as _createTextNode, prepend as _prepend, insert as _insert, append as _append, on as _on, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<button>foo<!>foo</button>")
|
const t0 = _template("<button>foo<!>foo</button>")
|
||||||
|
@ -196,7 +196,7 @@ export function render(_ctx) {
|
||||||
_setText(n1, undefined, _ctx.count)
|
_setText(n1, undefined, _ctx.count)
|
||||||
_setText(n2, undefined, _ctx.count)
|
_setText(n2, undefined, _ctx.count)
|
||||||
_setText(n3, undefined, _ctx.count)
|
_setText(n3, undefined, _ctx.count)
|
||||||
_setAttr(n4, "id", undefined, _ctx.count)
|
_setDynamicProp(n4, "id", undefined, _ctx.count)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
|
@ -222,7 +222,7 @@ exports[`compile > expression parsing > v-bind 1`] = `
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, key.value+1, undefined, _unref(foo)[key.value+1]())
|
_setDynamicProp(n1, key.value+1, undefined, _unref(foo)[key.value+1]())
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
})()"
|
})()"
|
||||||
|
|
|
@ -1,14 +1,42 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`compiler v-bind > .camel modifier 1`] = `
|
exports[`compiler v-bind > .attr modifier 1`] = `
|
||||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, "fooBar", undefined, _ctx.id)
|
_setDynamicProp(n1, "^foo-bar", undefined, _ctx.id)
|
||||||
|
})
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler v-bind > .attr modifier w/ no expression 1`] = `
|
||||||
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
const n0 = t0()
|
||||||
|
const { 0: [n1],} = _children(n0)
|
||||||
|
_renderEffect(() => {
|
||||||
|
_setDynamicProp(n1, "^foo-bar", undefined, _ctx.fooBar)
|
||||||
|
})
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler v-bind > .camel modifier 1`] = `
|
||||||
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
const n0 = t0()
|
||||||
|
const { 0: [n1],} = _children(n0)
|
||||||
|
_renderEffect(() => {
|
||||||
|
_setDynamicProp(n1, "fooBar", undefined, _ctx.id)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
|
@ -22,77 +50,147 @@ export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, _camelize(_ctx.foo), undefined, _ctx.id)
|
_setDynamicProp(n1, _camelize(_ctx.foo), undefined, _ctx.id)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > .camel modifier w/ no expression 1`] = `
|
exports[`compiler v-bind > .camel modifier w/ no expression 1`] = `
|
||||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, "fooBar", undefined, _ctx.fooBar)
|
_setDynamicProp(n1, "fooBar", undefined, _ctx.fooBar)
|
||||||
|
})
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler v-bind > .prop modifier (shortband) w/ no expression 1`] = `
|
||||||
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
const n0 = t0()
|
||||||
|
const { 0: [n1],} = _children(n0)
|
||||||
|
_renderEffect(() => {
|
||||||
|
_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)
|
||||||
|
})
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler v-bind > .prop modifier (shorthand) 1`] = `
|
||||||
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
const n0 = t0()
|
||||||
|
const { 0: [n1],} = _children(n0)
|
||||||
|
_renderEffect(() => {
|
||||||
|
_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)
|
||||||
|
})
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler v-bind > .prop modifier 1`] = `
|
||||||
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
const n0 = t0()
|
||||||
|
const { 0: [n1],} = _children(n0)
|
||||||
|
_renderEffect(() => {
|
||||||
|
_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)
|
||||||
|
})
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler v-bind > .prop modifier w/ dynamic arg 1`] = `
|
||||||
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
const n0 = t0()
|
||||||
|
const { 0: [n1],} = _children(n0)
|
||||||
|
_renderEffect(() => {
|
||||||
|
_setDynamicProp(n1, \`.\${_ctx.fooBar}\`, undefined, _ctx.id)
|
||||||
|
})
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler v-bind > .prop modifier w/ no expression 1`] = `
|
||||||
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
const n0 = t0()
|
||||||
|
const { 0: [n1],} = _children(n0)
|
||||||
|
_renderEffect(() => {
|
||||||
|
_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > basic 1`] = `
|
exports[`compiler v-bind > basic 1`] = `
|
||||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, "id", undefined, _ctx.id)
|
_setDynamicProp(n1, "id", undefined, _ctx.id)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > dynamic arg 1`] = `
|
exports[`compiler v-bind > dynamic arg 1`] = `
|
||||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, _ctx.id, undefined, _ctx.id)
|
_setDynamicProp(n1, _ctx.id, undefined, _ctx.id)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > no expression (shorthand) 1`] = `
|
exports[`compiler v-bind > no expression (shorthand) 1`] = `
|
||||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, "camel-case", undefined, _ctx.camelCase)
|
_setDynamicProp(n1, "camel-case", undefined, _ctx.camelCase)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler v-bind > no expression 1`] = `
|
exports[`compiler v-bind > no expression 1`] = `
|
||||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_renderEffect(() => {
|
_renderEffect(() => {
|
||||||
_setAttr(n1, "id", undefined, _ctx.id)
|
_setDynamicProp(n1, "id", undefined, _ctx.id)
|
||||||
})
|
})
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`compiler: v-once > as root node 1`] = `
|
exports[`compiler: v-once > as root node 1`] = `
|
||||||
"import { template as _template, children as _children, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [n1],} = _children(n0)
|
const { 0: [n1],} = _children(n0)
|
||||||
_setAttr(n1, "id", undefined, _ctx.foo)
|
_setDynamicProp(n1, "id", undefined, _ctx.foo)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: v-once > basic 1`] = `
|
exports[`compiler: v-once > basic 1`] = `
|
||||||
"import { template as _template, children as _children, createTextNode as _createTextNode, setText as _setText, setAttr as _setAttr, prepend as _prepend } from 'vue/vapor';
|
"import { template as _template, children as _children, createTextNode as _createTextNode, setText as _setText, setDynamicProp as _setDynamicProp, prepend as _prepend } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div> <span></span></div>")
|
const t0 = _template("<div> <span></span></div>")
|
||||||
|
@ -21,7 +21,7 @@ export function render(_ctx) {
|
||||||
const { 0: [n3, { 1: [n2],}],} = _children(n0)
|
const { 0: [n3, { 1: [n2],}],} = _children(n0)
|
||||||
const n1 = _createTextNode(_ctx.msg)
|
const n1 = _createTextNode(_ctx.msg)
|
||||||
_setText(n1, undefined, _ctx.msg)
|
_setText(n1, undefined, _ctx.msg)
|
||||||
_setAttr(n2, "class", undefined, _ctx.clz)
|
_setDynamicProp(n2, "class", undefined, _ctx.clz)
|
||||||
_prepend(n3, n1)
|
_prepend(n3, n1)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
|
@ -38,13 +38,13 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: v-once > on nested plain element 1`] = `
|
exports[`compiler: v-once > on nested plain element 1`] = `
|
||||||
"import { template as _template, children as _children, setAttr as _setAttr } from 'vue/vapor';
|
"import { template as _template, children as _children, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const t0 = _template("<div><div></div></div>")
|
const t0 = _template("<div><div></div></div>")
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const { 0: [, { 0: [n1],}],} = _children(n0)
|
const { 0: [, { 0: [n1],}],} = _children(n0)
|
||||||
_setAttr(n1, "id", undefined, _ctx.foo)
|
_setDynamicProp(n1, "id", undefined, _ctx.foo)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -83,7 +83,7 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
|
expect(code).contains('_setDynamicProp(n1, "id", undefined, _ctx.id)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('no expression', () => {
|
test('no expression', () => {
|
||||||
|
@ -110,7 +110,7 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
|
expect(code).contains('_setDynamicProp(n1, "id", undefined, _ctx.id)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('no expression (shorthand)', () => {
|
test('no expression (shorthand)', () => {
|
||||||
|
@ -130,7 +130,7 @@ describe('compiler v-bind', () => {
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_setAttr(n1, "camel-case", undefined, _ctx.camelCase)',
|
'_setDynamicProp(n1, "camel-case", undefined, _ctx.camelCase)',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)')
|
expect(code).contains('_setDynamicProp(n1, _ctx.id, undefined, _ctx.id)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should error if empty expression', () => {
|
test('should error if empty expression', () => {
|
||||||
|
@ -192,7 +192,7 @@ describe('compiler v-bind', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('_setAttr(n1, "fooBar", undefined, _ctx.id)')
|
expect(code).contains('_setDynamicProp(n1, "fooBar", undefined, _ctx.id)')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.camel modifier w/ no expression', () => {
|
test('.camel modifier w/ no expression', () => {
|
||||||
|
@ -211,7 +211,9 @@ describe('compiler v-bind', () => {
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains('_setAttr(n1, "fooBar", undefined, _ctx.fooBar)')
|
expect(code).contains(
|
||||||
|
'_setDynamicProp(n1, "fooBar", undefined, _ctx.fooBar)',
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('.camel modifier w/ dynamic arg', () => {
|
test('.camel modifier w/ dynamic arg', () => {
|
||||||
|
@ -232,18 +234,152 @@ describe('compiler v-bind', () => {
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains('renderEffect')
|
expect(code).contains('renderEffect')
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
`_setAttr(n1, _camelize(_ctx.foo), undefined, _ctx.id)`,
|
`_setDynamicProp(n1, _camelize(_ctx.foo), undefined, _ctx.id)`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test.todo('.camel modifier w/ dynamic arg + prefixIdentifiers')
|
test.todo('.camel modifier w/ dynamic arg + prefixIdentifiers')
|
||||||
|
|
||||||
test.todo('.prop modifier')
|
test('.prop modifier', () => {
|
||||||
test.todo('.prop modifier w/ no expression')
|
const { ir, code } = compileWithVBind(`<div v-bind:fooBar.prop="id"/>`)
|
||||||
test.todo('.prop modifier w/ dynamic arg')
|
|
||||||
test.todo('.prop modifier w/ dynamic arg + prefixIdentifiers')
|
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||||
test.todo('.prop modifier (shorthand)')
|
key: {
|
||||||
test.todo('.prop modifier (shortband) w/ no expression')
|
content: `.fooBar`,
|
||||||
test.todo('.attr modifier')
|
isStatic: true,
|
||||||
test.todo('.attr modifier w/ no expression')
|
},
|
||||||
|
value: {
|
||||||
|
content: `id`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('renderEffect')
|
||||||
|
expect(code).contains('_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('.prop modifier w/ no expression', () => {
|
||||||
|
const { ir, code } = compileWithVBind(`<div v-bind:fooBar.prop />`)
|
||||||
|
|
||||||
|
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: `.fooBar`,
|
||||||
|
isStatic: true,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `fooBar`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('renderEffect')
|
||||||
|
expect(code).contains(
|
||||||
|
'_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('.prop modifier w/ dynamic arg', () => {
|
||||||
|
const { ir, code } = compileWithVBind(`<div v-bind:[fooBar].prop="id"/>`)
|
||||||
|
|
||||||
|
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: `fooBar`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `id`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('renderEffect')
|
||||||
|
expect(code).contains(
|
||||||
|
'_setDynamicProp(n1, `.${_ctx.fooBar}`, undefined, _ctx.id)',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.todo('.prop modifier w/ dynamic arg + prefixIdentifiers')
|
||||||
|
|
||||||
|
test('.prop modifier (shorthand)', () => {
|
||||||
|
const { ir, code } = compileWithVBind(`<div .fooBar="id"/>`)
|
||||||
|
|
||||||
|
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: `.fooBar`,
|
||||||
|
isStatic: true,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `id`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('renderEffect')
|
||||||
|
expect(code).contains('_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('.prop modifier (shortband) w/ no expression', () => {
|
||||||
|
const { ir, code } = compileWithVBind(`<div .fooBar />`)
|
||||||
|
|
||||||
|
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: `.fooBar`,
|
||||||
|
isStatic: true,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `fooBar`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('renderEffect')
|
||||||
|
expect(code).contains(
|
||||||
|
'_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('.attr modifier', () => {
|
||||||
|
const { ir, code } = compileWithVBind(`<div v-bind:foo-bar.attr="id"/>`)
|
||||||
|
|
||||||
|
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: `^foo-bar`,
|
||||||
|
isStatic: true,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `id`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('renderEffect')
|
||||||
|
expect(code).contains('_setDynamicProp(n1, "^foo-bar", undefined, _ctx.id)')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('.attr modifier w/ no expression', () => {
|
||||||
|
const { ir, code } = compileWithVBind(`<div v-bind:foo-bar.attr />`)
|
||||||
|
|
||||||
|
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||||
|
key: {
|
||||||
|
content: `^foo-bar`,
|
||||||
|
isStatic: true,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
content: `fooBar`,
|
||||||
|
isStatic: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('renderEffect')
|
||||||
|
expect(code).contains(
|
||||||
|
'_setDynamicProp(n1, "^foo-bar", undefined, _ctx.fooBar)',
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -403,16 +403,20 @@ function genOperation(oper: OperationNode, context: CodegenContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function genSetProp(oper: SetPropIRNode, context: CodegenContext) {
|
function genSetProp(oper: SetPropIRNode, context: CodegenContext) {
|
||||||
const { pushFnCall, newline, vaporHelper, helper } = context
|
const { pushFnCall, pushMulti, newline, vaporHelper, helper } = context
|
||||||
|
|
||||||
newline()
|
newline()
|
||||||
pushFnCall(
|
pushFnCall(
|
||||||
vaporHelper('setAttr'),
|
vaporHelper('setDynamicProp'),
|
||||||
`n${oper.element}`,
|
`n${oper.element}`,
|
||||||
// 2. key name
|
// 2. key name
|
||||||
() => {
|
() => {
|
||||||
if (oper.runtimeCamelize) {
|
if (oper.runtimeCamelize) {
|
||||||
pushFnCall(helper('camelize'), () => genExpression(oper.key, context))
|
pushFnCall(helper('camelize'), () => genExpression(oper.key, context))
|
||||||
|
} else if (oper.runtimePrefix) {
|
||||||
|
pushMulti([`\`${oper.runtimePrefix}\${`, `}\``], () =>
|
||||||
|
genExpression(oper.key, context),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
genExpression(oper.key, context)
|
genExpression(oper.key, context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ export interface SetPropIRNode extends BaseIRNode {
|
||||||
key: IRExpression
|
key: IRExpression
|
||||||
value: IRExpression
|
value: IRExpression
|
||||||
runtimeCamelize: boolean
|
runtimeCamelize: boolean
|
||||||
|
runtimePrefix?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetTextIRNode extends BaseIRNode {
|
export interface SetTextIRNode extends BaseIRNode {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
ErrorCodes,
|
ErrorCodes,
|
||||||
|
type SimpleExpressionNode,
|
||||||
createCompilerError,
|
createCompilerError,
|
||||||
createSimpleExpression,
|
createSimpleExpression,
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
|
@ -30,6 +31,14 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let prefix: string | undefined
|
||||||
|
if (modifiers.includes('prop')) {
|
||||||
|
prefix = injectPrefix(arg, '.')
|
||||||
|
}
|
||||||
|
if (modifiers.includes('attr')) {
|
||||||
|
prefix = injectPrefix(arg, '^')
|
||||||
|
}
|
||||||
|
|
||||||
if (!exp.content.trim()) {
|
if (!exp.content.trim()) {
|
||||||
context.options.onError(
|
context.options.onError(
|
||||||
createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
|
createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
|
||||||
|
@ -48,7 +57,15 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => {
|
||||||
key: arg,
|
key: arg,
|
||||||
value: exp,
|
value: exp,
|
||||||
runtimeCamelize: camel,
|
runtimeCamelize: camel,
|
||||||
|
runtimePrefix: prefix,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const injectPrefix = (arg: SimpleExpressionNode, prefix: string) => {
|
||||||
|
if (!arg.isStatic) {
|
||||||
|
return prefix
|
||||||
|
}
|
||||||
|
arg.content = prefix + arg.content
|
||||||
|
}
|
||||||
|
|
|
@ -88,16 +88,34 @@ export function setAttr(el: Element, key: string, oldVal: any, newVal: any) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setDynamicProp(el: Element, key: string, val: any) {
|
export function setDOMProp(el: any, key: string, oldVal: any, newVal: any) {
|
||||||
|
// TODO special checks
|
||||||
|
if (newVal !== oldVal) {
|
||||||
|
el[key] = newVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setDynamicProp(
|
||||||
|
el: Element,
|
||||||
|
key: string,
|
||||||
|
oldVal: any,
|
||||||
|
newVal: any,
|
||||||
|
) {
|
||||||
if (key === 'class') {
|
if (key === 'class') {
|
||||||
setClass(el, void 0, val)
|
setClass(el, oldVal, newVal)
|
||||||
} else if (key === 'style') {
|
} else if (key === 'style') {
|
||||||
setStyle(el as HTMLElement, void 0, val)
|
setStyle(el as HTMLElement, oldVal, newVal)
|
||||||
} else if (key in el) {
|
} else if (
|
||||||
;(el as any)[key] = val
|
key[0] === '.'
|
||||||
|
? ((key = key.slice(1)), true)
|
||||||
|
: key[0] === '^'
|
||||||
|
? ((key = key.slice(1)), false)
|
||||||
|
: key in el
|
||||||
|
) {
|
||||||
|
setDOMProp(el, key, oldVal, newVal)
|
||||||
} else {
|
} else {
|
||||||
// TODO special checks
|
// TODO special checks
|
||||||
setAttr(el, key, void 0, val)
|
setAttr(el, key, oldVal, newVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue