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`] = `
|
||||
"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) {
|
||||
const t0 = _template("<div></div><div><Comp></Comp></div>")
|
||||
|
@ -133,14 +133,14 @@ export function render(_ctx) {
|
|||
_setText(n1, undefined, _ctx.bar)
|
||||
})
|
||||
_renderEffect(() => {
|
||||
_setAttr(n2, "id", undefined, _ctx.foo)
|
||||
_setDynamicProp(n2, "id", undefined, _ctx.foo)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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) {
|
||||
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)
|
||||
})
|
||||
_renderEffect(() => {
|
||||
_setAttr(n2, "id", undefined, _ctx.foo)
|
||||
_setDynamicProp(n2, "id", undefined, _ctx.foo)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
|
@ -179,7 +179,7 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<button>foo<!>foo</button>")
|
||||
|
@ -196,7 +196,7 @@ export function render(_ctx) {
|
|||
_setText(n1, undefined, _ctx.count)
|
||||
_setText(n2, undefined, _ctx.count)
|
||||
_setText(n3, undefined, _ctx.count)
|
||||
_setAttr(n4, "id", undefined, _ctx.count)
|
||||
_setDynamicProp(n4, "id", undefined, _ctx.count)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
|
@ -222,7 +222,7 @@ exports[`compile > expression parsing > v-bind 1`] = `
|
|||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_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
|
||||
})()"
|
||||
|
|
|
@ -1,14 +1,42 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`compiler v-bind > .camel modifier 1`] = `
|
||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
|
||||
exports[`compiler v-bind > .attr 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(() => {
|
||||
_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
|
||||
}"
|
||||
|
@ -22,77 +50,147 @@ export function render(_ctx) {
|
|||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_renderEffect(() => {
|
||||
_setAttr(n1, _camelize(_ctx.foo), undefined, _ctx.id)
|
||||
_setDynamicProp(n1, _camelize(_ctx.foo), undefined, _ctx.id)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_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
|
||||
}"
|
||||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_renderEffect(() => {
|
||||
_setAttr(n1, "id", undefined, _ctx.id)
|
||||
_setDynamicProp(n1, "id", undefined, _ctx.id)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_renderEffect(() => {
|
||||
_setAttr(n1, _ctx.id, undefined, _ctx.id)
|
||||
_setDynamicProp(n1, _ctx.id, undefined, _ctx.id)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_renderEffect(() => {
|
||||
_setAttr(n1, "camel-case", undefined, _ctx.camelCase)
|
||||
_setDynamicProp(n1, "camel-case", undefined, _ctx.camelCase)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_renderEffect(() => {
|
||||
_setAttr(n1, "id", undefined, _ctx.id)
|
||||
_setDynamicProp(n1, "id", undefined, _ctx.id)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_setAttr(n1, "id", undefined, _ctx.foo)
|
||||
_setDynamicProp(n1, "id", undefined, _ctx.foo)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div> <span></span></div>")
|
||||
|
@ -21,7 +21,7 @@ export function render(_ctx) {
|
|||
const { 0: [n3, { 1: [n2],}],} = _children(n0)
|
||||
const n1 = _createTextNode(_ctx.msg)
|
||||
_setText(n1, undefined, _ctx.msg)
|
||||
_setAttr(n2, "class", undefined, _ctx.clz)
|
||||
_setDynamicProp(n2, "class", undefined, _ctx.clz)
|
||||
_prepend(n3, n1)
|
||||
return n0
|
||||
}"
|
||||
|
@ -38,13 +38,13 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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) {
|
||||
const t0 = _template("<div><div></div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [, { 0: [n1],}],} = _children(n0)
|
||||
_setAttr(n1, "id", undefined, _ctx.foo)
|
||||
_setDynamicProp(n1, "id", undefined, _ctx.foo)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -83,7 +83,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
|
||||
expect(code).contains('_setDynamicProp(n1, "id", undefined, _ctx.id)')
|
||||
})
|
||||
|
||||
test('no expression', () => {
|
||||
|
@ -110,7 +110,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
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)', () => {
|
||||
|
@ -130,7 +130,7 @@ describe('compiler v-bind', () => {
|
|||
|
||||
expect(code).matchSnapshot()
|
||||
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).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)')
|
||||
expect(code).contains('_setDynamicProp(n1, _ctx.id, undefined, _ctx.id)')
|
||||
})
|
||||
|
||||
test('should error if empty expression', () => {
|
||||
|
@ -192,7 +192,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
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', () => {
|
||||
|
@ -211,7 +211,9 @@ describe('compiler v-bind', () => {
|
|||
|
||||
expect(code).matchSnapshot()
|
||||
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', () => {
|
||||
|
@ -232,18 +234,152 @@ describe('compiler v-bind', () => {
|
|||
expect(code).matchSnapshot()
|
||||
expect(code).contains('renderEffect')
|
||||
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('.prop modifier')
|
||||
test.todo('.prop modifier w/ no expression')
|
||||
test.todo('.prop modifier w/ dynamic arg')
|
||||
test('.prop modifier', () => {
|
||||
const { ir, code } = compileWithVBind(`<div v-bind:fooBar.prop="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 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.todo('.prop modifier (shorthand)')
|
||||
test.todo('.prop modifier (shortband) w/ no expression')
|
||||
test.todo('.attr modifier')
|
||||
test.todo('.attr modifier w/ no expression')
|
||||
|
||||
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) {
|
||||
const { pushFnCall, newline, vaporHelper, helper } = context
|
||||
const { pushFnCall, pushMulti, newline, vaporHelper, helper } = context
|
||||
|
||||
newline()
|
||||
pushFnCall(
|
||||
vaporHelper('setAttr'),
|
||||
vaporHelper('setDynamicProp'),
|
||||
`n${oper.element}`,
|
||||
// 2. key name
|
||||
() => {
|
||||
if (oper.runtimeCamelize) {
|
||||
pushFnCall(helper('camelize'), () => genExpression(oper.key, context))
|
||||
} else if (oper.runtimePrefix) {
|
||||
pushMulti([`\`${oper.runtimePrefix}\${`, `}\``], () =>
|
||||
genExpression(oper.key, context),
|
||||
)
|
||||
} else {
|
||||
genExpression(oper.key, context)
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ export interface SetPropIRNode extends BaseIRNode {
|
|||
key: IRExpression
|
||||
value: IRExpression
|
||||
runtimeCamelize: boolean
|
||||
runtimePrefix?: string
|
||||
}
|
||||
|
||||
export interface SetTextIRNode extends BaseIRNode {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
ErrorCodes,
|
||||
type SimpleExpressionNode,
|
||||
createCompilerError,
|
||||
createSimpleExpression,
|
||||
} 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()) {
|
||||
context.options.onError(
|
||||
createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
|
||||
|
@ -48,7 +57,15 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => {
|
|||
key: arg,
|
||||
value: exp,
|
||||
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') {
|
||||
setClass(el, void 0, val)
|
||||
setClass(el, oldVal, newVal)
|
||||
} else if (key === 'style') {
|
||||
setStyle(el as HTMLElement, void 0, val)
|
||||
} else if (key in el) {
|
||||
;(el as any)[key] = val
|
||||
setStyle(el as HTMLElement, oldVal, newVal)
|
||||
} else if (
|
||||
key[0] === '.'
|
||||
? ((key = key.slice(1)), true)
|
||||
: key[0] === '^'
|
||||
? ((key = key.slice(1)), false)
|
||||
: key in el
|
||||
) {
|
||||
setDOMProp(el, key, oldVal, newVal)
|
||||
} else {
|
||||
// TODO special checks
|
||||
setAttr(el, key, void 0, val)
|
||||
setAttr(el, key, oldVal, newVal)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue