Просмотр исходного кода

prohibit Vue.set/delete on Vue instances

Evan You 10 лет назад
Родитель
Сommit
d6ced71719

+ 12 - 7
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()

+ 0 - 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)
     })

+ 7 - 4
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)
   })