Browse Source

prohibit Vue.set/delete on Vue instances

dev
Evan You 9 years ago
parent
commit
d6ced71719
  1. 19
      src/core/observer/index.js
  2. 12
      test/unit/features/directives/for.spec.js
  3. 11
      test/unit/modules/observer/observer.spec.js

19
src/core/observer/index.js

@ -9,7 +9,8 @@ import {
isPlainObject,
hasProto,
hasOwn,
isReserved
isReserved,
warn
} from '../util/index'
const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
@ -233,7 +234,10 @@ export function set (obj, key, val) {
return
}
if (obj._isVue) {
set(obj._data, key, val)
process.env.NODE_ENV !== 'production' && warn(
'Do not add reactive properties to a Vue instance at runtime - ' +
'delcare it upfront in the data option.'
)
return
}
const ob = obj.__ob__
@ -261,17 +265,18 @@ export function set (obj, key, val) {
* @param {String} key
*/
export function del (obj, key) {
if (obj._isVue) {
process.env.NODE_ENV !== 'production' && warn(
'Do not delete properties on a Vue instance - just set it to null.'
)
return
}
if (!hasOwn(obj, key)) {
return
}
delete obj[key]
const ob = obj.__ob__
if (!ob) {
if (obj._isVue) {
delete obj._data[key]
obj.$forceUpdate()
}
return
}
ob.dep.notify()

12
test/unit/features/directives/for.spec.js

@ -102,12 +102,6 @@ describe('Directive v-for', () => {
vm.a = 3
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('<span>3-a</span><span>1-b</span><span>2-c</span>')
Vue.set(vm, 'd', 4)
}).then(() => {
expect(vm.$el.innerHTML).toBe('<span>3-a</span><span>1-b</span><span>2-c</span><span>4-d</span>')
Vue.delete(vm, 'a')
}).then(() => {
expect(vm.$el.innerHTML).toBe('<span>1-b</span><span>2-c</span><span>4-d</span>')
done()
}).catch(done)
})
@ -214,12 +208,6 @@ describe('Directive v-for', () => {
vm.a = 3
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('<span>3-a</span><span>1-b</span><span>2-c</span>')
Vue.set(vm, 'd', 4)
}).then(() => {
expect(vm.$el.innerHTML).toBe('<span>3-a</span><span>1-b</span><span>2-c</span><span>4-d</span>')
Vue.delete(vm, 'a')
}).then(() => {
expect(vm.$el.innerHTML).toBe('<span>1-b</span><span>2-c</span><span>4-d</span>')
done()
}).catch(done)
})

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

@ -281,19 +281,22 @@ describe('Observer', () => {
expect(dep3.notify.calls.count()).toBe(2)
})
it('observing set/delete in Vm object', done => {
it('warning set/delete on a Vue instance', done => {
const vm = new Vue({
template: '<div>{{a}}</div>',
data: { a: 1 }
})
vm.$mount()
}).$mount()
expect(vm.$el.outerHTML).toBe('<div>1</div>')
Vue.set(vm, 'a', 2)
waitForUpdate(() => {
expect(vm.$el.outerHTML).toBe('<div>2</div>')
expect('Do not add reactive properties to a Vue instance').not.toHaveBeenWarned()
Vue.delete(vm, 'a')
}).then(() => {
expect(vm.$el.outerHTML).toBe('<div></div>')
expect('Do not delete properties on a Vue instance').toHaveBeenWarned()
expect(vm.$el.outerHTML).toBe('<div>2</div>')
Vue.set(vm, 'b', 123)
expect('Do not add reactive properties to a Vue instance').toHaveBeenWarned()
done()
}).catch(done)
})

Loading…
Cancel
Save