', () => {
}"
`)
})
+
+ 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 9b0f1dd48..45d1c1754 100644
--- a/packages/compiler-ssr/package.json
+++ b/packages/compiler-ssr/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-ssr",
- "version": "3.4.0",
+ "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 b75b4d033..ad08a23a4 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/dts-test/watch.test-d.ts b/packages/dts-test/watch.test-d.ts
index 323716d8a..5986d3d30 100644
--- a/packages/dts-test/watch.test-d.ts
+++ b/packages/dts-test/watch.test-d.ts
@@ -1,4 +1,11 @@
-import { computed, defineComponent, ref, shallowRef, watch } from 'vue'
+import {
+ computed,
+ defineComponent,
+ defineModel,
+ ref,
+ shallowRef,
+ watch,
+} from 'vue'
import { expectType } from './utils'
const source = ref('foo')
@@ -106,3 +113,31 @@ defineComponent({
expectType(value)
})
}
+
+{
+ // defineModel
+ const bool = defineModel({ default: false })
+ watch(bool, value => {
+ expectType(value)
+ })
+
+ const bool1 = defineModel()
+ watch(bool1, value => {
+ expectType(value)
+ })
+
+ const msg = defineModel({ required: true })
+ watch(msg, value => {
+ expectType(value)
+ })
+
+ const arr = defineModel({ required: true })
+ watch(arr, value => {
+ expectType(value)
+ })
+
+ const obj = defineModel<{ foo: string }>({ required: true })
+ watch(obj, value => {
+ expectType<{ foo: string }>(value)
+ })
+}
diff --git a/packages/reactivity/package.json b/packages/reactivity/package.json
index 981cf8eba..7d6a792b1 100644
--- a/packages/reactivity/package.json
+++ b/packages/reactivity/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/reactivity",
- "version": "3.4.0",
+ "version": "3.4.2",
"description": "@vue/reactivity",
"main": "index.js",
"module": "dist/reactivity.esm-bundler.js",
diff --git a/packages/runtime-core/__tests__/apiSetupHelpers.spec.ts b/packages/runtime-core/__tests__/apiSetupHelpers.spec.ts
index 0528a1457..b50da90d4 100644
--- a/packages/runtime-core/__tests__/apiSetupHelpers.spec.ts
+++ b/packages/runtime-core/__tests__/apiSetupHelpers.spec.ts
@@ -279,6 +279,41 @@ describe('SFC