|
|
@@ -5,7 +5,6 @@ import Dep from './dep'
|
|
|
import { arrayMethods } from './array'
|
|
|
import {
|
|
|
def,
|
|
|
- remove,
|
|
|
isObject,
|
|
|
isPlainObject,
|
|
|
hasProto,
|
|
|
@@ -35,12 +34,12 @@ export const observerState = {
|
|
|
export class Observer {
|
|
|
value: any;
|
|
|
dep: Dep;
|
|
|
- vms: ?Array<Component>;
|
|
|
+ vmCount: number; // number of vms that has this object as root $data
|
|
|
|
|
|
constructor (value: any) {
|
|
|
this.value = value
|
|
|
this.dep = new Dep()
|
|
|
- this.vms = null
|
|
|
+ this.vmCount = 0
|
|
|
def(value, '__ob__', this)
|
|
|
if (Array.isArray(value)) {
|
|
|
const augment = hasProto
|
|
|
@@ -73,24 +72,6 @@ export class Observer {
|
|
|
observe(items[i])
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * Add an owner vm, so that when $set/$delete mutations
|
|
|
- * happen we can notify owner vms to proxy the keys and
|
|
|
- * digest the watchers. This is only called when the object
|
|
|
- * is observed as an instance's root $data.
|
|
|
- */
|
|
|
- addVm (vm: Component) {
|
|
|
- (this.vms || (this.vms = [])).push(vm)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Remove an owner vm. This is called when the object is
|
|
|
- * swapped out as an instance's $data object.
|
|
|
- */
|
|
|
- removeVm (vm: Component) {
|
|
|
- remove(this.vms, vm)
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
// helpers
|
|
|
@@ -123,7 +104,7 @@ function copyAugment (target: Object, src: Object, keys: Array<string>) {
|
|
|
* returns the new observer if successfully observed,
|
|
|
* or the existing observer if the value already has one.
|
|
|
*/
|
|
|
-export function observe (value: any, vm?: Component): Observer | void {
|
|
|
+export function observe (value: any): Observer | void {
|
|
|
if (!isObject(value)) {
|
|
|
return
|
|
|
}
|
|
|
@@ -139,9 +120,6 @@ export function observe (value: any, vm?: Component): Observer | void {
|
|
|
) {
|
|
|
ob = new Observer(value)
|
|
|
}
|
|
|
- if (ob && vm) {
|
|
|
- ob.addVm(vm)
|
|
|
- }
|
|
|
return ob
|
|
|
}
|
|
|
|
|
|
@@ -210,28 +188,20 @@ export function set (obj: Array<any> | Object, key: any, val: any) {
|
|
|
obj[key] = val
|
|
|
return
|
|
|
}
|
|
|
- if (obj._isVue) {
|
|
|
+ const ob = obj.__ob__
|
|
|
+ if (obj._isVue || (ob && ob.vmCount)) {
|
|
|
process.env.NODE_ENV !== 'production' && warn(
|
|
|
- 'Do not add reactive properties to a Vue instance at runtime - ' +
|
|
|
- 'delcare it upfront in the data option.'
|
|
|
+ 'Avoid adding reactive properties to a Vue instance or its root $data ' +
|
|
|
+ 'at runtime - delcare it upfront in the data option.'
|
|
|
)
|
|
|
return
|
|
|
}
|
|
|
- const ob = obj.__ob__
|
|
|
if (!ob) {
|
|
|
obj[key] = val
|
|
|
return
|
|
|
}
|
|
|
defineReactive(ob.value, key, val)
|
|
|
ob.dep.notify()
|
|
|
- if (ob.vms) {
|
|
|
- let i = ob.vms.length
|
|
|
- while (i--) {
|
|
|
- const vm = ob.vms[i]
|
|
|
- proxy(vm, key)
|
|
|
- vm.$forceUpdate()
|
|
|
- }
|
|
|
- }
|
|
|
return val
|
|
|
}
|
|
|
|
|
|
@@ -239,9 +209,11 @@ export function set (obj: Array<any> | Object, key: any, val: any) {
|
|
|
* Delete a property and trigger change if necessary.
|
|
|
*/
|
|
|
export function del (obj: Object, key: string) {
|
|
|
- if (obj._isVue) {
|
|
|
+ const ob = obj.__ob__
|
|
|
+ if (obj._isVue || (ob && ob.vmCount)) {
|
|
|
process.env.NODE_ENV !== 'production' && warn(
|
|
|
- 'Do not delete properties on a Vue instance - just set it to null.'
|
|
|
+ 'Avoid deleting properties on a Vue instance or its root $data ' +
|
|
|
+ '- just set it to null.'
|
|
|
)
|
|
|
return
|
|
|
}
|
|
|
@@ -249,19 +221,10 @@ export function del (obj: Object, key: string) {
|
|
|
return
|
|
|
}
|
|
|
delete obj[key]
|
|
|
- const ob = obj.__ob__
|
|
|
if (!ob) {
|
|
|
return
|
|
|
}
|
|
|
ob.dep.notify()
|
|
|
- if (ob.vms) {
|
|
|
- let i = ob.vms.length
|
|
|
- while (i--) {
|
|
|
- const vm = ob.vms[i]
|
|
|
- unproxy(vm, key)
|
|
|
- vm.$forceUpdate()
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
export function proxy (vm: Component, key: string) {
|