Skip to content

Commit 3c2707b

Browse files
committedJun 16, 2022
feat: defineExpose() support
1 parent bd8409b commit 3c2707b

File tree

7 files changed

+101
-161
lines changed

7 files changed

+101
-161
lines changed
 

Diff for: ‎packages/compiler-sfc/src/compileScript.ts

+4-7
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ export function compileScript(
11831183
s.prependLeft(startOffset, `\nlet __temp${any}, __restore${any}\n`)
11841184
}
11851185

1186-
const destructureElements = [`expose`]
1186+
const destructureElements = hasDefineExposeCall ? [`expose`] : []
11871187
if (emitIdentifier) {
11881188
destructureElements.push(
11891189
emitIdentifier === `emit` ? `emit` : `emit: ${emitIdentifier}`
@@ -1256,9 +1256,6 @@ export function compileScript(
12561256
runtimeOptions += genRuntimeEmits(typeDeclaredEmits)
12571257
}
12581258

1259-
// <script setup> components are closed by default. If the user did not
1260-
// explicitly call `defineExpose`, call expose() with no args.
1261-
const exposeCall = hasDefineExposeCall ? `` : ` expose();\n`
12621259
// wrap setup code with function.
12631260
if (isTS) {
12641261
// for TS, make sure the exported type is still valid type with
@@ -1273,7 +1270,7 @@ export function compileScript(
12731270
`defineComponent`
12741271
)}({${def}${runtimeOptions}\n ${
12751272
hasAwait ? `async ` : ``
1276-
}setup(${args}) {\n${exposeCall}`
1273+
}setup(${args}) {\n`
12771274
)
12781275
s.appendRight(endOffset, `})`)
12791276
} else {
@@ -1283,14 +1280,14 @@ export function compileScript(
12831280
s.prependLeft(
12841281
startOffset,
12851282
`\nexport default /*#__PURE__*/Object.assign(${DEFAULT_VAR}, {${runtimeOptions}\n ` +
1286-
`${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`
1283+
`${hasAwait ? `async ` : ``}setup(${args}) {\n`
12871284
)
12881285
s.appendRight(endOffset, `})`)
12891286
} else {
12901287
s.prependLeft(
12911288
startOffset,
12921289
`\nexport default {${runtimeOptions}\n ` +
1293-
`${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`
1290+
`${hasAwait ? `async ` : ``}setup(${args}) {\n`
12941291
)
12951292
s.appendRight(endOffset, `}`)
12961293
}

Diff for: ‎packages/compiler-sfc/test/__snapshots__/compileScript.spec.ts.snap

+69-138
Large diffs are not rendered by default.

Diff for: ‎packages/compiler-sfc/test/compileScript.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ const bar = 1
102102
// should remove defineOptions import and call
103103
expect(content).not.toMatch('defineProps')
104104
// should generate correct setup signature
105-
expect(content).toMatch(`setup(__props, { expose }) {`)
105+
expect(content).toMatch(`setup(__props) {`)
106106
// should assign user identifier to it
107107
expect(content).toMatch(`const props = __props`)
108108
// should include context options in default export
@@ -149,7 +149,7 @@ const myEmit = defineEmits(['foo', 'bar'])
149149
// should remove defineOptions import and call
150150
expect(content).not.toMatch('defineEmits')
151151
// should generate correct setup signature
152-
expect(content).toMatch(`setup(__props, { expose, emit: myEmit }) {`)
152+
expect(content).toMatch(`setup(__props, { emit: myEmit }) {`)
153153
// should include context options in default export
154154
expect(content).toMatch(`export default {
155155
emits: ['foo', 'bar'],`)
@@ -769,7 +769,7 @@ const emit = defineEmits(['a', 'b'])
769769
expect(content).toMatch(`export default /*#__PURE__*/_defineComponent({
770770
props: { foo: String },
771771
emits: ['a', 'b'],
772-
setup(__props, { expose, emit }) {`)
772+
setup(__props, { emit }) {`)
773773
})
774774

775775
test('defineProps w/ type', () => {

Diff for: ‎src/core/config.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export interface Config {
1313
productionTip: boolean
1414
performance: boolean
1515
devtools: boolean
16-
errorHandler?: (err: Error, vm: Component, info: string) => void
17-
warnHandler?: (msg: string, vm: Component, trace: string) => void
16+
errorHandler?: (err: Error, vm: Component | null, info: string) => void
17+
warnHandler?: (msg: string, vm: Component | null, trace: string) => void
1818
ignoredElements: Array<string | RegExp>
1919
keyCodes: { [key: string]: number | Array<number> }
2020

Diff for: ‎src/core/util/debug.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { noop, isArray, isFunction } from 'shared/util'
33
import type { Component } from 'types/component'
44
import { currentInstance } from 'v3/currentInstance'
55

6-
export let warn = noop
6+
export let warn: (msg: string, vm?: Component | null) => void = noop
77
export let tip = noop
88
export let generateComponentTrace: (vm: Component) => string // work around flow check
99
export let formatComponentName: (vm: Component, includeFile?: false) => string

Diff for: ‎src/types/options.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export type ComponentOptions = {
9090
comments?: boolean
9191
inheritAttrs?: boolean
9292

93-
// Class API
93+
// Legacy API
9494
abstract?: any
9595

9696
// private

Diff for: ‎src/v3/apiSetup.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface SetupContext {
1212
attrs: Record<string, any>
1313
slots: Record<string, () => VNode[]>
1414
emit: (event: string, ...args: any[]) => any
15+
expose: (exposed: Record<string, any>) => void
1516
}
1617

1718
export function initSetup(vm: Component) {
@@ -47,7 +48,7 @@ export function initSetup(vm: Component) {
4748
if (!setupResult.__sfc) {
4849
for (const key in setupResult) {
4950
if (!isReserved(key)) {
50-
proxySetupProperty(vm, setupResult, key)
51+
proxyWithRefUnwrap(vm, setupResult, key)
5152
} else if (__DEV__) {
5253
warn(`Avoid using variables that start with _ or $ in setup().`)
5354
}
@@ -56,7 +57,7 @@ export function initSetup(vm: Component) {
5657
// exposed for compiled render fn
5758
const proxy = (vm._setupProxy = {})
5859
for (const key in setupResult) {
59-
proxySetupProperty(proxy, setupResult, key)
60+
proxyWithRefUnwrap(proxy, setupResult, key)
6061
}
6162
}
6263
} else if (__DEV__ && setupResult !== undefined) {
@@ -69,22 +70,23 @@ export function initSetup(vm: Component) {
6970
}
7071
}
7172

72-
function proxySetupProperty(
73+
export function proxyWithRefUnwrap(
7374
target: any,
74-
setupResult: Record<string, any>,
75+
source: Record<string, any>,
7576
key: string
7677
) {
77-
let raw = setupResult[key]
78+
let raw = source[key]
7879
Object.defineProperty(target, key, {
7980
enumerable: true,
8081
configurable: true,
8182
get: () => (isRef(raw) ? raw.value : raw),
8283
set: newVal =>
83-
isRef(raw) ? (raw.value = newVal) : (raw = setupResult[key] = newVal)
84+
isRef(raw) ? (raw.value = newVal) : (raw = source[key] = newVal)
8485
})
8586
}
8687

87-
function createSetupContext(vm: Component) {
88+
function createSetupContext(vm: Component): SetupContext {
89+
let exposeCalled = false
8890
return {
8991
get attrs() {
9092
return initAttrsProxy(vm)
@@ -93,8 +95,18 @@ function createSetupContext(vm: Component) {
9395
return initSlotsProxy(vm)
9496
},
9597
emit: bind(vm.$emit, vm) as any,
96-
expose() {
97-
// TODO
98+
expose(exposed?: Record<string, any>) {
99+
if (__DEV__) {
100+
if (exposeCalled) {
101+
warn(`expose() should be called only once per setup().`, vm)
102+
}
103+
exposeCalled = true
104+
}
105+
if (exposed) {
106+
Object.keys(exposed).forEach(key =>
107+
proxyWithRefUnwrap(vm, exposed, key)
108+
)
109+
}
98110
}
99111
}
100112
}

0 commit comments

Comments
 (0)
Please sign in to comment.