From ec29fda9448236defc19eef306ded1c2026a1d2c Mon Sep 17 00:00:00 2001 From: javoski Date: Sat, 3 Feb 2018 06:28:29 +0800 Subject: [PATCH 1/6] add failed test case --- test/unit/features/options/data.spec.js | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/unit/features/options/data.spec.js b/test/unit/features/options/data.spec.js index cb8a75ad18d..ac431bbd939 100644 --- a/test/unit/features/options/data.spec.js +++ b/test/unit/features/options/data.spec.js @@ -93,6 +93,38 @@ describe('Options data', () => { expect(vm.$refs.test.b).toBe(1) }) + it('props should not be reactive', done => { + let calls = 0 + const vm = new Vue({ + template: ``, + data: { + msg: 'hello' + }, + beforeUpdate () { calls++ }, + components: { + child: { + template: `{{ localMsg }}`, + props: ['msg'], + data () { + return { localMsg: this.msg } + }, + computed: { + computedMsg () { + return this.msg + ' world' + } + } + } + } + }).$mount() + const child = vm.$children[0] + vm.msg = 'hi' + waitForUpdate(() => { + expect(child.localMsg).toBe('hello') + expect(child.computedMsg).toBe('hi world') + expect(calls).toBe(1) + }).then(done) + }) + it('should have access to methods', () => { const vm = new Vue({ methods: { From 705a3a83a50c8c4a03df0bf1d9e56fac3ff949fd Mon Sep 17 00:00:00 2001 From: javoski Date: Sat, 3 Feb 2018 06:32:02 +0800 Subject: [PATCH 2/6] fix(core): props used in data option shouldn't be reactive --- src/core/instance/state.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index a42638a13f7..6ea4b203711 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -150,11 +150,15 @@ function initData (vm: Component) { } export function getData (data: Function, vm: Component): any { + const prevTarget = Dep.target + Dep.target = null try { return data.call(vm, vm) } catch (e) { handleError(e, vm, `data()`) return {} + } finally { + Dep.target = prevTarget } } From 2c5c34a7a3526162240d7eeccc8e9461d3240c82 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 9 Mar 2018 13:02:15 -0500 Subject: [PATCH 3/6] Update state.js --- src/core/instance/state.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index 6ea4b203711..c4aae3dcce1 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -1,8 +1,8 @@ /* @flow */ import config from '../config' -import Dep from '../observer/dep' import Watcher from '../observer/watcher' +import Dep, { pushTarget, popTarget } from '../observer/dep' import { isUpdatingChildComponent } from './lifecycle' import { @@ -150,15 +150,14 @@ function initData (vm: Component) { } export function getData (data: Function, vm: Component): any { - const prevTarget = Dep.target - Dep.target = null + pushTarget() try { return data.call(vm, vm) } catch (e) { handleError(e, vm, `data()`) return {} } finally { - Dep.target = prevTarget + popTarget() } } From 616356de37ea1a663681501574354b014e3362bc Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 9 Mar 2018 13:03:01 -0500 Subject: [PATCH 4/6] Update lifecycle.js --- src/core/instance/lifecycle.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/instance/lifecycle.js b/src/core/instance/lifecycle.js index 27756af66fc..c9c3b43c1ae 100644 --- a/src/core/instance/lifecycle.js +++ b/src/core/instance/lifecycle.js @@ -7,6 +7,7 @@ import { createEmptyVNode } from '../vdom/vnode' import { observerState } from '../observer/index' import { updateComponentListeners } from './events' import { resolveSlots } from './render-helpers/resolve-slots' +import { pushTarget, popTarget } from '../observer/dep' import { warn, @@ -315,6 +316,8 @@ export function deactivateChildComponent (vm: Component, direct?: boolean) { } export function callHook (vm: Component, hook: string) { + // #7573 disable dep collection when invoking lifecycle hooks + pushTarget() const handlers = vm.$options[hook] if (handlers) { for (let i = 0, j = handlers.length; i < j; i++) { @@ -328,4 +331,5 @@ export function callHook (vm: Component, hook: string) { if (vm._hasHookEvent) { vm.$emit('hook:' + hook) } + popTarget() } From 3cc84fa85242965680e5c4114de7a893ba890de3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 9 Mar 2018 13:03:20 -0500 Subject: [PATCH 5/6] Update state.js --- src/core/instance/state.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index c4aae3dcce1..b3888252094 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -150,6 +150,7 @@ function initData (vm: Component) { } export function getData (data: Function, vm: Component): any { + // #7573 disable dep collection when invoking data getters pushTarget() try { return data.call(vm, vm) From 8275226a445fe2d2a3d612619b39753e570c29fd Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 9 Mar 2018 13:09:28 -0500 Subject: [PATCH 6/6] Update dep.js --- src/core/observer/dep.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/observer/dep.js b/src/core/observer/dep.js index 5d55e9cd421..abf3b275ce4 100644 --- a/src/core/observer/dep.js +++ b/src/core/observer/dep.js @@ -48,7 +48,7 @@ export default class Dep { Dep.target = null const targetStack = [] -export function pushTarget (_target: Watcher) { +export function pushTarget (_target: ?Watcher) { if (Dep.target) targetStack.push(Dep.target) Dep.target = _target }