Skip to content

Commit 3e7956f

Browse files
committed
feat: add defineSlots macro
1 parent f597146 commit 3e7956f

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
@@ -606,6 +608,26 @@ export function compileScript(
606608
return true
607609
}
608610

611+
function processDefineSlots(node: Node, declId?: LVal): boolean {
612+
if (!isCallOf(node, DEFINT_SLOTS)) {
613+
return false
614+
}
615+
if (hasDefineSlotsCall) {
616+
error(`duplicate ${DEFINT_SLOTS}() call`, node)
617+
}
618+
hasDefineSlotsCall = true
619+
620+
if (declId) {
621+
s.overwrite(
622+
startOffset + node.start!,
623+
startOffset + node.end!,
624+
`${helper('useSlots')}()`
625+
)
626+
}
627+
628+
return true
629+
}
630+
609631
function getAstBody(): Statement[] {
610632
return scriptAst
611633
? [...scriptSetupAst.body, ...scriptAst.body]
@@ -1301,7 +1323,8 @@ export function compileScript(
13011323
processDefineProps(expr) ||
13021324
processDefineEmits(expr) ||
13031325
processDefineOptions(expr) ||
1304-
processWithDefaults(expr)
1326+
processWithDefaults(expr) ||
1327+
processDefineSlots(expr)
13051328
) {
13061329
s.remove(node.start! + startOffset, node.end! + startOffset)
13071330
} else if (processDefineExpose(expr)) {
@@ -1336,6 +1359,8 @@ export function compileScript(
13361359
processDefineProps(init, decl.id) ||
13371360
processWithDefaults(init, decl.id, node.kind)
13381361
const isDefineEmits = processDefineEmits(init, decl.id)
1362+
processDefineSlots(init, decl.id)
1363+
13391364
if (isDefineProps || isDefineEmits) {
13401365
if (left === 1) {
13411366
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)