Browse Source

improve set/delete API (#5050)

dev
kazuya kawaguchi 8 years ago
committed by Evan You
parent
commit
0922b1d8aa
  1. 4
      flow/component.js
  2. 4
      flow/global-api.js
  3. 38
      src/core/observer/index.js
  4. 4
      test/unit/modules/observer/observer.spec.js

4
flow/component.js

@ -35,8 +35,8 @@ declare interface Component {
$mount: (el?: Element | string, hydrating?: boolean) => Component;
$forceUpdate: () => void;
$destroy: () => void;
$set: (obj: Array<mixed> | Object, key: mixed, val: mixed) => void;
$delete: (obj: Object, key: string) => void;
$set: <T>(target: Object | Array<T>, key: string | number, val: T) => T;
$delete: <T>(target: Object | Array<T>, key: string | number) => void;
$watch: (expOrFn: string | Function, cb: Function, options?: Object) => Function;
$on: (event: string | Array<string>, fn: Function) => Component;
$once: (event: string, fn: Function) => Component;

4
flow/global-api.js

@ -5,8 +5,8 @@ declare interface GlobalAPI {
util: Object;
extend: (options: Object) => Function;
set: (obj: Object, key: string, value: any) => void;
delete: (obj: Object, key: string) => void;
set: <T>(target: Object | Array<T>, key: string | number, value: T) => T;
delete: <T>(target: Object| Array<T>, key: string | number) => void;
nextTick: (fn: Function, context?: Object) => void;
use: (plugin: Function | Object) => void;
mixin: (mixin: Object) => void;

38
src/core/observer/index.js

@ -188,27 +188,27 @@ export function defineReactive (
* triggers change notification if the property doesn't
* already exist.
*/
export function set (obj: Array<any> | Object, key: any, val: any) {
if (Array.isArray(obj)) {
obj.length = Math.max(obj.length, key)
obj.splice(key, 1, val)
export function set (target: Array<any> | Object, key: any, val: any): any {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
if (hasOwn(obj, key)) {
obj[key] = val
return
if (hasOwn(target, key)) {
target[key] = val
return val
}
const ob = obj.__ob__
if (obj._isVue || (ob && ob.vmCount)) {
const ob = target.__ob__
if (target._isVue || (ob && ob.vmCount)) {
process.env.NODE_ENV !== 'production' && warn(
'Avoid adding reactive properties to a Vue instance or its root $data ' +
'at runtime - declare it upfront in the data option.'
)
return
return val
}
if (!ob) {
obj[key] = val
return
target[key] = val
return val
}
defineReactive(ob.value, key, val)
ob.dep.notify()
@ -218,23 +218,23 @@ export function set (obj: Array<any> | Object, key: any, val: any) {
/**
* Delete a property and trigger change if necessary.
*/
export function del (obj: Array<any> | Object, key: any) {
if (Array.isArray(obj)) {
obj.splice(key, 1)
export function del (target: Array<any> | Object, key: any) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
const ob = obj.__ob__
if (obj._isVue || (ob && ob.vmCount)) {
const ob = target.__ob__
if (target._isVue || (ob && ob.vmCount)) {
process.env.NODE_ENV !== 'production' && warn(
'Avoid deleting properties on a Vue instance or its root $data ' +
'- just set it to null.'
)
return
}
if (!hasOwn(obj, key)) {
if (!hasOwn(target, key)) {
return
}
delete obj[key]
delete target[key]
if (!ob) {
return
}

4
test/unit/modules/observer/observer.spec.js

@ -312,7 +312,7 @@ describe('Observer', () => {
data
}).$mount()
expect(vm.$el.outerHTML).toBe('<div>1</div>')
Vue.set(data, 'a', 2)
expect(Vue.set(data, 'a', 2)).toBe(2)
waitForUpdate(() => {
expect(vm.$el.outerHTML).toBe('<div>2</div>')
expect('Avoid adding reactive properties to a Vue instance').not.toHaveBeenWarned()
@ -320,7 +320,7 @@ describe('Observer', () => {
}).then(() => {
expect('Avoid deleting properties on a Vue instance').toHaveBeenWarned()
expect(vm.$el.outerHTML).toBe('<div>2</div>')
Vue.set(data, 'b', 123)
expect(Vue.set(data, 'b', 123)).toBe(123)
expect('Avoid adding reactive properties to a Vue instance').toHaveBeenWarned()
}).then(done)
})

Loading…
Cancel
Save