Skip to content

Commit ecd7ce6

Browse files
committed
feat(compiler-core): wrap slot functions with render context
1 parent bcb750b commit ecd7ce6

File tree

13 files changed

+114
-88
lines changed

13 files changed

+114
-88
lines changed

packages/compiler-core/__tests__/__snapshots__/scopeId.spec.ts.snap

+8-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const render = _withId(function render(_ctx, _cache) {
1919
`;
2020

2121
exports[`scopeId compiler support should wrap default slot 1`] = `
22-
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
22+
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
2323
const _withId = _withScopeId(\\"test\\")
2424
2525
export const render = _withId(function render(_ctx, _cache) {
@@ -28,14 +28,14 @@ export const render = _withId(function render(_ctx, _cache) {
2828
return (_openBlock(), _createBlock(_component_Child, null, {
2929
default: _withId(() => [
3030
_createVNode(\\"div\\")
31-
]),
31+
], _ctx),
3232
_: 1
3333
}))
3434
})"
3535
`;
3636

3737
exports[`scopeId compiler support should wrap dynamic slots 1`] = `
38-
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
38+
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
3939
const _withId = _withScopeId(\\"test\\")
4040
4141
export const render = _withId(function render(_ctx, _cache) {
@@ -47,23 +47,23 @@ export const render = _withId(function render(_ctx, _cache) {
4747
name: \\"foo\\",
4848
fn: _withId(() => [
4949
_createVNode(\\"div\\")
50-
])
50+
], _ctx)
5151
}
5252
: undefined,
5353
_renderList(_ctx.list, (i) => {
5454
return {
5555
name: i,
5656
fn: _withId(() => [
5757
_createVNode(\\"div\\")
58-
])
58+
], _ctx)
5959
}
6060
})
6161
]), 1024 /* DYNAMIC_SLOTS */))
6262
})"
6363
`;
6464

6565
exports[`scopeId compiler support should wrap named slots 1`] = `
66-
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
66+
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
6767
const _withId = _withScopeId(\\"test\\")
6868
6969
export const render = _withId(function render(_ctx, _cache) {
@@ -72,10 +72,10 @@ export const render = _withId(function render(_ctx, _cache) {
7272
return (_openBlock(), _createBlock(_component_Child, null, {
7373
foo: _withId(({ msg }) => [
7474
_createTextVNode(_toDisplayString(msg), 1 /* TEXT */)
75-
]),
75+
], _ctx),
7676
bar: _withId(() => [
7777
_createVNode(\\"div\\")
78-
]),
78+
], _ctx),
7979
_: 1
8080
}))
8181
})"

packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap

+3-3
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,14 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expr
239239
240240
return function render(_ctx, _cache) {
241241
with (_ctx) {
242-
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
242+
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
243243
244244
const _component_Comp = _resolveComponent(\\"Comp\\")
245245
246246
return (_openBlock(), _createBlock(_component_Comp, null, {
247-
default: ({ foo }) => [
247+
default: _withCtx(({ foo }) => [
248248
_createTextVNode(_toDisplayString(_ctx.foo), 1 /* TEXT */)
249-
],
249+
], _ctx),
250250
_: 1
251251
}))
252252
}

packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap

+29-29
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`compiler: transform component slots dynamically named slots 1`] = `
4-
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
4+
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
55
66
return function render(_ctx, _cache) {
77
const _component_Comp = _resolveComponent(\\"Comp\\")
88
99
return (_openBlock(), _createBlock(_component_Comp, null, {
10-
[_ctx.one]: ({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)],
11-
[_ctx.two]: ({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)],
10+
[_ctx.one]: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)], _ctx),
11+
[_ctx.two]: _withCtx(({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)], _ctx),
1212
_: 1
1313
}, 1024 /* DYNAMIC_SLOTS */))
1414
}"
1515
`;
1616

1717
exports[`compiler: transform component slots implicit default slot 1`] = `
18-
"const { createVNode: _createVNode, resolveComponent: _resolveComponent, openBlock: _openBlock, createBlock: _createBlock } = Vue
18+
"const { createVNode: _createVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
1919
2020
return function render(_ctx, _cache) {
2121
const _component_Comp = _resolveComponent(\\"Comp\\")
2222
2323
return (_openBlock(), _createBlock(_component_Comp, null, {
24-
default: () => [
24+
default: _withCtx(() => [
2525
_createVNode(\\"div\\")
26-
],
26+
], _ctx),
2727
_: 1
2828
}))
2929
}"
3030
`;
3131

3232
exports[`compiler: transform component slots named slot with v-for w/ prefixIdentifiers: true 1`] = `
33-
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, renderList: _renderList, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
33+
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
3434
3535
return function render(_ctx, _cache) {
3636
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -39,15 +39,15 @@ return function render(_ctx, _cache) {
3939
_renderList(_ctx.list, (name) => {
4040
return {
4141
name: name,
42-
fn: () => [_toDisplayString(name)]
42+
fn: _withCtx(() => [_toDisplayString(name)], _ctx)
4343
}
4444
})
4545
]), 1024 /* DYNAMIC_SLOTS */))
4646
}"
4747
`;
4848

4949
exports[`compiler: transform component slots named slot with v-if + prefixIdentifiers: true 1`] = `
50-
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
50+
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
5151
5252
return function render(_ctx, _cache) {
5353
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -56,7 +56,7 @@ return function render(_ctx, _cache) {
5656
(_ctx.ok)
5757
? {
5858
name: \\"one\\",
59-
fn: (props) => [_toDisplayString(props)]
59+
fn: _withCtx((props) => [_toDisplayString(props)], _ctx)
6060
}
6161
: undefined
6262
]), 1024 /* DYNAMIC_SLOTS */))
@@ -68,24 +68,24 @@ exports[`compiler: transform component slots named slot with v-if + v-else-if +
6868
6969
return function render(_ctx, _cache) {
7070
with (_ctx) {
71-
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
71+
const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
7272
7373
const _component_Comp = _resolveComponent(\\"Comp\\")
7474
7575
return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 1 }, [
7676
ok
7777
? {
7878
name: \\"one\\",
79-
fn: () => [\\"foo\\"]
79+
fn: _withCtx(() => [\\"foo\\"], _ctx)
8080
}
8181
: orNot
8282
? {
8383
name: \\"two\\",
84-
fn: (props) => [\\"bar\\"]
84+
fn: _withCtx((props) => [\\"bar\\"], _ctx)
8585
}
8686
: {
8787
name: \\"one\\",
88-
fn: () => [\\"baz\\"]
88+
fn: _withCtx(() => [\\"baz\\"], _ctx)
8989
}
9090
]), 1024 /* DYNAMIC_SLOTS */))
9191
}
@@ -97,15 +97,15 @@ exports[`compiler: transform component slots named slot with v-if 1`] = `
9797
9898
return function render(_ctx, _cache) {
9999
with (_ctx) {
100-
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
100+
const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
101101
102102
const _component_Comp = _resolveComponent(\\"Comp\\")
103103
104104
return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 1 }, [
105105
ok
106106
? {
107107
name: \\"one\\",
108-
fn: () => [\\"hello\\"]
108+
fn: _withCtx(() => [\\"hello\\"], _ctx)
109109
}
110110
: undefined
111111
]), 1024 /* DYNAMIC_SLOTS */))
@@ -114,14 +114,14 @@ return function render(_ctx, _cache) {
114114
`;
115115

116116
exports[`compiler: transform component slots named slots 1`] = `
117-
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
117+
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
118118
119119
return function render(_ctx, _cache) {
120120
const _component_Comp = _resolveComponent(\\"Comp\\")
121121
122122
return (_openBlock(), _createBlock(_component_Comp, null, {
123-
one: ({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)],
124-
two: ({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)],
123+
one: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)], _ctx),
124+
two: _withCtx(({ bar }) => [_toDisplayString(_ctx.foo), _toDisplayString(bar)], _ctx),
125125
_: 1
126126
}))
127127
}"
@@ -132,53 +132,53 @@ exports[`compiler: transform component slots named slots w/ implicit default slo
132132
133133
return function render(_ctx, _cache) {
134134
with (_ctx) {
135-
const { createVNode: _createVNode, resolveComponent: _resolveComponent, openBlock: _openBlock, createBlock: _createBlock } = _Vue
135+
const { createVNode: _createVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = _Vue
136136
137137
const _component_Comp = _resolveComponent(\\"Comp\\")
138138
139139
return (_openBlock(), _createBlock(_component_Comp, null, {
140-
one: () => [\\"foo\\"],
141-
default: () => [
140+
one: _withCtx(() => [\\"foo\\"], _ctx),
141+
default: _withCtx(() => [
142142
\\"bar\\",
143143
_createVNode(\\"span\\")
144-
],
144+
], _ctx),
145145
_: 1
146146
}))
147147
}
148148
}"
149149
`;
150150

151151
exports[`compiler: transform component slots nested slots scoping 1`] = `
152-
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
152+
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
153153
154154
return function render(_ctx, _cache) {
155155
const _component_Inner = _resolveComponent(\\"Inner\\")
156156
const _component_Comp = _resolveComponent(\\"Comp\\")
157157
158158
return (_openBlock(), _createBlock(_component_Comp, null, {
159-
default: ({ foo }) => [
159+
default: _withCtx(({ foo }) => [
160160
_createVNode(_component_Inner, null, {
161-
default: ({ bar }) => [_toDisplayString(foo), _toDisplayString(bar), _toDisplayString(_ctx.baz)],
161+
default: _withCtx(({ bar }) => [_toDisplayString(foo), _toDisplayString(bar), _toDisplayString(_ctx.baz)], _ctx),
162162
_: 1
163163
}, 1024 /* DYNAMIC_SLOTS */),
164164
\\" \\",
165165
_toDisplayString(foo),
166166
_toDisplayString(_ctx.bar),
167167
_toDisplayString(_ctx.baz)
168-
],
168+
], _ctx),
169169
_: 1
170170
}))
171171
}"
172172
`;
173173

174174
exports[`compiler: transform component slots on-component default slot 1`] = `
175-
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
175+
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
176176
177177
return function render(_ctx, _cache) {
178178
const _component_Comp = _resolveComponent(\\"Comp\\")
179179
180180
return (_openBlock(), _createBlock(_component_Comp, null, {
181-
default: ({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)],
181+
default: _withCtx(({ foo }) => [_toDisplayString(foo), _toDisplayString(_ctx.bar)], _ctx),
182182
_: 1
183183
}))
184184
}"

packages/compiler-core/src/codegen.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,8 @@ function genFunctionExpression(
768768

769769
if (genScopeId) {
770770
push(`_withId(`)
771+
} else if (isSlot) {
772+
push(`_withCtx(`)
771773
}
772774
push(`(`, node)
773775
if (isArray(params)) {
@@ -796,8 +798,8 @@ function genFunctionExpression(
796798
deindent()
797799
push(`}`)
798800
}
799-
if (genScopeId) {
800-
push(`)`)
801+
if (genScopeId || isSlot) {
802+
push(`, _ctx)`)
801803
}
802804
}
803805

packages/compiler-core/src/runtimeHelpers.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const SET_BLOCK_TRACKING = Symbol(__DEV__ ? `setBlockTracking` : ``)
2626
export const PUSH_SCOPE_ID = Symbol(__DEV__ ? `pushScopeId` : ``)
2727
export const POP_SCOPE_ID = Symbol(__DEV__ ? `popScopeId` : ``)
2828
export const WITH_SCOPE_ID = Symbol(__DEV__ ? `withScopeId` : ``)
29+
export const WITH_CTX = Symbol(__DEV__ ? `withCtx` : ``)
2930

3031
// Name mapping for runtime helpers that need to be imported from 'vue' in
3132
// generated code. Make sure these are correctly exported in the runtime!
@@ -56,7 +57,8 @@ export const helperNameMap: any = {
5657
[SET_BLOCK_TRACKING]: `setBlockTracking`,
5758
[PUSH_SCOPE_ID]: `pushScopeId`,
5859
[POP_SCOPE_ID]: `popScopeId`,
59-
[WITH_SCOPE_ID]: `withScopeId`
60+
[WITH_SCOPE_ID]: `withScopeId`,
61+
[WITH_CTX]: `withCtx`
6062
}
6163

6264
export function registerRuntimeHelpers(helpers: any) {

packages/compiler-core/src/transforms/vSlot.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
import { TransformContext, NodeTransform } from '../transform'
2626
import { createCompilerError, ErrorCodes } from '../errors'
2727
import { findDir, isTemplateNode, assert, isVSlot, hasScopeRef } from '../utils'
28-
import { CREATE_SLOTS, RENDER_LIST } from '../runtimeHelpers'
28+
import { CREATE_SLOTS, RENDER_LIST, WITH_CTX } from '../runtimeHelpers'
2929
import { parseForExpression, createForLoopParams } from './vFor'
3030

3131
const isStaticExp = (p: JSChildNode): p is SimpleExpressionNode =>
@@ -119,6 +119,8 @@ export function buildSlots(
119119
slots: SlotsExpression
120120
hasDynamicSlots: boolean
121121
} {
122+
context.helper(WITH_CTX)
123+
122124
const { children, loc } = node
123125
const slotsProperties: Property[] = []
124126
const dynamicSlots: (ConditionalExpression | CallExpression)[] = []

0 commit comments

Comments
 (0)