mirror of https://github.com/vuejs/core.git
Merge 3003db2076
into ba391f5fdf
This commit is contained in:
commit
8cbff687e1
|
@ -1,5 +1,31 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`compiler: transform component slots > Properly handle v-for and ref on template 1`] = `
|
||||
"const _Vue = Vue
|
||||
|
||||
return function render(_ctx, _cache) {
|
||||
with (_ctx) {
|
||||
const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = _Vue
|
||||
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
|
||||
return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 2 /* DYNAMIC */ }, [
|
||||
_renderList(_ctx.list, (name) => {
|
||||
return {
|
||||
name: name,
|
||||
fn: _withCtx(() => [
|
||||
_createElementVNode("p", {
|
||||
ref_for: true,
|
||||
ref: "slotItems"
|
||||
}, _toDisplayString(name), 513 /* TEXT, NEED_PATCH */)
|
||||
])
|
||||
}
|
||||
})
|
||||
]), 1024 /* DYNAMIC_SLOTS */))
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: transform component slots > dynamically named slots 1`] = `
|
||||
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
|
||||
|
||||
|
|
|
@ -371,6 +371,39 @@ describe('compiler: transform component slots', () => {
|
|||
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('Properly handle v-for and ref on template', () => {
|
||||
const { root, slots } = parseWithSlots(
|
||||
`<Comp>
|
||||
<template v-for="name in list" #[name]><p ref="slotItems">{{name}}</p></template>
|
||||
</Comp>`,
|
||||
{ prefixIdentifiers: true },
|
||||
)
|
||||
|
||||
const spy = {
|
||||
type: NodeTypes.JS_PROPERTY,
|
||||
key: {
|
||||
constType: 3,
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'ref_for',
|
||||
isStatic: true,
|
||||
},
|
||||
value: {
|
||||
constType: 0,
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'true',
|
||||
isStatic: false,
|
||||
},
|
||||
}
|
||||
|
||||
const properties = (slots as any).arguments[1].elements[0].arguments[1]
|
||||
.returns.properties[1].value.returns[0].codegenNode.props.properties[0]
|
||||
expect(properties).toMatchObject(spy)
|
||||
expect((root as any).children[0].codegenNode.patchFlag).toMatch(
|
||||
PatchFlags.DYNAMIC_SLOTS + '',
|
||||
)
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('nested slots scoping', () => {
|
||||
const { root, slots } = parseWithSlots(
|
||||
`<Comp>
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
NodeTypes,
|
||||
type ObjectExpression,
|
||||
type Property,
|
||||
type RenderSlotCall,
|
||||
type SlotsExpression,
|
||||
type SourceLocation,
|
||||
type TemplateChildNode,
|
||||
|
@ -25,7 +26,9 @@ import { ErrorCodes, createCompilerError } from '../errors'
|
|||
import {
|
||||
assert,
|
||||
findDir,
|
||||
findProp,
|
||||
hasScopeRef,
|
||||
injectProp,
|
||||
isStaticExp,
|
||||
isTemplateNode,
|
||||
isVSlot,
|
||||
|
@ -258,6 +261,8 @@ export function buildSlots(
|
|||
const parseResult = vFor.forParseResult
|
||||
if (parseResult) {
|
||||
finalizeForParseResult(parseResult, context)
|
||||
// #8395
|
||||
injectRefFor(slotElement.children, context)
|
||||
// Render the dynamic slots as an array and add it to the createSlot()
|
||||
// args. The runtime knows how to handle it appropriately.
|
||||
dynamicSlots.push(
|
||||
|
@ -419,3 +424,19 @@ function isNonWhitespaceContent(node: TemplateChildNode): boolean {
|
|||
? !!node.content.trim()
|
||||
: isNonWhitespaceContent(node.content)
|
||||
}
|
||||
|
||||
function injectRefFor(
|
||||
children: TemplateChildNode[],
|
||||
context: TransformContext,
|
||||
) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i]
|
||||
if (child.type === NodeTypes.ELEMENT && findProp(child, 'ref')) {
|
||||
const Property = createObjectProperty(
|
||||
createSimpleExpression('ref_for', true),
|
||||
createSimpleExpression('true'),
|
||||
)
|
||||
injectProp(child.codegenNode as RenderSlotCall, Property, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue