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
|
// 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`] = `
|
exports[`compiler: transform component slots > dynamically named slots 1`] = `
|
||||||
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
|
"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()
|
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', () => {
|
test('nested slots scoping', () => {
|
||||||
const { root, slots } = parseWithSlots(
|
const { root, slots } = parseWithSlots(
|
||||||
`<Comp>
|
`<Comp>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
type ObjectExpression,
|
type ObjectExpression,
|
||||||
type Property,
|
type Property,
|
||||||
|
type RenderSlotCall,
|
||||||
type SlotsExpression,
|
type SlotsExpression,
|
||||||
type SourceLocation,
|
type SourceLocation,
|
||||||
type TemplateChildNode,
|
type TemplateChildNode,
|
||||||
|
@ -25,7 +26,9 @@ import { ErrorCodes, createCompilerError } from '../errors'
|
||||||
import {
|
import {
|
||||||
assert,
|
assert,
|
||||||
findDir,
|
findDir,
|
||||||
|
findProp,
|
||||||
hasScopeRef,
|
hasScopeRef,
|
||||||
|
injectProp,
|
||||||
isStaticExp,
|
isStaticExp,
|
||||||
isTemplateNode,
|
isTemplateNode,
|
||||||
isVSlot,
|
isVSlot,
|
||||||
|
@ -258,6 +261,8 @@ export function buildSlots(
|
||||||
const parseResult = vFor.forParseResult
|
const parseResult = vFor.forParseResult
|
||||||
if (parseResult) {
|
if (parseResult) {
|
||||||
finalizeForParseResult(parseResult, context)
|
finalizeForParseResult(parseResult, context)
|
||||||
|
// #8395
|
||||||
|
injectRefFor(slotElement.children, context)
|
||||||
// Render the dynamic slots as an array and add it to the createSlot()
|
// Render the dynamic slots as an array and add it to the createSlot()
|
||||||
// args. The runtime knows how to handle it appropriately.
|
// args. The runtime knows how to handle it appropriately.
|
||||||
dynamicSlots.push(
|
dynamicSlots.push(
|
||||||
|
@ -419,3 +424,19 @@ function isNonWhitespaceContent(node: TemplateChildNode): boolean {
|
||||||
? !!node.content.trim()
|
? !!node.content.trim()
|
||||||
: isNonWhitespaceContent(node.content)
|
: 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