Skip to content

Commit 9fa6fc3

Browse files
committed
feat: add defineSlots macro
1 parent c346af2 commit 9fa6fc3

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

packages/compiler-sfc/src/compileScript.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const DEFINE_EMITS = 'defineEmits'
6767
const DEFINE_EXPOSE = 'defineExpose'
6868
const WITH_DEFAULTS = 'withDefaults'
6969
const DEFINE_OPTIONS = 'defineOptions'
70+
const DEFINT_SLOTS = 'defineSlots'
7071

7172
const isBuiltInDir = makeMap(
7273
`once,memo,if,for,else,else-if,slot,text,html,on,bind,model,show,cloak,is`
@@ -312,6 +313,7 @@ export function compileScript(
312313
let hasDefaultExportName = false
313314
let hasDefaultExportRender = false
314315
let hasDefineOptionsCall = false
316+
let hasDefineSlotsCall = false
315317
let propsRuntimeDecl: Node | undefined
316318
let propsRuntimeDefaults: Node | undefined
317319
let propsDestructureDecl: Node | undefined
@@ -590,6 +592,26 @@ export function compileScript(
590592
return true
591593
}
592594

595+
function processDefineSlots(node: Node, declId?: LVal): boolean {
596+
if (!isCallOf(node, DEFINT_SLOTS)) {
597+
return false
598+
}
599+
if (hasDefineSlotsCall) {
600+
error(`duplicate ${DEFINT_SLOTS}() call`, node)
601+
}
602+
hasDefineSlotsCall = true
603+
604+
if (declId) {
605+
s.overwrite(
606+
startOffset + node.start!,
607+
startOffset + node.end!,
608+
`${helper('useSlots')}()`
609+
)
610+
}
611+
612+
return true
613+
}
614+
593615
function getAstBody(): Statement[] {
594616
return scriptAst
595617
? [...scriptSetupAst.body, ...scriptAst.body]
@@ -1286,7 +1308,8 @@ export function compileScript(
12861308
processDefineProps(expr) ||
12871309
processDefineEmits(expr) ||
12881310
processDefineOptions(expr) ||
1289-
processWithDefaults(expr)
1311+
processWithDefaults(expr) ||
1312+
processDefineSlots(expr)
12901313
) {
12911314
s.remove(node.start! + startOffset, node.end! + startOffset)
12921315
} else if (processDefineExpose(expr)) {
@@ -1321,6 +1344,8 @@ export function compileScript(
13211344
processDefineProps(init, decl.id) ||
13221345
processWithDefaults(init, decl.id)
13231346
const isDefineEmits = processDefineEmits(init, decl.id)
1347+
processDefineSlots(init, decl.id)
1348+
13241349
if (isDefineProps || isDefineEmits) {
13251350
if (left === 1) {
13261351
s.remove(node.start! + startOffset, node.end! + startOffset)

packages/runtime-core/src/apiSetupHelpers.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
ExtractPropTypes
2626
} from './componentProps'
2727
import { warn } from './warning'
28+
import { VNode } from './vnode'
2829

2930
// dev only
3031
const warnRuntimeUsage = (method: string) =>
@@ -192,6 +193,17 @@ export function defineOptions<
192193
}
193194
}
194195

196+
export function defineSlots<
197+
T extends Record<string, any>
198+
>(): // @ts-expect-error
199+
{
200+
[K in keyof T]: (scope: T[K]) => VNode[] | undefined
201+
} {
202+
if (__DEV__) {
203+
warnRuntimeUsage(`defineSlots`)
204+
}
205+
}
206+
195207
type NotUndefined<T> = T extends undefined ? never : T
196208

197209
type InferDefaults<T> = {

packages/runtime-core/types/scriptSetupHelpers.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ type _defineProps = typeof defineProps
44
type _defineEmits = typeof defineEmits
55
type _defineExpose = typeof defineExpose
66
type _defineOptions = typeof defineOptions
7+
type _defineSlots = typeof defineSlots
78
type _withDefaults = typeof withDefaults
89

910
declare global {
1011
const defineProps: _defineProps
1112
const defineEmits: _defineEmits
1213
const defineExpose: _defineExpose
1314
const defineOptions: _defineOptions
15+
const defineSlots: _defineSlots
1416
const withDefaults: _withDefaults
1517
}

0 commit comments

Comments
 (0)