feat(vapor): merge inherited attrs with current attrs
This commit is contained in:
parent
c91586528a
commit
247617612a
|
@ -29,7 +29,7 @@
|
|||
"dev-prepare-cjs": "node scripts/prepare-cjs.js || npm run build-all-cjs",
|
||||
"dev-compiler": "run-p \"dev template-explorer\" serve open",
|
||||
"dev-sfc": "run-s dev-prepare-cjs dev-sfc-run",
|
||||
"dev-sfc-serve": "vite packages-private/sfc-playground --host",
|
||||
"dev-sfc-serve": "vite packages-private/sfc-playground",
|
||||
"dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if esm-bundler-runtime\" \"dev vue -ipf esm-browser-runtime\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve",
|
||||
"dev-vapor": "pnpm -C playground run dev",
|
||||
"serve": "serve",
|
||||
|
|
|
@ -140,11 +140,12 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compile > directives > v-pre > basic 1`] = `
|
||||
"import { template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
|
||||
|
||||
export function render(_ctx, $props) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(false)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -176,15 +177,16 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compile > dynamic root nodes and interpolation 1`] = `
|
||||
"import { delegate as _delegate, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||
"import { delegate as _delegate, setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<button></button>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_delegate(n0, "click", () => _ctx.handleClick)
|
||||
_setInheritAttrs(["id"])
|
||||
_renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
|
||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.count))
|
||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.count, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -199,7 +201,8 @@ exports[`compile > expression parsing > interpolation 1`] = `
|
|||
exports[`compile > expression parsing > v-bind 1`] = `
|
||||
"((_ctx) => {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, { [key.value+1]: _unref(foo)[key.value+1]() }))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true))
|
||||
return n0
|
||||
})()"
|
||||
`;
|
||||
|
|
|
@ -286,22 +286,24 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compiler: element transform > props + children 1`] = `
|
||||
"import { template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div id=\\"foo\\"><span></span></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(false)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: element transform > props merging: class 1`] = `
|
||||
"import { renderEffect as _renderEffect, setClass as _setClass, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setClass as _setClass, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setClass(n0, ["foo", { bar: _ctx.isBar }]))
|
||||
_setInheritAttrs(["class"])
|
||||
_renderEffect(() => _setClass(n0, ["foo", { bar: _ctx.isBar }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -324,66 +326,72 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compiler: element transform > props merging: style 1`] = `
|
||||
"import { renderEffect as _renderEffect, setStyle as _setStyle, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setStyle as _setStyle, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setStyle(n0, ["color: green", { color: 'red' }]))
|
||||
_setInheritAttrs(["style"])
|
||||
_renderEffect(() => _setStyle(n0, ["color: green", { color: 'red' }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: element transform > static props 1`] = `
|
||||
"import { template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div id=\\"foo\\" class=\\"bar\\"></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(false)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: element transform > v-bind="obj" 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, _ctx.obj))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: element transform > v-bind="obj" after static prop 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, { id: "foo" }, _ctx.obj))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: element transform > v-bind="obj" before static prop 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, _ctx.obj, { id: "foo" }))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: element transform > v-bind="obj" between static props 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, { id: "foo" }, _ctx.obj, { class: "bar" }))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -1,177 +1,193 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`compiler v-bind > .attr modifier 1`] = `
|
||||
"import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
|
||||
"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()
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id))
|
||||
_setInheritAttrs(["foo-bar"])
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .attr modifier w/ no expression 1`] = `
|
||||
"import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor';
|
||||
"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()
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar))
|
||||
_setInheritAttrs(["foo-bar"])
|
||||
_renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .camel modifier 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id))
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = `
|
||||
"import { camelize as _camelize } from 'vue';
|
||||
import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, { [_camelize(_ctx.foo)]: _ctx.id }))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .camel modifier w/ no expression 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar))
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .prop modifier (shortband) w/ no expression 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||
"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()
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar))
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .prop modifier (shorthand) 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||
"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()
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id))
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .prop modifier 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||
"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()
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id))
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .prop modifier w/ dynamic arg 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, { ["." + _ctx.fooBar]: _ctx.id }))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > .prop modifier w/ no expression 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor';
|
||||
"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()
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar))
|
||||
_setInheritAttrs(["fooBar"])
|
||||
_renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > basic 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id))
|
||||
_setInheritAttrs(["id"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > dynamic arg 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, { [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > dynamic arg w/ static attribute 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProps(n0, { [_ctx.id]: _ctx.id, foo: "bar", checked: "" }))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > no expression (shorthand) 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase))
|
||||
_setInheritAttrs(["camel-case"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > no expression 1`] = `
|
||||
"import { renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id))
|
||||
_setInheritAttrs(["id"])
|
||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.id, true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > should error if empty expression 1`] = `
|
||||
"import { template as _template } from 'vue/vapor';
|
||||
"import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div arg></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setInheritAttrs(false)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -126,13 +126,14 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compiler: vModel transform > should support input (checkbox) 1`] = `
|
||||
"import { vModelCheckbox as _vModelCheckbox, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
|
||||
"import { vModelCheckbox as _vModelCheckbox, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<input type=\\"checkbox\\">")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_withDirectives(n0, [[_vModelCheckbox, () => _ctx.model]])
|
||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||
_setInheritAttrs(false)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -150,25 +151,27 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compiler: vModel transform > should support input (radio) 1`] = `
|
||||
"import { vModelRadio as _vModelRadio, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
|
||||
"import { vModelRadio as _vModelRadio, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<input type=\\"radio\\">")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_withDirectives(n0, [[_vModelRadio, () => _ctx.model]])
|
||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||
_setInheritAttrs(false)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: vModel transform > should support input (text) 1`] = `
|
||||
"import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
|
||||
"import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<input type=\\"text\\">")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_withDirectives(n0, [[_vModelText, () => _ctx.model]])
|
||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||
_setInheritAttrs(false)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -243,14 +246,15 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compiler: vModel transform > should support w/ dynamic v-bind 1`] = `
|
||||
"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor';
|
||||
"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';
|
||||
const t0 = _template("<input>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_withDirectives(n0, [[_vModelDynamic, () => _ctx.model]])
|
||||
_delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event))
|
||||
_renderEffect(() => _setDynamicProps(n0, _ctx.obj))
|
||||
_setInheritAttrs(true)
|
||||
_renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`compiler: v-once > as root node 1`] = `
|
||||
"import { setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
||||
"import { setDynamicProp as _setDynamicProp, setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setDynamicProp(n0, "id", _ctx.foo)
|
||||
_setDynamicProp(n0, "id", _ctx.foo, true)
|
||||
_setInheritAttrs(["id"])
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -588,7 +588,7 @@ describe('compiler: element transform', () => {
|
|||
],
|
||||
},
|
||||
])
|
||||
expect(code).contains('_setDynamicProps(n0, _ctx.obj)')
|
||||
expect(code).contains('_setDynamicProps(n0, [_ctx.obj], true)')
|
||||
})
|
||||
|
||||
test('v-bind="obj" after static prop', () => {
|
||||
|
@ -624,7 +624,9 @@ describe('compiler: element transform', () => {
|
|||
],
|
||||
},
|
||||
])
|
||||
expect(code).contains('_setDynamicProps(n0, { id: "foo" }, _ctx.obj)')
|
||||
expect(code).contains(
|
||||
'_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true)',
|
||||
)
|
||||
})
|
||||
|
||||
test('v-bind="obj" before static prop', () => {
|
||||
|
@ -650,7 +652,9 @@ describe('compiler: element transform', () => {
|
|||
],
|
||||
},
|
||||
])
|
||||
expect(code).contains('_setDynamicProps(n0, _ctx.obj, { id: "foo" })')
|
||||
expect(code).contains(
|
||||
'_setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true)',
|
||||
)
|
||||
})
|
||||
|
||||
test('v-bind="obj" between static props', () => {
|
||||
|
@ -678,7 +682,7 @@ describe('compiler: element transform', () => {
|
|||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
'_setDynamicProps(n0, { id: "foo" }, _ctx.obj, { class: "bar" })',
|
||||
'_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true)',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -723,6 +727,9 @@ describe('compiler: element transform', () => {
|
|||
delegate: true,
|
||||
effect: false,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ describe('compiler: template ref transform', () => {
|
|||
flags: DynamicFlag.REFERENCED,
|
||||
})
|
||||
expect(ir.template).toEqual(['<div></div>'])
|
||||
expect(ir.block.operation).lengthOf(1)
|
||||
expect(ir.block.operation[0]).toMatchObject({
|
||||
expect(ir.block.operation).lengthOf(2)
|
||||
expect(ir.block.operation[1]).toMatchObject({
|
||||
type: IRNodeTypes.SET_TEMPLATE_REF,
|
||||
element: 0,
|
||||
value: {
|
||||
|
@ -56,6 +56,9 @@ describe('compiler: template ref transform', () => {
|
|||
})
|
||||
expect(ir.template).toEqual(['<div></div>'])
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.DECLARE_OLD_REF,
|
||||
id: 0,
|
||||
|
|
|
@ -74,7 +74,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id)')
|
||||
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id, true)')
|
||||
})
|
||||
|
||||
test('no expression', () => {
|
||||
|
@ -104,7 +104,7 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
},
|
||||
})
|
||||
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id)')
|
||||
expect(code).contains('_setDynamicProp(n0, "id", _ctx.id, true)')
|
||||
})
|
||||
|
||||
test('no expression (shorthand)', () => {
|
||||
|
@ -126,7 +126,9 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
},
|
||||
})
|
||||
expect(code).contains('_setDynamicProp(n0, "camel-case", _ctx.camelCase)')
|
||||
expect(code).contains(
|
||||
'_setDynamicProp(n0, "camel-case", _ctx.camelCase, true)',
|
||||
)
|
||||
})
|
||||
|
||||
test('dynamic arg', () => {
|
||||
|
@ -171,7 +173,7 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
})
|
||||
expect(code).contains(
|
||||
'_setDynamicProps(n0, { [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title })',
|
||||
'_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true)',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -224,7 +226,7 @@ describe('compiler v-bind', () => {
|
|||
],
|
||||
})
|
||||
expect(code).contains(
|
||||
'_setDynamicProps(n0, { [_ctx.id]: _ctx.id, foo: "bar", checked: "" })',
|
||||
'_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true)',
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -286,7 +288,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id)')
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id, true)')
|
||||
})
|
||||
|
||||
test('.camel modifier w/ no expression', () => {
|
||||
|
@ -310,7 +312,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar)')
|
||||
expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||
})
|
||||
|
||||
test('.camel modifier w/ dynamic arg', () => {
|
||||
|
@ -341,7 +343,7 @@ describe('compiler v-bind', () => {
|
|||
expect(code).matchSnapshot()
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains(
|
||||
`_setDynamicProps(n0, { [_camelize(_ctx.foo)]: _ctx.id })`,
|
||||
`_setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true)`,
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -368,7 +370,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id, true)')
|
||||
})
|
||||
|
||||
test('.prop modifier w/ no expression', () => {
|
||||
|
@ -392,7 +394,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||
})
|
||||
|
||||
test('.prop modifier w/ dynamic arg', () => {
|
||||
|
@ -422,7 +424,7 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains(
|
||||
`_setDynamicProps(n0, { ["." + _ctx.fooBar]: _ctx.id })`,
|
||||
`_setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true)`,
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -449,7 +451,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id, true)')
|
||||
})
|
||||
|
||||
test('.prop modifier (shortband) w/ no expression', () => {
|
||||
|
@ -473,7 +475,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)')
|
||||
expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar, true)')
|
||||
})
|
||||
|
||||
test('.attr modifier', () => {
|
||||
|
@ -497,7 +499,7 @@ describe('compiler v-bind', () => {
|
|||
},
|
||||
})
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id)')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id, true)')
|
||||
})
|
||||
|
||||
test('.attr modifier w/ no expression', () => {
|
||||
|
@ -522,6 +524,6 @@ describe('compiler v-bind', () => {
|
|||
})
|
||||
|
||||
expect(code).contains('renderEffect')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.fooBar)')
|
||||
expect(code).contains('_setAttr(n0, "foo-bar", _ctx.fooBar, true)')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -28,7 +28,11 @@ describe('v-html', () => {
|
|||
expect(vaporHelpers).contains('setHtml')
|
||||
expect(helpers.size).toBe(0)
|
||||
|
||||
expect(ir.block.operation).toEqual([])
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(ir.block.effect).toMatchObject([
|
||||
{
|
||||
expressions: [
|
||||
|
@ -70,7 +74,11 @@ describe('v-html', () => {
|
|||
// children should have been removed
|
||||
expect(ir.template).toEqual(['<div></div>'])
|
||||
|
||||
expect(ir.block.operation).toEqual([])
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(ir.block.effect).toMatchObject([
|
||||
{
|
||||
expressions: [
|
||||
|
|
|
@ -47,6 +47,9 @@ describe('v-on', () => {
|
|||
keyOverride: undefined,
|
||||
delegate: true,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
|
@ -91,7 +94,11 @@ describe('v-on', () => {
|
|||
expect(vaporHelpers).contains('on')
|
||||
expect(vaporHelpers).contains('renderEffect')
|
||||
expect(helpers.size).toBe(0)
|
||||
expect(ir.block.operation).toEqual([])
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(ir.block.effect[0].operations[0]).toMatchObject({
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
|
@ -130,7 +137,11 @@ describe('v-on', () => {
|
|||
expect(vaporHelpers).contains('on')
|
||||
expect(vaporHelpers).contains('renderEffect')
|
||||
expect(helpers.size).toBe(0)
|
||||
expect(ir.block.operation).toEqual([])
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(ir.block.effect[0].operations[0]).toMatchObject({
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
|
@ -169,6 +180,9 @@ describe('v-on', () => {
|
|||
},
|
||||
delegate: true,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(code).contains(`_delegate(n0, "click", () => $event => (_ctx.i++))`)
|
||||
})
|
||||
|
@ -206,6 +220,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: 'foo();bar()' },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
// should wrap with `{` for multiple statements
|
||||
// in this case the return value is discarded and the behavior is
|
||||
|
@ -224,6 +241,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: '\nfoo();\nbar()\n' },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
// should wrap with `{` for multiple statements
|
||||
// in this case the return value is discarded and the behavior is
|
||||
|
@ -244,6 +264,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: 'foo($event)' },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
// should NOT prefix $event
|
||||
expect(code).contains(
|
||||
|
@ -262,6 +285,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: 'foo($event);bar()' },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
// should NOT prefix $event
|
||||
expect(code).contains(
|
||||
|
@ -278,6 +304,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: '$event => foo($event)' },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
`_delegate(n0, "click", () => $event => _ctx.foo($event))`,
|
||||
|
@ -296,6 +325,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: '(e: any): any => foo(e)' },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
`_delegate(n0, "click", () => (e: any): any => _ctx.foo(e))`,
|
||||
|
@ -323,6 +355,9 @@ describe('v-on', () => {
|
|||
`,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
|
@ -349,6 +384,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: `a['b' + c]` },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -361,6 +399,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: `a['b' + c]` },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -378,6 +419,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: `e => foo(e)` },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(code).contains(`_delegate(n0, "click", () => e => _ctx.foo(e))`)
|
||||
})
|
||||
|
@ -432,6 +476,9 @@ describe('v-on', () => {
|
|||
keyOverride: undefined,
|
||||
delegate: false,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(code).contains(
|
||||
`_on(n0, "click", () => _ctx.test, {
|
||||
|
@ -487,6 +534,9 @@ describe('v-on', () => {
|
|||
options: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -529,6 +579,9 @@ describe('v-on', () => {
|
|||
options: ['capture'],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -543,6 +596,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
modifiers: { nonKeys: ['exact'] },
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -562,6 +618,9 @@ describe('v-on', () => {
|
|||
options: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -604,6 +663,9 @@ describe('v-on', () => {
|
|||
modifiers: { nonKeys: ['right'] },
|
||||
keyOverride: undefined,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -645,6 +707,9 @@ describe('v-on', () => {
|
|||
modifiers: { nonKeys: ['middle'] },
|
||||
keyOverride: undefined,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
|
@ -694,6 +759,9 @@ describe('v-on', () => {
|
|||
type: IRNodeTypes.SET_EVENT,
|
||||
delegate: true,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -68,6 +68,7 @@ describe('compiler: v-once', () => {
|
|||
elements: [0],
|
||||
parent: 2,
|
||||
},
|
||||
{ type: IRNodeTypes.SET_INHERIT_ATTRS },
|
||||
])
|
||||
})
|
||||
|
||||
|
@ -96,6 +97,9 @@ describe('compiler: v-once', () => {
|
|||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
expect(code).not.contains('effect')
|
||||
})
|
||||
|
@ -128,6 +132,9 @@ describe('compiler: v-once', () => {
|
|||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
|
@ -147,6 +154,7 @@ describe('compiler: v-once', () => {
|
|||
elements: [0],
|
||||
parent: 1,
|
||||
},
|
||||
{ type: IRNodeTypes.SET_INHERIT_ATTRS },
|
||||
])
|
||||
})
|
||||
|
||||
|
@ -160,7 +168,7 @@ describe('compiler: v-once', () => {
|
|||
expect(code).toMatchSnapshot()
|
||||
expect(helpers).lengthOf(0)
|
||||
expect(ir.block.effect).lengthOf(0)
|
||||
expect(ir.block.operation).lengthOf(0)
|
||||
expect(ir.block.operation).lengthOf(1)
|
||||
})
|
||||
|
||||
test.todo('with hoistStatic: true')
|
||||
|
|
|
@ -28,7 +28,11 @@ describe('v-text', () => {
|
|||
expect(vaporHelpers).contains('setText')
|
||||
expect(helpers.size).toBe(0)
|
||||
|
||||
expect(ir.block.operation).toEqual([])
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
},
|
||||
])
|
||||
|
||||
expect(ir.block.effect).toMatchObject([
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
genMulti,
|
||||
} from './utils'
|
||||
import { genExpression } from './expression'
|
||||
import { genPropKey } from './prop'
|
||||
import { genPropKey, genPropValue } from './prop'
|
||||
import {
|
||||
createSimpleExpression,
|
||||
toValidAssetId,
|
||||
|
@ -121,14 +121,15 @@ function genStaticProps(
|
|||
}
|
||||
|
||||
function genProp(prop: IRProp, context: CodegenContext, isStatic?: boolean) {
|
||||
const values = genPropValue(prop.values, context)
|
||||
return [
|
||||
...genPropKey(prop, context),
|
||||
': ',
|
||||
...(prop.handler
|
||||
? genEventHandler(context, prop.values[0])
|
||||
: isStatic
|
||||
? ['() => (', ...genExpression(prop.values[0], context), ')']
|
||||
: genExpression(prop.values[0], context)),
|
||||
? ['() => (', ...values, ')']
|
||||
: values),
|
||||
...(prop.model
|
||||
? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)]
|
||||
: []),
|
||||
|
|
|
@ -132,7 +132,7 @@ function genIdentifier(
|
|||
prefix = `${raw}: `
|
||||
}
|
||||
|
||||
const type = bindingMetadata[raw]
|
||||
const type = bindingMetadata && bindingMetadata[raw]
|
||||
if (inline) {
|
||||
switch (type) {
|
||||
case BindingTypes.SETUP_LET:
|
||||
|
|
|
@ -6,7 +6,7 @@ import { genFor } from './for'
|
|||
import { genSetHtml } from './html'
|
||||
import { genIf } from './if'
|
||||
import { genSetModelValue } from './modelValue'
|
||||
import { genDynamicProps, genSetProp } from './prop'
|
||||
import { genDynamicProps, genSetInheritAttrs, genSetProp } from './prop'
|
||||
import { genDeclareOldRef, genSetTemplateRef } from './templateRef'
|
||||
import { genCreateTextNode, genSetText } from './text'
|
||||
import {
|
||||
|
@ -67,6 +67,8 @@ export function genOperation(
|
|||
return genDeclareOldRef(oper)
|
||||
case IRNodeTypes.SLOT_OUTLET_NODE:
|
||||
return genSlotOutlet(oper, context)
|
||||
case IRNodeTypes.SET_INHERIT_ATTRS:
|
||||
return genSetInheritAttrs(oper, context)
|
||||
}
|
||||
|
||||
return []
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
IRDynamicPropsKind,
|
||||
type IRProp,
|
||||
type SetDynamicPropsIRNode,
|
||||
type SetInheritAttrsIRNode,
|
||||
type SetPropIRNode,
|
||||
type VaporHelper,
|
||||
} from '../ir'
|
||||
|
@ -55,6 +56,7 @@ export function genSetProp(
|
|||
`n${oper.element}`,
|
||||
omitKey ? false : genExpression(key, context),
|
||||
genPropValue(values, context),
|
||||
oper.root && 'true',
|
||||
),
|
||||
]
|
||||
}
|
||||
|
@ -70,14 +72,18 @@ export function genDynamicProps(
|
|||
...genCall(
|
||||
vaporHelper('setDynamicProps'),
|
||||
`n${oper.element}`,
|
||||
...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=""
|
||||
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=""
|
||||
),
|
||||
),
|
||||
oper.root && 'true',
|
||||
),
|
||||
]
|
||||
}
|
||||
|
@ -125,7 +131,10 @@ export function genPropKey(
|
|||
return ['[', modifier && `${JSON.stringify(modifier)} + `, ...key, ']']
|
||||
}
|
||||
|
||||
function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) {
|
||||
export function genPropValue(
|
||||
values: SimpleExpressionNode[],
|
||||
context: CodegenContext,
|
||||
): CodeFragment[] {
|
||||
if (values.length === 1) {
|
||||
return genExpression(values[0], context)
|
||||
}
|
||||
|
@ -134,3 +143,28 @@ function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) {
|
|||
...values.map(expr => genExpression(expr, context)),
|
||||
)
|
||||
}
|
||||
|
||||
export function genSetInheritAttrs(
|
||||
{ staticProps, dynamicProps }: SetInheritAttrsIRNode,
|
||||
context: CodegenContext,
|
||||
): CodeFragment[] {
|
||||
const { vaporHelper } = context
|
||||
|
||||
// - `undefined` : no props
|
||||
// - `false` : all props are static
|
||||
// - `string[]` : list of props are dynamic
|
||||
// - `true` : all props as dynamic
|
||||
const value =
|
||||
dynamicProps === true
|
||||
? 'true'
|
||||
: dynamicProps.length
|
||||
? genMulti(
|
||||
DELIMITERS_ARRAY,
|
||||
...dynamicProps.map(p => JSON.stringify(p)),
|
||||
)
|
||||
: staticProps
|
||||
? 'false'
|
||||
: null
|
||||
if (value == null) return []
|
||||
return [NEWLINE, ...genCall(vaporHelper('setInheritAttrs'), value)]
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ export function genMulti(
|
|||
...frags: CodeFragments[]
|
||||
): CodeFragment[] {
|
||||
if (placeholder) {
|
||||
while (!frags[frags.length - 1]) {
|
||||
while (frags.length > 0 && !frags[frags.length - 1]) {
|
||||
frags.pop()
|
||||
}
|
||||
frags = frags.map(frag => frag || placeholder)
|
||||
|
|
|
@ -24,6 +24,7 @@ export enum IRNodeTypes {
|
|||
SET_HTML,
|
||||
SET_TEMPLATE_REF,
|
||||
SET_MODEL_VALUE,
|
||||
SET_INHERIT_ATTRS,
|
||||
|
||||
INSERT_NODE,
|
||||
PREPEND_NODE,
|
||||
|
@ -93,12 +94,14 @@ export interface SetPropIRNode extends BaseIRNode {
|
|||
type: IRNodeTypes.SET_PROP
|
||||
element: number
|
||||
prop: IRProp
|
||||
root: boolean
|
||||
}
|
||||
|
||||
export interface SetDynamicPropsIRNode extends BaseIRNode {
|
||||
type: IRNodeTypes.SET_DYNAMIC_PROPS
|
||||
element: number
|
||||
props: IRProps[]
|
||||
root: boolean
|
||||
}
|
||||
|
||||
export interface SetDynamicEventsIRNode extends BaseIRNode {
|
||||
|
@ -156,6 +159,12 @@ export interface SetModelValueIRNode extends BaseIRNode {
|
|||
isComponent: boolean
|
||||
}
|
||||
|
||||
export interface SetInheritAttrsIRNode extends BaseIRNode {
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS
|
||||
staticProps: boolean
|
||||
dynamicProps: true | string[]
|
||||
}
|
||||
|
||||
export interface CreateTextNodeIRNode extends BaseIRNode {
|
||||
type: IRNodeTypes.CREATE_TEXT_NODE
|
||||
id: number
|
||||
|
@ -220,6 +229,7 @@ export type OperationNode =
|
|||
| SetHtmlIRNode
|
||||
| SetTemplateRefIRNode
|
||||
| SetModelValueIRNode
|
||||
| SetInheritAttrsIRNode
|
||||
| CreateTextNodeIRNode
|
||||
| InsertNodeIRNode
|
||||
| PrependNodeIRNode
|
||||
|
|
|
@ -64,9 +64,15 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||
isDynamicComponent,
|
||||
)
|
||||
|
||||
const singleRoot =
|
||||
context.root === context.parent &&
|
||||
context.parent.node.children.filter(
|
||||
child => child.type !== NodeTypes.COMMENT,
|
||||
).length === 1
|
||||
;(isComponent ? transformComponentElement : transformNativeElement)(
|
||||
node as any,
|
||||
propsResult,
|
||||
singleRoot,
|
||||
context as TransformContext<ElementNode>,
|
||||
isDynamicComponent,
|
||||
)
|
||||
|
@ -76,6 +82,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||
function transformComponentElement(
|
||||
node: ComponentNode,
|
||||
propsResult: PropsResult,
|
||||
singleRoot: boolean,
|
||||
context: TransformContext,
|
||||
isDynamicComponent: boolean,
|
||||
) {
|
||||
|
@ -108,16 +115,13 @@ function transformComponentElement(
|
|||
}
|
||||
|
||||
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
|
||||
const root =
|
||||
context.root === context.parent && context.parent.node.children.length === 1
|
||||
|
||||
context.registerOperation({
|
||||
type: IRNodeTypes.CREATE_COMPONENT_NODE,
|
||||
id: context.reference(),
|
||||
tag,
|
||||
props: propsResult[0] ? propsResult[1] : [propsResult[1]],
|
||||
asset,
|
||||
root,
|
||||
root: singleRoot,
|
||||
slots: [...context.slots],
|
||||
once: context.inVOnce,
|
||||
dynamic: dynamicComponent,
|
||||
|
@ -162,6 +166,7 @@ function resolveSetupReference(name: string, context: TransformContext) {
|
|||
function transformNativeElement(
|
||||
node: PlainElementNode,
|
||||
propsResult: PropsResult,
|
||||
singleRoot: boolean,
|
||||
context: TransformContext<ElementNode>,
|
||||
) {
|
||||
const { tag } = node
|
||||
|
@ -172,29 +177,43 @@ function transformNativeElement(
|
|||
template += `<${tag}`
|
||||
if (scopeId) template += ` ${scopeId}`
|
||||
|
||||
let staticProps = false
|
||||
const dynamicProps: string[] = []
|
||||
if (propsResult[0] /* dynamic props */) {
|
||||
const [, dynamicArgs, expressions] = propsResult
|
||||
context.registerEffect(expressions, {
|
||||
type: IRNodeTypes.SET_DYNAMIC_PROPS,
|
||||
element: context.reference(),
|
||||
props: dynamicArgs,
|
||||
root: singleRoot,
|
||||
})
|
||||
} else {
|
||||
for (const prop of propsResult[1]) {
|
||||
const { key, values } = prop
|
||||
if (key.isStatic && values.length === 1 && values[0].isStatic) {
|
||||
staticProps = true
|
||||
template += ` ${key.content}`
|
||||
if (values[0].content) template += `="${values[0].content}"`
|
||||
} else {
|
||||
dynamicProps.push(key.content)
|
||||
context.registerEffect(values, {
|
||||
type: IRNodeTypes.SET_PROP,
|
||||
element: context.reference(),
|
||||
prop,
|
||||
root: singleRoot,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (singleRoot) {
|
||||
context.registerOperation({
|
||||
type: IRNodeTypes.SET_INHERIT_ATTRS,
|
||||
staticProps: staticProps,
|
||||
dynamicProps: propsResult[0] ? true : dynamicProps,
|
||||
})
|
||||
}
|
||||
|
||||
template += `>` + context.childrenTemplate.join('')
|
||||
// TODO remove unnecessary close tag, e.g. if it's the last element of the template
|
||||
if (!isVoidTag(tag)) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
ref,
|
||||
renderEffect,
|
||||
setDynamicProps,
|
||||
setInheritAttrs,
|
||||
template,
|
||||
watchEffect,
|
||||
} from '../src'
|
||||
|
@ -77,9 +78,7 @@ describe('api: setup context', () => {
|
|||
inheritAttrs: false,
|
||||
setup(props, { attrs }) {
|
||||
const el = document.createElement('div')
|
||||
renderEffect(() => {
|
||||
setDynamicProps(el, attrs)
|
||||
})
|
||||
renderEffect(() => setDynamicProps(el, [attrs]))
|
||||
return el
|
||||
},
|
||||
})
|
||||
|
@ -103,23 +102,24 @@ describe('api: setup context', () => {
|
|||
const toggle = ref(true)
|
||||
|
||||
const Wrapper = defineComponent({
|
||||
setup(_, { slots }) {
|
||||
return slots.default!()
|
||||
setup(_) {
|
||||
const n0 = createSlot('default')
|
||||
setInheritAttrs(false, true)
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
||||
const Child = defineComponent({
|
||||
inheritAttrs: false,
|
||||
setup(_: any, { attrs }: any) {
|
||||
return createComponent(Wrapper, null, {
|
||||
const n0 = createComponent(Wrapper, null, {
|
||||
default: () => {
|
||||
const n0 = template('<div>')() as HTMLDivElement
|
||||
renderEffect(() => {
|
||||
setDynamicProps(n0, attrs)
|
||||
})
|
||||
renderEffect(() => setDynamicProps(n0, [attrs], true))
|
||||
return n0
|
||||
},
|
||||
})
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
getCurrentInstance,
|
||||
nextTick,
|
||||
ref,
|
||||
setInheritAttrs,
|
||||
setText,
|
||||
template,
|
||||
watchEffect,
|
||||
|
@ -18,7 +19,8 @@ describe('attribute fallthrough', () => {
|
|||
props: ['foo'],
|
||||
render() {
|
||||
const instance = getCurrentInstance()!
|
||||
const n0 = t0()
|
||||
const n0 = t0() as Element
|
||||
setInheritAttrs()
|
||||
watchEffect(() => setText(n0, instance.props.foo))
|
||||
return n0
|
||||
},
|
||||
|
@ -62,7 +64,8 @@ describe('attribute fallthrough', () => {
|
|||
inheritAttrs: false,
|
||||
render() {
|
||||
const instance = getCurrentInstance()!
|
||||
const n0 = t0()
|
||||
const n0 = t0() as Element
|
||||
setInheritAttrs()
|
||||
watchEffect(() => setText(n0, instance.props.foo))
|
||||
return n0
|
||||
},
|
||||
|
@ -105,7 +108,8 @@ describe('attribute fallthrough', () => {
|
|||
props: ['custom-attr'],
|
||||
render() {
|
||||
const instance = getCurrentInstance()!
|
||||
const n0 = t0()
|
||||
const n0 = t0() as Element
|
||||
setInheritAttrs()
|
||||
watchEffect(() => setText(n0, instance.attrs.foo))
|
||||
return n0
|
||||
},
|
||||
|
|
|
@ -407,25 +407,25 @@ describe('patchProp', () => {
|
|||
describe('setDynamicProps', () => {
|
||||
test('basic set dynamic props', () => {
|
||||
const el = document.createElement('div')
|
||||
setDynamicProps(el, { foo: 'val' }, { bar: 'val' })
|
||||
setDynamicProps(el, [{ 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, [{ foo: 'val' }, { foo: 'newVal' }])
|
||||
expect(el.getAttribute('foo')).toBe('newVal')
|
||||
})
|
||||
|
||||
test('should reset old props', () => {
|
||||
const el = document.createElement('div')
|
||||
|
||||
setDynamicProps(el, { foo: 'val' })
|
||||
setDynamicProps(el, [{ foo: 'val' }])
|
||||
expect(el.attributes.length).toBe(1)
|
||||
expect(el.getAttribute('foo')).toBe('val')
|
||||
|
||||
setDynamicProps(el, { bar: 'val' })
|
||||
setDynamicProps(el, [{ bar: 'val' }])
|
||||
expect(el.attributes.length).toBe(1)
|
||||
expect(el.getAttribute('bar')).toBe('val')
|
||||
expect(el.getAttribute('foo')).toBeNull()
|
||||
|
@ -434,18 +434,18 @@ describe('patchProp', () => {
|
|||
test('should reset old modifier props', () => {
|
||||
const el = document.createElement('div')
|
||||
|
||||
setDynamicProps(el, { ['.foo']: 'val' })
|
||||
setDynamicProps(el, [{ ['.foo']: 'val' }])
|
||||
expect((el as any).foo).toBe('val')
|
||||
|
||||
setDynamicProps(el, { ['.bar']: 'val' })
|
||||
setDynamicProps(el, [{ ['.bar']: 'val' }])
|
||||
expect((el as any).bar).toBe('val')
|
||||
expect((el as any).foo).toBe('')
|
||||
|
||||
setDynamicProps(el, { ['^foo']: 'val' })
|
||||
setDynamicProps(el, [{ ['^foo']: 'val' }])
|
||||
expect(el.attributes.length).toBe(1)
|
||||
expect(el.getAttribute('foo')).toBe('val')
|
||||
|
||||
setDynamicProps(el, { ['^bar']: 'val' })
|
||||
setDynamicProps(el, [{ ['^bar']: 'val' }])
|
||||
expect(el.attributes.length).toBe(1)
|
||||
expect(el.getAttribute('bar')).toBe('val')
|
||||
expect(el.getAttribute('foo')).toBeNull()
|
||||
|
|
|
@ -12,11 +12,12 @@ import {
|
|||
walkRawProps,
|
||||
} from './componentProps'
|
||||
import { type RawSlots, isDynamicSlotFn } from './componentSlots'
|
||||
import { withAttrs } from './componentAttrs'
|
||||
import { setInheritAttrs, withAttrs } from './componentAttrs'
|
||||
import { isString } from '@vue/shared'
|
||||
import { renderEffect } from './renderEffect'
|
||||
import { normalizeBlock } from './dom/element'
|
||||
import { setDynamicProp } from './dom/prop'
|
||||
import { setClass, setDynamicProp } from './dom/prop'
|
||||
import { setStyle } from './dom/style'
|
||||
|
||||
export function createComponent(
|
||||
comp: Component | string,
|
||||
|
@ -25,11 +26,12 @@ export function createComponent(
|
|||
singleRoot: boolean = false,
|
||||
once: boolean = false,
|
||||
): ComponentInternalInstance | HTMLElement {
|
||||
const current = currentInstance!
|
||||
|
||||
if (isString(comp)) {
|
||||
return fallbackComponent(comp, rawProps, slots)
|
||||
return fallbackComponent(comp, rawProps, slots, current, singleRoot)
|
||||
}
|
||||
|
||||
const current = currentInstance!
|
||||
const instance = createComponentInstance(
|
||||
comp,
|
||||
singleRoot ? withAttrs(rawProps) : rawProps,
|
||||
|
@ -48,16 +50,31 @@ function fallbackComponent(
|
|||
comp: string,
|
||||
rawProps: RawProps | null,
|
||||
slots: RawSlots | null,
|
||||
instance: ComponentInternalInstance,
|
||||
singleRoot: boolean = false,
|
||||
): HTMLElement {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const el = document.createElement(comp)
|
||||
|
||||
if (rawProps) {
|
||||
rawProps = normalizeRawProps(rawProps)
|
||||
if (rawProps || Object.keys(instance.attrs).length) {
|
||||
rawProps = [() => instance.attrs, ...normalizeRawProps(rawProps)]
|
||||
|
||||
renderEffect(() => {
|
||||
walkRawProps(rawProps as NormalizedRawProps, (key, value, getter) => {
|
||||
setDynamicProp(el, key, getter ? value() : value)
|
||||
})
|
||||
let classes: unknown[] | undefined
|
||||
let styles: unknown[] | undefined
|
||||
|
||||
walkRawProps(
|
||||
rawProps as NormalizedRawProps,
|
||||
(key, valueOrGetter, getter) => {
|
||||
const value = getter ? valueOrGetter() : valueOrGetter
|
||||
if (key === 'class') (classes ||= []).push(value)
|
||||
else if (key === 'style') (styles ||= []).push(value)
|
||||
else setDynamicProp(el, key, value)
|
||||
},
|
||||
)
|
||||
|
||||
if (classes) setClass(el, classes)
|
||||
if (styles) setStyle(el, styles)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -72,5 +89,9 @@ function fallbackComponent(
|
|||
}
|
||||
}
|
||||
|
||||
if (singleRoot) {
|
||||
setInheritAttrs(true)
|
||||
}
|
||||
|
||||
return el
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@ import {
|
|||
shallowReadonly,
|
||||
} from '@vue/reactivity'
|
||||
import { isArray, isFunction, isObject } from '@vue/shared'
|
||||
import { fallThroughAttrs } from './componentAttrs'
|
||||
import { VaporErrorCodes, callWithErrorHandling } from './errorHandling'
|
||||
import { endMeasure, startMeasure } from './profiling'
|
||||
import { devtoolsComponentAdded } from './devtools'
|
||||
import { fallThroughAttrs } from './componentAttrs'
|
||||
|
||||
export const fragmentKey: unique symbol = Symbol(__DEV__ ? `fragmentKey` : ``)
|
||||
|
||||
|
@ -86,9 +86,6 @@ export function setupComponent(instance: ComponentInternalInstance): void {
|
|||
resetTracking()
|
||||
}
|
||||
|
||||
if (block instanceof DocumentFragment) {
|
||||
block = Array.from(block.childNodes)
|
||||
}
|
||||
if (!block) {
|
||||
// TODO: warn no template
|
||||
block = []
|
||||
|
|
|
@ -174,6 +174,13 @@ export interface ComponentInternalInstance {
|
|||
emit: EmitFn
|
||||
emitted: Record<string, boolean> | null
|
||||
attrs: Data
|
||||
/**
|
||||
* - `undefined` : no props
|
||||
* - `false` : all props are static
|
||||
* - `string[]` : list of props are dynamic
|
||||
* - `true` : all props as dynamic
|
||||
*/
|
||||
dynamicAttrs?: string[] | boolean
|
||||
slots: StaticSlots
|
||||
refs: Data
|
||||
// exposed properties via expose()
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { camelize, isArray } from '@vue/shared'
|
||||
import { camelize, isArray, normalizeClass, normalizeStyle } from '@vue/shared'
|
||||
import { type ComponentInternalInstance, currentInstance } from './component'
|
||||
import { isEmitListener } from './componentEmits'
|
||||
import { setDynamicProps } from './dom/prop'
|
||||
import { type RawProps, walkRawProps } from './componentProps'
|
||||
import { renderEffect } from './renderEffect'
|
||||
import { mergeProp, setDynamicProp } from './dom/prop'
|
||||
|
||||
export function patchAttrs(instance: ComponentInternalInstance): void {
|
||||
export function patchAttrs(
|
||||
instance: ComponentInternalInstance,
|
||||
hasDynamicProps?: boolean,
|
||||
): void {
|
||||
const {
|
||||
attrs,
|
||||
rawProps,
|
||||
|
@ -14,6 +17,8 @@ export function patchAttrs(instance: ComponentInternalInstance): void {
|
|||
|
||||
if (!rawProps.length) return
|
||||
const keys = new Set<string>()
|
||||
const classes: any[] = []
|
||||
const styles: any[] = []
|
||||
|
||||
walkRawProps(rawProps, registerAttr)
|
||||
for (const key in attrs) {
|
||||
|
@ -22,14 +27,42 @@ export function patchAttrs(instance: ComponentInternalInstance): void {
|
|||
}
|
||||
}
|
||||
|
||||
setClassOrStyle(classes, 'class', normalizeClass)
|
||||
setClassOrStyle(styles, 'style', normalizeStyle)
|
||||
|
||||
function setClassOrStyle(
|
||||
values: any[],
|
||||
field: 'class' | 'style',
|
||||
normalize: (value: any) => any,
|
||||
) {
|
||||
if (values.length) {
|
||||
if (hasDynamicProps) {
|
||||
Object.defineProperty(attrs, field, {
|
||||
get() {
|
||||
return normalize(values.map(value => value()))
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
})
|
||||
} else {
|
||||
attrs[field] = normalizeClass(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerAttr(key: string, value: any, getter?: boolean) {
|
||||
if (
|
||||
(!options || !(camelize(key) in options)) &&
|
||||
!isEmitListener(instance.emitsOptions, key) &&
|
||||
!keys.has(key)
|
||||
(key === 'class' || key === 'style' || !keys.has(key))
|
||||
) {
|
||||
keys.add(key)
|
||||
if (getter) {
|
||||
|
||||
if (key === 'class' || key === 'style') {
|
||||
;(key === 'class' ? classes : styles).push(
|
||||
hasDynamicProps ? (getter ? value : () => value) : value,
|
||||
)
|
||||
} else if (getter) {
|
||||
Object.defineProperty(attrs, key, {
|
||||
get: value,
|
||||
enumerable: true,
|
||||
|
@ -57,16 +90,47 @@ export function fallThroughAttrs(instance: ComponentInternalInstance): void {
|
|||
const {
|
||||
block,
|
||||
type: { inheritAttrs },
|
||||
dynamicAttrs,
|
||||
} = instance
|
||||
if (inheritAttrs === false) return
|
||||
if (
|
||||
inheritAttrs === false ||
|
||||
!(block instanceof Element) ||
|
||||
// all props as dynamic
|
||||
dynamicAttrs === true
|
||||
)
|
||||
return
|
||||
|
||||
if (block instanceof Element) {
|
||||
const hasStaticAttrs = dynamicAttrs || dynamicAttrs === false
|
||||
|
||||
let initial: Record<string, string> | undefined
|
||||
if (hasStaticAttrs) {
|
||||
// attrs in static template
|
||||
const initial: Record<string, string> = {}
|
||||
initial = {}
|
||||
for (let i = 0; i < block.attributes.length; i++) {
|
||||
const attr = block.attributes[i]
|
||||
if (dynamicAttrs && dynamicAttrs.includes(attr.name)) continue
|
||||
initial[attr.name] = attr.value
|
||||
}
|
||||
renderEffect(() => setDynamicProps(block, instance.attrs, initial))
|
||||
}
|
||||
|
||||
renderEffect(() => {
|
||||
for (const key in instance.attrs) {
|
||||
if (dynamicAttrs && dynamicAttrs.includes(key)) continue
|
||||
|
||||
let value: unknown
|
||||
if (hasStaticAttrs) {
|
||||
value = mergeProp(key, instance.attrs[key], initial![key])
|
||||
} else {
|
||||
value = instance.attrs[key]
|
||||
}
|
||||
|
||||
setDynamicProp(block, key, value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function setInheritAttrs(dynamicAttrs?: string[] | boolean): void {
|
||||
const instance = currentInstance!
|
||||
if (instance.type.inheritAttrs === false) return
|
||||
instance.dynamicAttrs = dynamicAttrs
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ export function initProps(
|
|||
}
|
||||
|
||||
if (hasDynamicProps) {
|
||||
firstEffect(instance, () => patchAttrs(instance))
|
||||
firstEffect(instance, () => patchAttrs(instance, true))
|
||||
} else {
|
||||
patchAttrs(instance)
|
||||
}
|
||||
|
|
|
@ -18,9 +18,20 @@ import {
|
|||
} from '../componentMetadata'
|
||||
import { on } from './event'
|
||||
import type { Data } from '@vue/runtime-shared'
|
||||
import { currentInstance } from '../component'
|
||||
|
||||
export function mergeInheritAttr(key: string, value: any): unknown {
|
||||
const instance = currentInstance!
|
||||
return mergeProp(key, instance.attrs[key], value)
|
||||
}
|
||||
|
||||
export function setClass(el: Element, value: any, root?: boolean): void {
|
||||
const prev = recordPropMetadata(
|
||||
el,
|
||||
'class',
|
||||
(value = normalizeClass(root ? mergeInheritAttr('class', value) : value)),
|
||||
)
|
||||
|
||||
export function setClass(el: Element, value: any): void {
|
||||
const prev = recordPropMetadata(el, 'class', (value = normalizeClass(value)))
|
||||
if (value !== prev && (value || prev)) {
|
||||
el.className = value
|
||||
}
|
||||
|
@ -132,8 +143,15 @@ export function setDynamicProp(el: Element, key: string, value: any): void {
|
|||
}
|
||||
}
|
||||
|
||||
export function setDynamicProps(el: Element, ...args: any): void {
|
||||
export function setDynamicProps(
|
||||
el: Element,
|
||||
args: any[],
|
||||
root?: boolean,
|
||||
): void {
|
||||
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) {
|
||||
|
@ -153,32 +171,36 @@ export function setDynamicProps(el: Element, ...args: any): void {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO copied from runtime-core
|
||||
export function mergeProp(
|
||||
key: string,
|
||||
existing: unknown,
|
||||
incoming: unknown,
|
||||
): unknown {
|
||||
if (key === 'class') {
|
||||
if (existing !== incoming) {
|
||||
return normalizeClass([existing, incoming])
|
||||
}
|
||||
} else if (key === 'style') {
|
||||
return normalizeStyle([existing, incoming])
|
||||
} else if (isOn(key)) {
|
||||
if (
|
||||
incoming &&
|
||||
existing !== incoming &&
|
||||
!(isArray(existing) && existing.includes(incoming))
|
||||
) {
|
||||
return existing ? [].concat(existing as any, incoming as any) : incoming
|
||||
}
|
||||
}
|
||||
return incoming
|
||||
}
|
||||
|
||||
export function mergeProps(...args: Data[]): Data {
|
||||
const ret: Data = {}
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const toMerge = args[i]
|
||||
for (const key in toMerge) {
|
||||
if (key === 'class') {
|
||||
if (ret.class !== toMerge.class) {
|
||||
ret.class = normalizeClass([ret.class, toMerge.class])
|
||||
}
|
||||
} else if (key === 'style') {
|
||||
ret.style = normalizeStyle([ret.style, toMerge.style])
|
||||
} else if (isOn(key)) {
|
||||
const existing = ret[key]
|
||||
const incoming = toMerge[key]
|
||||
if (
|
||||
incoming &&
|
||||
existing !== incoming &&
|
||||
!(isArray(existing) && existing.includes(incoming))
|
||||
) {
|
||||
ret[key] = existing
|
||||
? [].concat(existing as any, incoming as any)
|
||||
: incoming
|
||||
}
|
||||
} else if (key !== '') {
|
||||
ret[key] = toMerge[key]
|
||||
if (key !== '') {
|
||||
ret[key] = mergeProp(key, ret[key], toMerge[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,14 @@ import {
|
|||
} from '@vue/shared'
|
||||
import { warn } from '../warning'
|
||||
import { recordPropMetadata } from '../componentMetadata'
|
||||
import { mergeInheritAttr } from './prop'
|
||||
|
||||
export function setStyle(el: HTMLElement, value: any): void {
|
||||
const prev = recordPropMetadata(el, 'style', (value = normalizeStyle(value)))
|
||||
export function setStyle(el: HTMLElement, value: any, root?: boolean): void {
|
||||
const prev = recordPropMetadata(
|
||||
el,
|
||||
'style',
|
||||
(value = normalizeStyle(root ? mergeInheritAttr('style', value) : value)),
|
||||
)
|
||||
patchStyle(el, prev, value)
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ export { createIf } from './apiCreateIf'
|
|||
export { createFor, createForSlots } from './apiCreateFor'
|
||||
export { createComponent } from './apiCreateComponent'
|
||||
export { createSelector } from './apiCreateSelector'
|
||||
export { setInheritAttrs } from './componentAttrs'
|
||||
|
||||
export {
|
||||
resolveComponent,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"vue": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5",
|
||||
"@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@481bcd4",
|
||||
"vite": "catalog:",
|
||||
"vite-hyper-config": "^0.4.0",
|
||||
"vite-plugin-inspect": "^0.8.7"
|
||||
|
|
|
@ -521,8 +521,8 @@ importers:
|
|||
version: link:../packages/vue
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5
|
||||
version: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)
|
||||
specifier: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4
|
||||
version: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)
|
||||
vite:
|
||||
specifier: 'catalog:'
|
||||
version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||
|
@ -1416,6 +1416,14 @@ packages:
|
|||
vite: ^5.0.0
|
||||
vue: ^3.2.25
|
||||
|
||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@481bcd4':
|
||||
resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4}
|
||||
version: 5.1.5
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
peerDependencies:
|
||||
vite: ^5.0.0
|
||||
vue: ^3.2.25
|
||||
|
||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5':
|
||||
resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5}
|
||||
version: 5.1.4
|
||||
|
@ -4495,16 +4503,16 @@ snapshots:
|
|||
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||
vue: link:packages/vue
|
||||
|
||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@481bcd4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)':
|
||||
dependencies:
|
||||
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||
vue: link:packages/vue
|
||||
|
||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@3.5.12(typescript@5.6.2))':
|
||||
dependencies:
|
||||
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||
vue: 3.5.12(typescript@5.6.2)
|
||||
|
||||
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)':
|
||||
dependencies:
|
||||
vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)
|
||||
vue: link:packages/vue
|
||||
|
||||
'@vitest/coverage-v8@2.1.1(vitest@2.1.1)':
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
|
|
Loading…
Reference in New Issue