Skip to content

Commit 4d39443

Browse files
antfupikax
andauthored
fix: reactive for props (#547)
* fix: reactive for props * chore: remove uneccssary PropsReactive symbol * refactor: createObserver * Update src/reactivity/reactive.ts Co-authored-by: Carlos Rodrigues <[email protected]> Co-authored-by: Carlos Rodrigues <[email protected]>
1 parent 9315570 commit 4d39443

File tree

6 files changed

+20
-13
lines changed

6 files changed

+20
-13
lines changed

src/apis/watch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ function createVueWatcher(
182182
}
183183

184184
// We have to monkeypatch the teardown function so Vue will run
185-
// runCleanup() when it tears down the watcher on unmmount.
185+
// runCleanup() when it tears down the watcher on unmounted.
186186
function patchWatcherTeardown(watcher: VueWatcher, runCleanup: () => void) {
187187
const _teardown = watcher.teardown
188188
watcher.teardown = function (...args) {

src/mixin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
resolveScopedSlots,
2424
asVmProperty,
2525
} from './utils/instance'
26-
import { PropsReactive } from './utils/symbols'
26+
import { createObserver } from './reactivity/reactive'
2727

2828
export function mixin(Vue: VueConstructor) {
2929
Vue.mixin({
@@ -83,7 +83,7 @@ export function mixin(Vue: VueConstructor) {
8383
const ctx = createSetupContext(vm)
8484

8585
// fake reactive for `toRefs(props)`
86-
def(props, PropsReactive, true)
86+
def(props, '__ob__', createObserver())
8787

8888
// resolve scopedSlots and slots to functions
8989
resolveScopedSlots(vm, ctx.slots)

src/reactivity/reactive.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ function observe<T>(obj: T): T {
119119
return observed
120120
}
121121

122+
export function createObserver() {
123+
return observe<any>({}).__ob__ || {}
124+
}
125+
122126
export function shallowReactive<T extends object = any>(obj: T): T
123127
export function shallowReactive(obj: any): any {
124128
if (__DEV__ && !obj) {
@@ -255,7 +259,7 @@ export function markRaw<T extends object>(obj: T): T {
255259
}
256260

257261
// set the vue observable flag at obj
258-
const ob = (observe({}) as any).__ob__
262+
const ob = createObserver()
259263
ob.__raw__ = true
260264
def(obj, '__ob__', ob)
261265

src/reactivity/ref.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Data } from '../component'
2-
import { RefKey, PropsReactive } from '../utils/symbols'
2+
import { RefKey } from '../utils/symbols'
33
import { proxy, isPlainObject, warn } from '../utils'
44
import { reactive, isReactive, shallowReactive } from './reactive'
55
import { readonlySet } from '../utils/sets'
@@ -114,16 +114,13 @@ export function ref(raw?: unknown) {
114114
export function isRef<T>(value: any): value is Ref<T> {
115115
return value instanceof RefImpl
116116
}
117-
function isPropObject(obj: unknown) {
118-
return obj && typeof obj === 'object' && PropsReactive in obj
119-
}
120117

121118
export function unref<T>(ref: T): T extends Ref<infer V> ? V : T {
122119
return isRef(ref) ? (ref.value as any) : ref
123120
}
124121

125122
export function toRefs<T extends Data = Data>(obj: T): ToRefs<T> {
126-
if (__DEV__ && !isReactive(obj) && !isPropObject(obj)) {
123+
if (__DEV__ && !isReactive(obj)) {
127124
warn(`toRefs() expects a reactive object but received a plain one.`)
128125
}
129126
if (!isPlainObject(obj)) return obj as any

src/utils/symbols.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,3 @@ export const WatcherPostFlushQueueKey = createSymbol(
1313

1414
// must be a string, symbol key is ignored in reactive
1515
export const RefKey = 'composition-api.refKey'
16-
export const PropsReactive = '__props_reactive__'

test/setup.spec.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ const {
1010
markRaw,
1111
toRaw,
1212
nextTick,
13+
isReactive,
1314
defineComponent,
14-
onMounted,
15+
onMounted
1516
} = require('../src')
1617
const { sleep } = require('./helpers/utils')
1718

@@ -58,7 +59,7 @@ describe('setup', () => {
5859
expect(vm.b).toBe('foobar')
5960
})
6061

61-
it('should be overrided by data option of plain object', () => {
62+
it('should be overridden by data option of plain object', () => {
6263
const vm = new Vue({
6364
setup() {
6465
return {
@@ -303,8 +304,9 @@ describe('setup', () => {
303304
expect(vm.$refs.test.b).toBe(1)
304305
})
305306

306-
it('props should not be reactive', (done) => {
307+
it('props should be reactive', (done) => {
307308
let calls = 0
309+
let _props
308310
const vm = new Vue({
309311
template: `<child :msg="msg"></child>`,
310312
setup() {
@@ -318,6 +320,8 @@ describe('setup', () => {
318320
template: `<span>{{ localMsg }}</span>`,
319321
props: ['msg'],
320322
setup(props) {
323+
_props = props
324+
321325
return {
322326
localMsg: props.msg,
323327
computedMsg: computed(() => props.msg + ' world'),
@@ -326,6 +330,9 @@ describe('setup', () => {
326330
},
327331
},
328332
}).$mount()
333+
334+
expect(isReactive(_props)).toBe(true)
335+
329336
const child = vm.$children[0]
330337
expect(child.localMsg).toBe('hello')
331338
expect(child.computedMsg).toBe('hello world')

0 commit comments

Comments
 (0)