@@ -19,6 +19,7 @@ import { proxyWithRefUnwrap } from './reactivity/ref'
1919 */
2020export interface SetupContext {
2121 attrs : Record < string , any >
22+ listeners : Record < string , Function | Function [ ] >
2223 slots : Record < string , ( ) => VNode [ ] >
2324 emit : ( event : string , ...args : any [ ] ) => any
2425 expose : ( exposed : Record < string , any > ) => void
@@ -87,7 +88,19 @@ function createSetupContext(vm: Component): SetupContext {
8788 let exposeCalled = false
8889 return {
8990 get attrs ( ) {
90- return initAttrsProxy ( vm )
91+ if ( ! vm . _attrsProxy ) {
92+ const proxy = ( vm . _attrsProxy = { } )
93+ def ( proxy , '_v_attr_proxy' , true )
94+ syncSetupProxy ( proxy , vm . $attrs , emptyObject , vm , '$attrs' )
95+ }
96+ return vm . _attrsProxy
97+ } ,
98+ get listeners ( ) {
99+ if ( ! vm . _listenersProxy ) {
100+ const proxy = ( vm . _listenersProxy = { } )
101+ syncSetupProxy ( proxy , vm . $listeners , emptyObject , vm , '$listeners' )
102+ }
103+ return vm . _listenersProxy
91104 } ,
92105 get slots ( ) {
93106 return initSlotsProxy ( vm )
@@ -109,26 +122,18 @@ function createSetupContext(vm: Component): SetupContext {
109122 }
110123}
111124
112- function initAttrsProxy ( vm : Component ) {
113- if ( ! vm . _attrsProxy ) {
114- const proxy = ( vm . _attrsProxy = { } )
115- def ( proxy , '_v_attr_proxy' , true )
116- syncSetupAttrs ( proxy , vm . $attrs , emptyObject , vm )
117- }
118- return vm . _attrsProxy
119- }
120-
121- export function syncSetupAttrs (
125+ export function syncSetupProxy (
122126 to : any ,
123127 from : any ,
124128 prev : any ,
125- instance : Component
129+ instance : Component ,
130+ type : string
126131) {
127132 let changed = false
128133 for ( const key in from ) {
129134 if ( ! ( key in to ) ) {
130135 changed = true
131- defineProxyAttr ( to , key , instance )
136+ defineProxyAttr ( to , key , instance , type )
132137 } else if ( from [ key ] !== prev [ key ] ) {
133138 changed = true
134139 }
@@ -142,12 +147,17 @@ export function syncSetupAttrs(
142147 return changed
143148}
144149
145- function defineProxyAttr ( proxy : any , key : string , instance : Component ) {
150+ function defineProxyAttr (
151+ proxy : any ,
152+ key : string ,
153+ instance : Component ,
154+ type : string
155+ ) {
146156 Object . defineProperty ( proxy , key , {
147157 enumerable : true ,
148158 configurable : true ,
149159 get ( ) {
150- return instance . $attrs [ key ]
160+ return instance [ type ] [ key ]
151161 }
152162 } )
153163}
@@ -171,19 +181,23 @@ export function syncSetupSlots(to: any, from: any) {
171181}
172182
173183/**
174- * @internal use manual type def
184+ * @internal use manual type def because it relies on legacy VNode types
175185 */
176186export function useSlots ( ) : SetupContext [ 'slots' ] {
177187 return getContext ( ) . slots
178188}
179189
180- /**
181- * @internal use manual type def
182- */
183190export function useAttrs ( ) : SetupContext [ 'attrs' ] {
184191 return getContext ( ) . attrs
185192}
186193
194+ /**
195+ * Vue 2 only
196+ */
197+ export function useListeners ( ) : SetupContext [ 'listeners' ] {
198+ return getContext ( ) . listeners
199+ }
200+
187201function getContext ( ) : SetupContext {
188202 if ( __DEV__ && ! currentInstance ) {
189203 warn ( `useContext() called without active instance.` )
0 commit comments