diff --git a/CHANGELOG.md b/CHANGELOG.md index be105cbfcdb..e10e5632c04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [3.4.2](https://github.com/vuejs/core/compare/v3.4.1...v3.4.2) (2023-12-30) + + +### Bug Fixes + +* **compiler-sfc:** fix dev regression for dot / namespace component usage ([dce99c1](https://github.com/vuejs/core/commit/dce99c12df981ca45a4d848c37ba8b16496025f0)), closes [#9947](https://github.com/vuejs/core/issues/9947) +* **runtime-core:** support deep: false when watch reactive ([#9928](https://github.com/vuejs/core/issues/9928)) ([4f703d1](https://github.com/vuejs/core/commit/4f703d120d76d711084346f73ea295c73e6ef6b6)), closes [#9916](https://github.com/vuejs/core/issues/9916) +* **ssr:** fix hydration error for slot outlet inside transition-group ([#9937](https://github.com/vuejs/core/issues/9937)) ([6cb00ed](https://github.com/vuejs/core/commit/6cb00ed0f9b64428ec18fada0f68467d6a813fde)), closes [#9933](https://github.com/vuejs/core/issues/9933) + + + ## [3.4.1](https://github.com/vuejs/core/compare/v3.4.0...v3.4.1) (2023-12-30) diff --git a/package.json b/package.json index 70da20ed52e..add8eab6e21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "3.4.1", + "version": "3.4.2", "packageManager": "pnpm@8.12.1", "type": "module", "scripts": { diff --git a/packages/compiler-core/package.json b/packages/compiler-core/package.json index 0aed4be6ef7..4bd35266fed 100644 --- a/packages/compiler-core/package.json +++ b/packages/compiler-core/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-core", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/compiler-core", "main": "index.js", "module": "dist/compiler-core.esm-bundler.js", diff --git a/packages/compiler-dom/package.json b/packages/compiler-dom/package.json index 95912165b37..1d56d6fdff0 100644 --- a/packages/compiler-dom/package.json +++ b/packages/compiler-dom/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-dom", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/compiler-dom", "main": "index.js", "module": "dist/compiler-dom.esm-bundler.js", diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap index a2d24599cfa..d63e6ec4d40 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap @@ -639,190 +639,6 @@ return { foo, bar, baz, y, z } }" `; -exports[`SFC compile - - `) - // FooBar: should not be matched by plain text or incorrect case - // FooBaz: used as PascalCase component - // FooQux: used as kebab-case component - // foo: lowercase component - expect(content).toMatch( - `return { fooBar, get FooBaz() { return FooBaz }, ` + - `get FooQux() { return FooQux }, get foo() { return foo } }`, - ) - assertCode(content) - }) - - test('directive', () => { - const { content } = compile(` - - - `) - expect(content).toMatch(`return { get vMyDir() { return vMyDir } }`) - assertCode(content) - }) - - test('dynamic arguments', () => { - const { content } = compile(` - - - `) - expect(content).toMatch( - `return { get FooBar() { return FooBar }, get foo() { return foo }, ` + - `get bar() { return bar }, get baz() { return baz } }`, - ) - assertCode(content) - }) - - // https://github.com/vuejs/core/issues/4599 - test('attribute expressions', () => { - const { content } = compile(` - - - `) - expect(content).toMatch( - `return { cond, get bar() { return bar }, get baz() { return baz } }`, - ) - assertCode(content) - }) - - test('vue interpolations', () => { - const { content } = compile(` - - - `) - // x: used in interpolation - // y: should not be matched by {{ yy }} or 'y' in binding exps - // x$y: #4274 should escape special chars when creating Regex - expect(content).toMatch( - `return { get x() { return x }, get z() { return z }, get x$y() { return x$y } }`, - ) - assertCode(content) - }) - - // #4340 interpolations in template strings - test('js template string interpolations', () => { - const { content } = compile(` - - - `) - // VAR2 should not be matched - expect(content).toMatch( - `return { get VAR() { return VAR }, get VAR3() { return VAR3 } }`, - ) - assertCode(content) - }) - - // edge case: last tag in template - test('last tag', () => { - const { content } = compile(` - - - `) - expect(content).toMatch( - `return { get FooBaz() { return FooBaz }, get Last() { return Last } }`, - ) - assertCode(content) - }) - - test('TS annotations', () => { - const { content } = compile(` - - - `) - expect(content).toMatch(`return { a, b, get Baz() { return Baz } }`) - assertCode(content) - }) - - // vuejs/vue#12591 - test('v-on inline statement', () => { - // should not error - compile(` - - - `) - }) - - test('template ref', () => { - const { content } = compile(` - - - `) - expect(content).toMatch( - 'return { get foo() { return foo }, get bar() { return bar }, get Baz() { return Baz } }', - ) - assertCode(content) - }) - - // https://github.com/nuxt/nuxt/issues/22416 - test('property access', () => { - const { content } = compile(` - - - `) - expect(content).toMatch('return { get Foo() { return Foo } }') - assertCode(content) - }) - - test('spread operator', () => { - const { content } = compile(` - - - `) - expect(content).toMatch('return { get Foo() { return Foo } }') - assertCode(content) - }) - - test('property access (whitespace)', () => { - const { content } = compile(` - - - `) - expect(content).toMatch('return { get Foo() { return Foo } }') - assertCode(content) - }) - }) - describe('inlineTemplate mode', () => { test('should work', () => { const { content } = compile( diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/importUsageCheck.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/importUsageCheck.spec.ts.snap new file mode 100644 index 00000000000..cfdbf5f45c2 --- /dev/null +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/importUsageCheck.spec.ts.snap @@ -0,0 +1,215 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`TS annotations 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { Foo, Bar, Baz, Qux, Fred } from './x' + const a = 1 + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + function b() {} + +return { a, b, get Baz() { return Baz } } +} + +})" +`; + +exports[`attribute expressions 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { bar, baz } from './x' + const cond = true + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { cond, get bar() { return bar }, get baz() { return baz } } +} + +})" +`; + +exports[`components 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { FooBar, FooBaz, FooQux, foo } from './x' + const fooBar: FooBar = 1 + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { fooBar, get FooBaz() { return FooBaz }, get FooQux() { return FooQux }, get foo() { return foo } } +} + +})" +`; + +exports[`directive 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { vMyDir } from './x' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get vMyDir() { return vMyDir } } +} + +})" +`; + +exports[`dynamic arguments 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { FooBar, foo, bar, unused, baz } from './x' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get FooBar() { return FooBar }, get foo() { return foo }, get bar() { return bar }, get baz() { return baz } } +} + +})" +`; + +exports[`import namespace 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import * as Foo from './foo' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get Foo() { return Foo } } +} + +})" +`; + +exports[`js template string interpolations 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { VAR, VAR2, VAR3 } from './x' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get VAR() { return VAR }, get VAR3() { return VAR3 } } +} + +})" +`; + +exports[`last tag 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { FooBaz, Last } from './x' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get FooBaz() { return FooBaz }, get Last() { return Last } } +} + +})" +`; + +exports[`namespace / dot component usage 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import * as Foo from './foo' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get Foo() { return Foo } } +} + +})" +`; + +exports[`property access (whitespace) 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { Foo, Bar, Baz } from './foo' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get Foo() { return Foo } } +} + +})" +`; + +exports[`property access 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { Foo, Bar, Baz } from './foo' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get Foo() { return Foo } } +} + +})" +`; + +exports[`spread operator 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { Foo, Bar, Baz } from './foo' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get Foo() { return Foo } } +} + +})" +`; + +exports[`template ref 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { foo, bar, Baz } from './foo' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get foo() { return foo }, get bar() { return bar }, get Baz() { return Baz } } +} + +})" +`; + +exports[`vue interpolations 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +import { x, y, z, x$y } from './x' + +export default /*#__PURE__*/_defineComponent({ + setup(__props, { expose: __expose }) { + __expose(); + + +return { get x() { return x }, get z() { return z }, get x$y() { return x$y } } +} + +})" +`; diff --git a/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts b/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts new file mode 100644 index 00000000000..d9fd1dfe529 --- /dev/null +++ b/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts @@ -0,0 +1,235 @@ +import { assertCode, compileSFCScript as compile } from '../utils' + +// in dev mode, declared bindings are returned as an object from setup() +// when using TS, users may import types which should not be returned as +// values, so we need to check import usage in the template to determine +// what to be returned. + +test('components', () => { + const { content } = compile(` + + + `) + // FooBar: should not be matched by plain text or incorrect case + // FooBaz: used as PascalCase component + // FooQux: used as kebab-case component + // foo: lowercase component + expect(content).toMatch( + `return { fooBar, get FooBaz() { return FooBaz }, ` + + `get FooQux() { return FooQux }, get foo() { return foo } }`, + ) + assertCode(content) +}) + +test('directive', () => { + const { content } = compile(` + + + `) + expect(content).toMatch(`return { get vMyDir() { return vMyDir } }`) + assertCode(content) +}) + +test('dynamic arguments', () => { + const { content } = compile(` + + + `) + expect(content).toMatch( + `return { get FooBar() { return FooBar }, get foo() { return foo }, ` + + `get bar() { return bar }, get baz() { return baz } }`, + ) + assertCode(content) +}) + +// https://github.com/vuejs/core/issues/4599 +test('attribute expressions', () => { + const { content } = compile(` + + + `) + expect(content).toMatch( + `return { cond, get bar() { return bar }, get baz() { return baz } }`, + ) + assertCode(content) +}) + +test('vue interpolations', () => { + const { content } = compile(` + + + `) + // x: used in interpolation + // y: should not be matched by {{ yy }} or 'y' in binding exps + // x$y: #4274 should escape special chars when creating Regex + expect(content).toMatch( + `return { get x() { return x }, get z() { return z }, get x$y() { return x$y } }`, + ) + assertCode(content) +}) + +// #4340 interpolations in template strings +test('js template string interpolations', () => { + const { content } = compile(` + + + `) + // VAR2 should not be matched + expect(content).toMatch( + `return { get VAR() { return VAR }, get VAR3() { return VAR3 } }`, + ) + assertCode(content) +}) + +// edge case: last tag in template +test('last tag', () => { + const { content } = compile(` + + + `) + expect(content).toMatch( + `return { get FooBaz() { return FooBaz }, get Last() { return Last } }`, + ) + assertCode(content) +}) + +test('TS annotations', () => { + const { content } = compile(` + + + `) + expect(content).toMatch(`return { a, b, get Baz() { return Baz } }`) + assertCode(content) +}) + +// vuejs/vue#12591 +test('v-on inline statement', () => { + // should not error + compile(` + + + `) +}) + +test('template ref', () => { + const { content } = compile(` + + + `) + expect(content).toMatch( + 'return { get foo() { return foo }, get bar() { return bar }, get Baz() { return Baz } }', + ) + assertCode(content) +}) + +// https://github.com/nuxt/nuxt/issues/22416 +test('property access', () => { + const { content } = compile(` + + + `) + expect(content).toMatch('return { get Foo() { return Foo } }') + assertCode(content) +}) + +test('spread operator', () => { + const { content } = compile(` + + + `) + expect(content).toMatch('return { get Foo() { return Foo } }') + assertCode(content) +}) + +test('property access (whitespace)', () => { + const { content } = compile(` + + + `) + expect(content).toMatch('return { get Foo() { return Foo } }') + assertCode(content) +}) + +// #9974 +test('namespace / dot component usage', () => { + const { content } = compile(` + + + `) + expect(content).toMatch('return { get Foo() { return Foo } }') + assertCode(content) +}) diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index 684ff4afdf6..ad85bed3e55 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-sfc", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/compiler-sfc", "main": "dist/compiler-sfc.cjs.js", "module": "dist/compiler-sfc.esm-browser.js", diff --git a/packages/compiler-sfc/src/script/importUsageCheck.ts b/packages/compiler-sfc/src/script/importUsageCheck.ts index 5ea11f9157f..211efc49089 100644 --- a/packages/compiler-sfc/src/script/importUsageCheck.ts +++ b/packages/compiler-sfc/src/script/importUsageCheck.ts @@ -16,12 +16,12 @@ import { camelize, capitalize, isBuiltInDirective } from '@vue/shared' * when not using inline mode. */ export function isImportUsed(local: string, sfc: SFCDescriptor): boolean { - return resolveTemplateUsageCheckString(sfc).has(local) + return resolveTemplateUsedIdentifiers(sfc).has(local) } const templateUsageCheckCache = createCache>() -function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { +function resolveTemplateUsedIdentifiers(sfc: SFCDescriptor): Set { const { content, ast } = sfc.template! const cached = templateUsageCheckCache.get(content) if (cached) { @@ -35,12 +35,14 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { function walk(node: TemplateChildNode) { switch (node.type) { case NodeTypes.ELEMENT: + let tag = node.tag + if (tag.includes('.')) tag = tag.split('.')[0].trim() if ( - !parserOptions.isNativeTag!(node.tag) && - !parserOptions.isBuiltInComponent!(node.tag) + !parserOptions.isNativeTag!(tag) && + !parserOptions.isBuiltInComponent!(tag) ) { - ids.add(camelize(node.tag)) - ids.add(capitalize(camelize(node.tag))) + ids.add(camelize(tag)) + ids.add(capitalize(camelize(tag))) } for (let i = 0; i < node.props.length; i++) { const prop = node.props[i] diff --git a/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts b/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts index 977cc8027d0..655d68efbbc 100644 --- a/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts @@ -127,4 +127,20 @@ describe('ssr: ', () => { }" `) }) + + test('inside transition-group', () => { + const { code } = compile( + ``, + ) + expect(code).toMatch(ssrHelpers[SSR_RENDER_SLOT_INNER]) + expect(code).toMatchInlineSnapshot(` + "const { ssrRenderSlotInner: _ssrRenderSlotInner, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer") + + return function ssrRender(_ctx, _push, _parent, _attrs) { + _push(\`\`) + _ssrRenderSlotInner(_ctx.$slots, "default", {}, null, _push, _parent, null, true) + _push(\`\`) + }" + `) + }) }) diff --git a/packages/compiler-ssr/package.json b/packages/compiler-ssr/package.json index 211504c7a9b..7dd9f551f1f 100644 --- a/packages/compiler-ssr/package.json +++ b/packages/compiler-ssr/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-ssr", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/compiler-ssr", "main": "dist/compiler-ssr.cjs.js", "types": "dist/compiler-ssr.d.ts", diff --git a/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts b/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts index b75b4d03366..ad08a23a445 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts @@ -4,6 +4,7 @@ import { NodeTypes, type SlotOutletNode, TRANSITION, + TRANSITION_GROUP, createCallExpression, createFunctionExpression, isSlotOutlet, @@ -37,16 +38,19 @@ export const ssrTransformSlotOutlet: NodeTransform = (node, context) => { let method = SSR_RENDER_SLOT - // #3989 + // #3989, #9933 // check if this is a single slot inside a transition wrapper - since - // transition will unwrap the slot fragment into a single vnode at runtime, + // transition/transition-group will unwrap the slot fragment into vnode(s) at runtime, // we need to avoid rendering the slot as a fragment. const parent = context.parent + let componentType if ( parent && parent.type === NodeTypes.ELEMENT && parent.tagType === ElementTypes.COMPONENT && - resolveComponentType(parent, context, true) === TRANSITION && + ((componentType = resolveComponentType(parent, context, true)) === + TRANSITION || + componentType === TRANSITION_GROUP) && parent.children.filter(c => c.type === NodeTypes.ELEMENT).length === 1 ) { method = SSR_RENDER_SLOT_INNER diff --git a/packages/reactivity/package.json b/packages/reactivity/package.json index acc43e932d6..d903c9edf35 100644 --- a/packages/reactivity/package.json +++ b/packages/reactivity/package.json @@ -1,6 +1,6 @@ { "name": "@vue/reactivity", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/reactivity", "main": "index.js", "module": "dist/reactivity.esm-bundler.js", diff --git a/packages/runtime-core/__tests__/apiWatch.spec.ts b/packages/runtime-core/__tests__/apiWatch.spec.ts index 3bc614ef9b7..b25635e664e 100644 --- a/packages/runtime-core/__tests__/apiWatch.spec.ts +++ b/packages/runtime-core/__tests__/apiWatch.spec.ts @@ -25,9 +25,11 @@ import { type DebuggerEvent, ITERATE_KEY, type Ref, + type ShallowRef, TrackOpTypes, TriggerOpTypes, effectScope, + shallowReactive, shallowRef, toRef, triggerRef, @@ -156,6 +158,59 @@ describe('api: watch', () => { expect(dummy).toBe(1) }) + it('directly watching reactive object with explicit deep: false', async () => { + const src = reactive({ + state: { + count: 0, + }, + }) + let dummy + watch( + src, + ({ state }) => { + dummy = state?.count + }, + { + deep: false, + }, + ) + + // nested should not trigger + src.state.count++ + await nextTick() + expect(dummy).toBe(undefined) + + // root level should trigger + src.state = { count: 1 } + await nextTick() + expect(dummy).toBe(1) + }) + + // #9916 + it('directly watching shallow reactive array', async () => { + class foo { + prop1: ShallowRef = shallowRef('') + prop2: string = '' + } + + const obj1 = new foo() + const obj2 = new foo() + + const collection = shallowReactive([obj1, obj2]) + const cb = vi.fn() + watch(collection, cb) + + collection[0].prop1.value = 'foo' + await nextTick() + // should not trigger + expect(cb).toBeCalledTimes(0) + + collection.push(new foo()) + await nextTick() + // should trigger on array self mutation + expect(cb).toBeCalledTimes(1) + }) + it('watching multiple sources', async () => { const state = reactive({ count: 1 }) const count = ref(1) diff --git a/packages/runtime-core/package.json b/packages/runtime-core/package.json index 9e8b20e6246..a5d6bb12bfe 100644 --- a/packages/runtime-core/package.json +++ b/packages/runtime-core/package.json @@ -1,6 +1,6 @@ { "name": "@vue/runtime-core", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/runtime-core", "main": "index.js", "module": "dist/runtime-core.esm-bundler.js", diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index a3cd3894f41..0c13e72988f 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -231,8 +231,11 @@ function doWatch( getter = () => source.value forceTrigger = isShallow(source) } else if (isReactive(source)) { - getter = () => source - deep = true + getter = + isShallow(source) || deep === false + ? () => traverse(source, 1) + : () => traverse(source) + forceTrigger = true } else if (isArray(source)) { isMultiSource = true forceTrigger = source.some(s => isReactive(s) || isShallow(s)) @@ -241,7 +244,7 @@ function doWatch( if (isRef(s)) { return s.value } else if (isReactive(s)) { - return traverse(s) + return traverse(s, isShallow(s) || deep === false ? 1 : undefined) } else if (isFunction(s)) { return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER) } else { @@ -460,28 +463,41 @@ export function createPathGetter(ctx: any, path: string) { } } -export function traverse(value: unknown, seen?: Set) { +export function traverse( + value: unknown, + depth?: number, + currentDepth = 0, + seen?: Set, +) { if (!isObject(value) || (value as any)[ReactiveFlags.SKIP]) { return value } + + if (depth && depth > 0) { + if (currentDepth >= depth) { + return value + } + currentDepth++ + } + seen = seen || new Set() if (seen.has(value)) { return value } seen.add(value) if (isRef(value)) { - traverse(value.value, seen) + traverse(value.value, depth, currentDepth, seen) } else if (isArray(value)) { for (let i = 0; i < value.length; i++) { - traverse(value[i], seen) + traverse(value[i], depth, currentDepth, seen) } } else if (isSet(value) || isMap(value)) { value.forEach((v: any) => { - traverse(v, seen) + traverse(v, depth, currentDepth, seen) }) } else if (isPlainObject(value)) { for (const key in value) { - traverse(value[key], seen) + traverse(value[key], depth, currentDepth, seen) } } return value diff --git a/packages/runtime-dom/package.json b/packages/runtime-dom/package.json index acd4760e2c2..23c92b225c1 100644 --- a/packages/runtime-dom/package.json +++ b/packages/runtime-dom/package.json @@ -1,6 +1,6 @@ { "name": "@vue/runtime-dom", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/runtime-dom", "main": "index.js", "module": "dist/runtime-dom.esm-bundler.js", diff --git a/packages/server-renderer/package.json b/packages/server-renderer/package.json index b41e757a27d..ee3cc84b936 100644 --- a/packages/server-renderer/package.json +++ b/packages/server-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@vue/server-renderer", - "version": "3.4.1", + "version": "3.4.2", "description": "@vue/server-renderer", "main": "index.js", "module": "dist/server-renderer.esm-bundler.js", diff --git a/packages/shared/package.json b/packages/shared/package.json index 97fdfb01fc1..7ddc6d58f6d 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@vue/shared", - "version": "3.4.1", + "version": "3.4.2", "description": "internal utils shared across @vue packages", "main": "index.js", "module": "dist/shared.esm-bundler.js", diff --git a/packages/vue-compat/package.json b/packages/vue-compat/package.json index 0020a1c7fed..017879cc718 100644 --- a/packages/vue-compat/package.json +++ b/packages/vue-compat/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compat", - "version": "3.4.1", + "version": "3.4.2", "description": "Vue 3 compatibility build for Vue 2", "main": "index.js", "module": "dist/vue.runtime.esm-bundler.js", diff --git a/packages/vue/package.json b/packages/vue/package.json index c0ec583c519..94b2f20c277 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "vue", - "version": "3.4.1", + "version": "3.4.2", "description": "The progressive JavaScript framework for building modern web UI.", "main": "index.js", "module": "dist/vue.runtime.esm-bundler.js",