Skip to content

Commit 4e10d69

Browse files
committed
feat: add defineSlots macro
1 parent 71635be commit 4e10d69

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
@@ -68,6 +68,7 @@ const DEFINE_EMITS = 'defineEmits'
6868
const DEFINE_EXPOSE = 'defineExpose'
6969
const WITH_DEFAULTS = 'withDefaults'
7070
const DEFINE_OPTIONS = 'defineOptions'
71+
const DEFINT_SLOTS = 'defineSlots'
7172

7273
const isBuiltInDir = makeMap(
7374
`once,memo,if,for,else,else-if,slot,text,html,on,bind,model,show,cloak,is`
@@ -313,6 +314,7 @@ export function compileScript(
313314
let hasDefaultExportName = false
314315
let hasDefaultExportRender = false
315316
let hasDefineOptionsCall = false
317+
let hasDefineSlotsCall = false
316318
let propsRuntimeDecl: Node | undefined
317319
let propsRuntimeDefaults: ObjectExpression | undefined
318320
let propsDestructureDecl: Node | undefined
@@ -607,6 +609,26 @@ export function compileScript(
607609
return true
608610
}
609611

612+
function processDefineSlots(node: Node, declId?: LVal): boolean {
613+
if (!isCallOf(node, DEFINT_SLOTS)) {
614+
return false
615+
}
616+
if (hasDefineSlotsCall) {
617+
error(`duplicate ${DEFINT_SLOTS}() call`, node)
618+
}
619+
hasDefineSlotsCall = true
620+
621+
if (declId) {
622+
s.overwrite(
623+
startOffset + node.start!,
624+
startOffset + node.end!,
625+
`${helper('useSlots')}()`
626+
)
627+
}
628+
629+
return true
630+
}
631+
610632
function getAstBody(): Statement[] {
611633
return scriptAst
612634
? [...scriptSetupAst.body, ...scriptAst.body]
@@ -1302,7 +1324,8 @@ export function compileScript(
13021324
processDefineProps(expr) ||
13031325
processDefineEmits(expr) ||
13041326
processDefineOptions(expr) ||
1305-
processWithDefaults(expr)
1327+
processWithDefaults(expr) ||
1328+
processDefineSlots(expr)
13061329
) {
13071330
s.remove(node.start! + startOffset, node.end! + startOffset)
13081331
} else if (processDefineExpose(expr)) {
@@ -1337,6 +1360,8 @@ export function compileScript(
13371360
processDefineProps(init, decl.id) ||
13381361
processWithDefaults(init, decl.id, node.kind)
13391362
const isDefineEmits = processDefineEmits(init, decl.id)
1363+
processDefineSlots(init, decl.id)
1364+
13401365
if (isDefineProps || isDefineEmits) {
13411366
if (left === 1) {
13421367
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
@@ -19,6 +19,7 @@ import {
1919
ExtractPropTypes
2020
} from './componentProps'
2121
import { warn } from './warning'
22+
import { VNode } from './vnode'
2223

2324
// dev only
2425
const warnRuntimeUsage = (method: string) =>
@@ -176,6 +177,17 @@ export function defineOptions<
176177
}
177178
}
178179

180+
export function defineSlots<
181+
T extends Record<string, any>
182+
>(): // @ts-expect-error
183+
{
184+
[K in keyof T]: (scope: T[K]) => VNode[] | undefined
185+
} {
186+
if (__DEV__) {
187+
warnRuntimeUsage(`defineSlots`)
188+
}
189+
}
190+
179191
type NotUndefined<T> = T extends undefined ? never : T
180192

181193
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)