mirror of https://github.com/vuejs/core.git
Merge 4d7a697734
into ba391f5fdf
This commit is contained in:
commit
7b5436e5dd
|
@ -33,6 +33,44 @@ describe('ssr: v-show', () => {
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('with component', () => {
|
||||||
|
expect(
|
||||||
|
compileWithWrapper(`<Foo :style="{color:'red'}" v-show="foo"/>`).code,
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
"const { resolveComponent: _resolveComponent } = require("vue")
|
||||||
|
const { ssrRenderComponent: _ssrRenderComponent, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
|
||||||
|
|
||||||
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
|
const _component_Foo = _resolveComponent("Foo")
|
||||||
|
|
||||||
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}>\`)
|
||||||
|
_push(_ssrRenderComponent(_component_Foo, { style: {color:'red'} }, null, _parent, undefined, {
|
||||||
|
style: (_ctx.foo) ? null : { display: "none" }
|
||||||
|
}))
|
||||||
|
_push(\`</div>\`)
|
||||||
|
}"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('with dynamic component', () => {
|
||||||
|
expect(
|
||||||
|
compileWithWrapper(
|
||||||
|
`<component is="Foo" :style="{color:'red'}" v-show="foo"/>`,
|
||||||
|
).code,
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
"const { resolveDynamicComponent: _resolveDynamicComponent, createVNode: _createVNode } = require("vue")
|
||||||
|
const { ssrRenderVNode: _ssrRenderVNode, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
|
||||||
|
|
||||||
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}>\`)
|
||||||
|
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("Foo"), { style: {color:'red'} }, null), _parent, undefined, {
|
||||||
|
style: (_ctx.foo) ? null : { display: "none" }
|
||||||
|
})
|
||||||
|
_push(\`</div>\`)
|
||||||
|
}"
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
test('with static style', () => {
|
test('with static style', () => {
|
||||||
expect(compileWithWrapper(`<div style="color:red" v-show="foo"/>`).code)
|
expect(compileWithWrapper(`<div style="color:red" v-show="foo"/>`).code)
|
||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
|
|
|
@ -30,6 +30,7 @@ import {
|
||||||
createCallExpression,
|
createCallExpression,
|
||||||
createFunctionExpression,
|
createFunctionExpression,
|
||||||
createIfStatement,
|
createIfStatement,
|
||||||
|
createObjectExpression,
|
||||||
createReturnStatement,
|
createReturnStatement,
|
||||||
createRoot,
|
createRoot,
|
||||||
createSimpleExpression,
|
createSimpleExpression,
|
||||||
|
@ -134,6 +135,17 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let vShowExp
|
||||||
|
const vShowDir = node.props.find(
|
||||||
|
p => p.type === NodeTypes.DIRECTIVE && p.name === 'show',
|
||||||
|
) as DirectiveNode | undefined
|
||||||
|
if (vShowDir) {
|
||||||
|
node.props = node.props.filter(p => p !== vShowDir)
|
||||||
|
const directiveTransform = context.directiveTransforms['show']
|
||||||
|
const { props } = directiveTransform!(vShowDir, node, context)
|
||||||
|
vShowExp = createObjectExpression(props)
|
||||||
|
}
|
||||||
|
|
||||||
let propsExp: string | JSChildNode = `null`
|
let propsExp: string | JSChildNode = `null`
|
||||||
if (node.props.length) {
|
if (node.props.length) {
|
||||||
// note we are not passing ssr: true here because for components, v-on
|
// note we are not passing ssr: true here because for components, v-on
|
||||||
|
@ -180,9 +192,7 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
|
||||||
// dynamic component that resolved to a `resolveDynamicComponent` call
|
// dynamic component that resolved to a `resolveDynamicComponent` call
|
||||||
// expression - since the resolved result may be a plain element (string)
|
// expression - since the resolved result may be a plain element (string)
|
||||||
// or a VNode, handle it with `renderVNode`.
|
// or a VNode, handle it with `renderVNode`.
|
||||||
node.ssrCodegenNode = createCallExpression(
|
const args: (string | JSChildNode)[] = [
|
||||||
context.helper(SSR_RENDER_VNODE),
|
|
||||||
[
|
|
||||||
`_push`,
|
`_push`,
|
||||||
createCallExpression(context.helper(CREATE_VNODE), [
|
createCallExpression(context.helper(CREATE_VNODE), [
|
||||||
component,
|
component,
|
||||||
|
@ -190,12 +200,23 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
|
||||||
slots,
|
slots,
|
||||||
]),
|
]),
|
||||||
`_parent`,
|
`_parent`,
|
||||||
],
|
]
|
||||||
|
if (vShowExp) args.push(`undefined`, vShowExp)
|
||||||
|
node.ssrCodegenNode = createCallExpression(
|
||||||
|
context.helper(SSR_RENDER_VNODE),
|
||||||
|
args,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
const args: (string | JSChildNode)[] = [
|
||||||
|
component,
|
||||||
|
propsExp,
|
||||||
|
slots,
|
||||||
|
`_parent`,
|
||||||
|
]
|
||||||
|
if (vShowExp) args.push(`undefined`, vShowExp)
|
||||||
node.ssrCodegenNode = createCallExpression(
|
node.ssrCodegenNode = createCallExpression(
|
||||||
context.helper(SSR_RENDER_COMPONENT),
|
context.helper(SSR_RENDER_COMPONENT),
|
||||||
[component, propsExp, slots, `_parent`],
|
args,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,38 @@ describe('ssr: directives', () => {
|
||||||
),
|
),
|
||||||
).toBe(`<div style="color:red;font-size:12;display:none;"></div>`)
|
).toBe(`<div style="color:red;font-size:12;display:none;"></div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('with component', async () => {
|
||||||
|
expect(
|
||||||
|
await renderToString(
|
||||||
|
createApp({
|
||||||
|
components: {
|
||||||
|
Foo: {
|
||||||
|
template: `<div><span v-bind="$attrs"></span></div>`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: () => ({ show: false }),
|
||||||
|
template: `<Foo v-show="show"/>`,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toBe(`<div style="display:none;"><span></span></div>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('with dynamic component', async () => {
|
||||||
|
expect(
|
||||||
|
await renderToString(
|
||||||
|
createApp({
|
||||||
|
components: {
|
||||||
|
Foo: {
|
||||||
|
template: `<div><span v-bind="$attrs"></span></div>`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: () => ({ show: false }),
|
||||||
|
template: `<component is="Foo" v-show="show"/>`,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toBe(`<div style="display:none;"><span></span></div>`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('template v-model', () => {
|
describe('template v-model', () => {
|
||||||
|
|
|
@ -13,10 +13,12 @@ export function ssrRenderComponent(
|
||||||
children: Slots | SSRSlots | null = null,
|
children: Slots | SSRSlots | null = null,
|
||||||
parentComponent: ComponentInternalInstance | null = null,
|
parentComponent: ComponentInternalInstance | null = null,
|
||||||
slotScopeId?: string,
|
slotScopeId?: string,
|
||||||
|
vShowValue?: Props,
|
||||||
): SSRBuffer | Promise<SSRBuffer> {
|
): SSRBuffer | Promise<SSRBuffer> {
|
||||||
return renderComponentVNode(
|
return renderComponentVNode(
|
||||||
createVNode(comp, props, children),
|
createVNode(comp, props, children),
|
||||||
parentComponent,
|
parentComponent,
|
||||||
slotScopeId,
|
slotScopeId,
|
||||||
|
vShowValue,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ export function renderComponentVNode(
|
||||||
vnode: VNode,
|
vnode: VNode,
|
||||||
parentComponent: ComponentInternalInstance | null = null,
|
parentComponent: ComponentInternalInstance | null = null,
|
||||||
slotScopeId?: string,
|
slotScopeId?: string,
|
||||||
|
vShowValue?: Props,
|
||||||
): SSRBuffer | Promise<SSRBuffer> {
|
): SSRBuffer | Promise<SSRBuffer> {
|
||||||
const instance = (vnode.component = createComponentInstance(
|
const instance = (vnode.component = createComponentInstance(
|
||||||
vnode,
|
vnode,
|
||||||
|
@ -116,15 +117,18 @@ export function renderComponentVNode(
|
||||||
})
|
})
|
||||||
// Note: error display is already done by the wrapped lifecycle hook function.
|
// Note: error display is already done by the wrapped lifecycle hook function.
|
||||||
.catch(NOOP)
|
.catch(NOOP)
|
||||||
return p.then(() => renderComponentSubTree(instance, slotScopeId))
|
return p.then(() =>
|
||||||
|
renderComponentSubTree(instance, slotScopeId, vShowValue),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return renderComponentSubTree(instance, slotScopeId)
|
return renderComponentSubTree(instance, slotScopeId, vShowValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderComponentSubTree(
|
function renderComponentSubTree(
|
||||||
instance: ComponentInternalInstance,
|
instance: ComponentInternalInstance,
|
||||||
slotScopeId?: string,
|
slotScopeId?: string,
|
||||||
|
vShowValue?: Props,
|
||||||
): SSRBuffer | Promise<SSRBuffer> {
|
): SSRBuffer | Promise<SSRBuffer> {
|
||||||
if (__DEV__) pushWarningContext(instance.vnode)
|
if (__DEV__) pushWarningContext(instance.vnode)
|
||||||
const comp = instance.type as Component
|
const comp = instance.type as Component
|
||||||
|
@ -186,6 +190,12 @@ function renderComponentSubTree(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vShowValue) {
|
||||||
|
// v-show has higher priority
|
||||||
|
if (attrs) attrs = mergeProps(attrs, vShowValue)
|
||||||
|
else attrs = vShowValue
|
||||||
|
}
|
||||||
|
|
||||||
// set current rendering instance for asset resolution
|
// set current rendering instance for asset resolution
|
||||||
const prev = setCurrentRenderingInstance(instance)
|
const prev = setCurrentRenderingInstance(instance)
|
||||||
try {
|
try {
|
||||||
|
@ -225,6 +235,7 @@ export function renderVNode(
|
||||||
vnode: VNode,
|
vnode: VNode,
|
||||||
parentComponent: ComponentInternalInstance,
|
parentComponent: ComponentInternalInstance,
|
||||||
slotScopeId?: string,
|
slotScopeId?: string,
|
||||||
|
vShowValue?: Props,
|
||||||
): void {
|
): void {
|
||||||
const { type, shapeFlag, children, dirs, props } = vnode
|
const { type, shapeFlag, children, dirs, props } = vnode
|
||||||
if (dirs) {
|
if (dirs) {
|
||||||
|
@ -263,7 +274,9 @@ export function renderVNode(
|
||||||
if (shapeFlag & ShapeFlags.ELEMENT) {
|
if (shapeFlag & ShapeFlags.ELEMENT) {
|
||||||
renderElementVNode(push, vnode, parentComponent, slotScopeId)
|
renderElementVNode(push, vnode, parentComponent, slotScopeId)
|
||||||
} else if (shapeFlag & ShapeFlags.COMPONENT) {
|
} else if (shapeFlag & ShapeFlags.COMPONENT) {
|
||||||
push(renderComponentVNode(vnode, parentComponent, slotScopeId))
|
push(
|
||||||
|
renderComponentVNode(vnode, parentComponent, slotScopeId, vShowValue),
|
||||||
|
)
|
||||||
} else if (shapeFlag & ShapeFlags.TELEPORT) {
|
} else if (shapeFlag & ShapeFlags.TELEPORT) {
|
||||||
renderTeleportVNode(push, vnode, parentComponent, slotScopeId)
|
renderTeleportVNode(push, vnode, parentComponent, slotScopeId)
|
||||||
} else if (shapeFlag & ShapeFlags.SUSPENSE) {
|
} else if (shapeFlag & ShapeFlags.SUSPENSE) {
|
||||||
|
|
Loading…
Reference in New Issue