diff --git a/src/core/vdom/helpers/normalize-scoped-slots.js b/src/core/vdom/helpers/normalize-scoped-slots.js
index a9c1bae8bf6..cc0348f6550 100644
--- a/src/core/vdom/helpers/normalize-scoped-slots.js
+++ b/src/core/vdom/helpers/normalize-scoped-slots.js
@@ -60,8 +60,10 @@ function normalizeScopedSlot(normalSlots, key, fn) {
res = res && typeof res === 'object' && !Array.isArray(res)
? [res] // single vnode
: normalizeChildren(res)
- return res && res.length === 0
- ? undefined
+ return res && (
+ res.length === 0 ||
+ (res.length === 1 && res[0].isComment) // #9658
+ ) ? undefined
: res
}
// this is a slot using the new v-slot syntax without scope. although it is
diff --git a/test/unit/features/component/component-scoped-slot.spec.js b/test/unit/features/component/component-scoped-slot.spec.js
index ae86dd96ee8..8960d8bf8c5 100644
--- a/test/unit/features/component/component-scoped-slot.spec.js
+++ b/test/unit/features/component/component-scoped-slot.spec.js
@@ -1264,4 +1264,17 @@ describe('Component scoped slot', () => {
expect(vm.$el.textContent).toMatch(`Content:ok`)
}).then(done)
})
+
+ //#9658
+ it('fallback for scoped slot with single v-if', () => {
+ const vm = new Vue({
+ template: `