import { createCodegenNodeForBranch } from './vIf'
import { validateBrowserExpression } from '../validateExpression'
import { cloneLoc } from '../parser'
+import { clone } from '@vue/shared'
export const transformSkip: NodeTransform = createStructuralDirectiveTransform(
'skip',
undefined,
true,
)
- // find default slot if not has dynamic slots
+ // find default slot without slot props if not has dynamic slots
if (!hasDynamicSlots && slots.type === NodeTypes.JS_OBJECT_EXPRESSION) {
processAsSkipNode = true
const prop = slots.properties.find(
p.value.params === undefined,
)
if (prop) {
- children = prop.value.returns as TemplateChildNode[]
+ const slotNode = prop.value.returns as TemplateChildNode[]
+ // clone the slot node to avoid mutating the original one, since it
+ // will be transformed again in ssr slot vnode fallback
+ children = context.inSSR ? clone(slotNode) : slotNode
} else {
context.onError(
createCompilerError(ErrorCodes.X_V_SKIP_UNEXPECTED_SLOT, loc),
`)
})
- test.todo('on component with implicit default slot + v-if', () => {
+ test('on component with implicit default slot + v-if', () => {
expect(
compile(
`<Comp v-skip="ok">
</Comp>`,
).code,
).toMatchInlineSnapshot(`
+ "const { withCtx: _withCtx, resolveComponent: _resolveComponent, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = require("vue")
+ const { ssrRenderComponent: _ssrRenderComponent } = require("vue/server-renderer")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ const _component_Comp = _resolveComponent("Comp")
+
+ if (_ctx.ok) {
+ _push(\`<!--[-->\`)
+ if (_ctx.yes) {
+ _push(\`<span>default</span>\`)
+ } else {
+ _push(\`<!---->\`)
+ }
+ _push(\`<!--]-->\`)
+ } else {
+ _push(_ssrRenderComponent(_component_Comp, _attrs, {
+ default: _withCtx((_, _push, _parent, _scopeId) => {
+ if (_push) {
+ if (_ctx.yes) {
+ _push(\`<span\${_scopeId}>default</span>\`)
+ } else {
+ _push(\`<!---->\`)
+ }
+ } else {
+ return [
+ (_ctx.yes)
+ ? (_openBlock(), _createBlock("span", { key: 0 }, "default"))
+ : _createCommentVNode("v-if", true)
+ ]
+ }
+ }),
+ _: 1 /* STABLE */
+ }, _parent))
+ }
+ }"
`)
})
ssrProcessTransitionGroup,
ssrTransformTransitionGroup,
} from './ssrTransformTransitionGroup'
-import { extend, isArray, isObject, isPlainObject, isSymbol } from '@vue/shared'
+import { clone, extend, isObject, isSymbol } from '@vue/shared'
import { buildSSRProps } from './ssrTransformElement'
import {
ssrProcessTransition,
// node/client branches
// - hoists are not enabled for the client branch here
}
-
-function clone(v: any): any {
- if (isArray(v)) {
- return v.map(clone)
- } else if (isPlainObject(v)) {
- const res: any = {}
- for (const key in v) {
- res[key] = clone(v[key as keyof typeof v])
- }
- return res
- } else {
- return v
- }
-}
)
)
}
+
+export function clone(v: any): any {
+ if (isArray(v)) {
+ return v.map(clone)
+ } else if (isPlainObject(v)) {
+ const res: any = {}
+ for (const key in v) {
+ res[key] = clone(v[key as keyof typeof v])
+ }
+ return res
+ } else {
+ return v
+ }
+}