Skip to content

Commit 492c2fb

Browse files
committed
fix: destructure attrs from context keep reactive, close vuejs#264
1 parent d1ff9df commit 492c2fb

File tree

3 files changed

+237
-152
lines changed

3 files changed

+237
-152
lines changed

src/mixin.ts

Lines changed: 38 additions & 17 deletions
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({
@@ -190,38 +190,59 @@ export function mixin(Vue: VueConstructor) {
190190
function createSetupContext(
191191
vm: ComponentInstance & { [x: string]: any }
192192
): SetupContext {
193-
const ctx = {
194-
slots: {},
195-
} as SetupContext
196-
const props: Array<string | [string, string]> = [
193+
const ctx = { slots: {} } as SetupContext
194+
195+
const propsPlain = [
197196
'root',
198197
'parent',
199198
'refs',
200-
'attrs',
201199
'listeners',
202200
'isServer',
203201
'ssrContext',
204202
]
203+
const propsReactiveProxy = ['attrs']
205204
const methodReturnVoid = ['emit']
206-
props.forEach((key) => {
207-
let targetKey: string
208-
let srcKey: string
209-
if (Array.isArray(key)) {
210-
;[targetKey, srcKey] = key
211-
} else {
212-
targetKey = srcKey = key
213-
}
214-
srcKey = `$${srcKey}`
215-
proxy(ctx, targetKey, {
205+
206+
propsPlain.forEach((key) => {
207+
let srcKey = `$${key}`
208+
proxy(ctx, key, {
216209
get: () => vm[srcKey],
217210
set() {
218211
warn(
219-
`Cannot assign to '${targetKey}' because it is a read-only property`,
212+
`Cannot assign to '${key}' because it is a read-only property`,
213+
vm
214+
)
215+
},
216+
})
217+
})
218+
219+
propsReactiveProxy.forEach((key) => {
220+
let srcKey = `$${key}`
221+
proxy(ctx, key, {
222+
get: () => {
223+
const data = reactive({})
224+
const source = vm[srcKey]
225+
226+
for (const attr of Object.keys(source)) {
227+
proxy(data, attr, {
228+
get: () => {
229+
// to ensure it always return the latest value
230+
return vm[srcKey][attr]
231+
},
232+
})
233+
}
234+
235+
return data
236+
},
237+
set() {
238+
warn(
239+
`Cannot assign to '${key}' because it is a read-only property`,
220240
vm
221241
)
222242
},
223243
})
224244
})
245+
225246
methodReturnVoid.forEach((key) => {
226247
const srcKey = `$${key}`
227248
proxy(ctx, key, {

test/setupContext.spec.js

Lines changed: 0 additions & 135 deletions
This file was deleted.

0 commit comments

Comments
 (0)