]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(vapor): merge inherited attrs with current attrs
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Thu, 14 Nov 2024 12:01:10 +0000 (20:01 +0800)
committer三咲智子 Kevin Deng <sxzz@sxzz.moe>
Thu, 14 Nov 2024 12:21:20 +0000 (20:21 +0800)
33 files changed:
package.json
packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
packages/compiler-vapor/__tests__/transforms/transformTemplateRef.spec.ts
packages/compiler-vapor/__tests__/transforms/vBind.spec.ts
packages/compiler-vapor/__tests__/transforms/vHtml.spec.ts
packages/compiler-vapor/__tests__/transforms/vOn.spec.ts
packages/compiler-vapor/__tests__/transforms/vOnce.spec.ts
packages/compiler-vapor/__tests__/transforms/vText.spec.ts
packages/compiler-vapor/src/generators/component.ts
packages/compiler-vapor/src/generators/expression.ts
packages/compiler-vapor/src/generators/operation.ts
packages/compiler-vapor/src/generators/prop.ts
packages/compiler-vapor/src/generators/utils.ts
packages/compiler-vapor/src/ir/index.ts
packages/compiler-vapor/src/transforms/transformElement.ts
packages/runtime-vapor/__tests__/apiSetupContext.spec.ts
packages/runtime-vapor/__tests__/componentAttrs.spec.ts
packages/runtime-vapor/__tests__/dom/prop.spec.ts
packages/runtime-vapor/src/apiCreateComponent.ts
packages/runtime-vapor/src/apiRender.ts
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/componentAttrs.ts
packages/runtime-vapor/src/componentProps.ts
packages/runtime-vapor/src/dom/prop.ts
packages/runtime-vapor/src/dom/style.ts
packages/runtime-vapor/src/index.ts
playground/package.json
pnpm-lock.yaml

index b1338f9866137bbd173808c125b2188091bdbbaf..b1ffb9401686737b9ef2b857ffdda6a04c95a55c 100644 (file)
@@ -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",
index 7d0eca13fa302289fbcc8f9e13018ff89505df49..067610dc71e04f19f659cb56d54b376199179b99 100644 (file)
@@ -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
 })()"
 `;
index 8e4509e196a142efafc571ae044561e4dd316e2b..d06052b81309a7da34bfc566fd54db2e0abfcfc7 100644 (file)
@@ -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
 }"
 `;
index 16cbc20664367c760aa5848cd3d7e8d2768e5fff..5e1e43c88d37374d6afcc26a38171b018122b13e 100644 (file)
 // 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
 }"
 `;
index 5aec9a164986b38c87a07ac3a8bdbfd444d20364..87bc349f41038efd6a94286e88b0d3f9cfc7528f 100644 (file)
@@ -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
 }"
 `;
index 1c382d8be64e31fbe5502071e738b675b8d7104a..70c9e35ab91c0c7f1b46623af4d2d93ffe72f552 100644 (file)
@@ -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
 }"
 `;
index dacfab9825ad940beaabf406a11067383281b321..2b5f894645612113fa4ce9e1b02995006821512f 100644 (file)
@@ -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,
+      },
     ])
   })
 
index 22f68f9533ae808c1c618e8897e62e12ccf841f7..b9adeb51e41c4130086a9dbdd8e9e954679ad847 100644 (file)
@@ -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,
index 39b02a5e408122848a6cd69188a17163537f33e9..0097d0b7ca9fd2ab7292ae673531a6b2d2872650 100644 (file)
@@ -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)')
   })
 })
index 612016107ae18532f5a0d857f72a8026ebf29617..d66c9df574fd02ed85ca964163a40131c6989f2d 100644 (file)
@@ -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: [
index d8794b6028da887206163a0cd350053c95cc9268..3c74c197190399f7344d57bbf1ff7af4b540e832 100644 (file)
@@ -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,
+      },
     ])
   })
 })
index 19c306aaa5fbc3a03ac01d15872c9c694f2e9abb..f3f8679b480abf6ea8a6ae2b8b98d2d9e5d25f87 100644 (file)
@@ -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')
index 7bd2c07771d8adbbd1c3f596d8cca9f4df4321c0..4542da09b8f27c80e002f796b994fae0a0d64a2d 100644 (file)
@@ -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([
       {
index a0df807902aec4efad4bb8f61110f287ae4845ea..d936a634070e16af9a1ad485444687f7bb07f9af 100644 (file)
@@ -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)]
       : []),
index fee6cc18aaa5ef361b727b9d47403072cf05946a..ad40584652cc2777c309318b5af429c9fa1c1a2b 100644 (file)
@@ -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:
index 244de2ad3d54b040f27c130392e71772f47da077..b637e797a83a36c45bb70ebd97b9a1b0beb74632 100644 (file)
@@ -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 []
index 3b6a441828662f9c28ce995566e5d6d3c02b3513..120aa3733d988264f7f7a79028f29872dd048d18 100644 (file)
@@ -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)]
+}
index 9f3b8ad2ecbee46ea5c55e1a4f2331e61d754156..f001d8e928b9f50927f2c6c1ffdd49d5eab77a38 100644 (file)
@@ -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)
index 0b0b87fc4b037768af7c48c49e660e0508ffd18a..8b887e9249fc45ad654a200f52eec683eab81c4a 100644 (file)
@@ -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
index fd64e84a1f8c5b593611630cb1243fff5a3fd30d..c894c724b6c2f37485720f4d93c8fcfe35bd4d20 100644 (file)
@@ -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)) {
index 7bee76beb25e4412c8b811b9cb597617866ae66b..947e7042159f250bc3a97d11f58f4810e0cf7352 100644 (file)
@@ -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
       },
     })
 
index 18effd8e07d6caa3b0071541c759b85e7afb70fc..d66474559374ea87b7d24642d8073eff511ef092 100644 (file)
@@ -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
       },
index ab5a3d4e63b49c437c0d4a6a247609088cb4a6ba..7ccb1f51ee3b37c0889aadaaf1dcda62967ca603 100644 (file)
@@ -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()
index 7b91988329c081e37bc769e0c37b0dc493108b0d..cb7580038165089c12cfe1ea709801cd4fe15389 100644 (file)
@@ -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
 }
index 7dd97193efded52812705cd74a133990d098865b..751a92c05674aeaf7cd7b2eff5b641500b7b9256 100644 (file)
@@ -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 = []
index ca0cb7fa04f7e6a54b5f2de2d73b7a1fec797544..fdfcd55f06c530d336632196f1c0ac9d2c088e16 100644 (file)
@@ -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()
index 53f951299a9f530a302df1e6af81a82efa273270..ce0ad86ca475c28d8b8d379727aa63e72b2365bd 100644 (file)
@@ -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
 }
index 6e23328812449091a475d8da19bc3ce781c3a02f..1fb8d79f681e5ec9996f50cf21e5e122585131de 100644 (file)
@@ -116,7 +116,7 @@ export function initProps(
   }
 
   if (hasDynamicProps) {
-    firstEffect(instance, () => patchAttrs(instance))
+    firstEffect(instance, () => patchAttrs(instance, true))
   } else {
     patchAttrs(instance)
   }
index 411533722e65a8e28b140f47e6ada5ec8b486029..48d95173ec61816c7a87328da15d0eda5fd24972 100644 (file)
@@ -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])
       }
     }
   }
index b7ecfa53cb0bdd923137732d8d012711cc5e46de..5ee233a0cdbd465f26c665ff3bcad6586fa24707 100644 (file)
@@ -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)
 }
 
index 0a652b2081dc05c76d2e7a54d5462c495c7d632a..f1d77f2ee8f16acce487102a2b10b063815f7733 100644 (file)
@@ -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,
index 8c28097d54f595609ce1f8afe1134f2bef060ecf..c3e21f038fef9f501cfaa31355401e1701987927 100644 (file)
@@ -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"
index 45a506edaaf1997f5f2a6705f3d40f8b727da203..37f7290fd3c25f97e401bcbf0ddfcd5fada6800b 100644 (file)
@@ -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,15 +4503,15 @@ 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@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))':
+  '@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: 3.5.12(typescript@5.6.2)
+      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@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: link:packages/vue
+      vue: 3.5.12(typescript@5.6.2)
 
   '@vitest/coverage-v8@2.1.1(vitest@2.1.1)':
     dependencies: