Ver código fonte

fix: $set should respect properties on prototype chain

fix #6845
Evan You 8 anos atrás
pai
commit
83ed92608d

+ 1 - 1
src/core/observer/index.js

@@ -196,7 +196,7 @@ export function set (target: Array<any> | Object, key: any, val: any): any {
     target.splice(key, 1, val)
     return val
   }
-  if (hasOwn(target, key)) {
+  if (key in target && !(key in Object.prototype)) {
     target[key] = val
     return val
   }

+ 26 - 0
test/unit/features/global-api/set-delete.spec.js

@@ -80,6 +80,32 @@ describe('Global API: set/delete', () => {
         expect(vm.$el.innerHTML).toBe('<p>D</p><p>B</p><p>C</p>')
       }).then(done)
     })
+
+    // #6845
+    it('should not overwrite properties on prototype chain', () => {
+      class Model {
+        constructor () {
+          this._bar = null
+        }
+        get bar () {
+          return this._bar
+        }
+        set bar (newvalue) {
+          this._bar = newvalue
+        }
+      }
+
+      const vm = new Vue({
+        data: {
+          data: new Model()
+        }
+      })
+
+      Vue.set(vm.data, 'bar', 123)
+      expect(vm.data.bar).toBe(123)
+      expect(vm.data.hasOwnProperty('bar')).toBe(false)
+      expect(vm.data._bar).toBe(123)
+    })
   })
 
   describe('Vue.delete', () => {