Skip to content

Commit 4eecd66

Browse files
authored
fix: destructure attrs from context keep reactive, close #264 (#594)
1 parent c7a89b3 commit 4eecd66

File tree

3 files changed

+237
-152
lines changed

3 files changed

+237
-152
lines changed

src/mixin.ts

+38-17
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
asVmProperty,
2626
} from './utils/instance'
2727
import { getVueConstructor } from './runtimeContext'
28-
import { createObserver } from './reactivity/reactive'
28+
import { createObserver, reactive } from './reactivity/reactive'
2929

3030
export function mixin(Vue: VueConstructor) {
3131
Vue.mixin({
@@ -192,38 +192,59 @@ export function mixin(Vue: VueConstructor) {
192192
function createSetupContext(
193193
vm: ComponentInstance & { [x: string]: any }
194194
): SetupContext {
195-
const ctx = {
196-
slots: {},
197-
} as SetupContext
198-
const props: Array<string | [string, string]> = [
195+
const ctx = { slots: {} } as SetupContext
196+
197+
const propsPlain = [
199198
'root',
200199
'parent',
201200
'refs',
202-
'attrs',
203201
'listeners',
204202
'isServer',
205203
'ssrContext',
206204
]
205+
const propsReactiveProxy = ['attrs']
207206
const methodReturnVoid = ['emit']
208-
props.forEach((key) => {
209-
let targetKey: string
210-
let srcKey: string
211-
if (Array.isArray(key)) {
212-
;[targetKey, srcKey] = key
213-
} else {
214-
targetKey = srcKey = key
215-
}
216-
srcKey = `$${srcKey}`
217-
proxy(ctx, targetKey, {
207+
208+
propsPlain.forEach((key) => {
209+
let srcKey = `$${key}`
210+
proxy(ctx, key, {
218211
get: () => vm[srcKey],
219212
set() {
220213
warn(
221-
`Cannot assign to '${targetKey}' because it is a read-only property`,
214+
`Cannot assign to '${key}' because it is a read-only property`,
215+
vm
216+
)
217+
},
218+
})
219+
})
220+
221+
propsReactiveProxy.forEach((key) => {
222+
let srcKey = `$${key}`
223+
proxy(ctx, key, {
224+
get: () => {
225+
const data = reactive({})
226+
const source = vm[srcKey]
227+
228+
for (const attr of Object.keys(source)) {
229+
proxy(data, attr, {
230+
get: () => {
231+
// to ensure it always return the latest value
232+
return vm[srcKey][attr]
233+
},
234+
})
235+
}
236+
237+
return data
238+
},
239+
set() {
240+
warn(
241+
`Cannot assign to '${key}' because it is a read-only property`,
222242
vm
223243
)
224244
},
225245
})
226246
})
247+
227248
methodReturnVoid.forEach((key) => {
228249
const srcKey = `$${key}`
229250
proxy(ctx, key, {

test/setupContext.spec.js

-135
This file was deleted.

0 commit comments

Comments
 (0)