From a12d32a56df2519c9cdf8d2da9d9425876263f89 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 3 Apr 2017 14:13:57 +0800 Subject: [PATCH] fix style diffing on cached/slot elements (fix #5318) --- flow/vnode.js | 1 + src/platforms/web/runtime/modules/style.js | 11 ++++++++--- test/unit/features/directives/style.spec.js | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/flow/vnode.js b/flow/vnode.js index 5d06d322e21..0966ddc03ee 100644 --- a/flow/vnode.js +++ b/flow/vnode.js @@ -40,6 +40,7 @@ declare interface VNodeData { class?: any; staticStyle?: { [key: string]: any }; style?: Array | Object; + normalizedStyle?: Object; props?: { [key: string]: any }; attrs?: { [key: string]: string }; domProps?: { [key: string]: any }; diff --git a/src/platforms/web/runtime/modules/style.js b/src/platforms/web/runtime/modules/style.js index 0519421b7cd..3b0033c4d22 100644 --- a/src/platforms/web/runtime/modules/style.js +++ b/src/platforms/web/runtime/modules/style.js @@ -45,15 +45,20 @@ function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) { let cur, name const el: any = vnode.elm - const oldStaticStyle: any = oldVnode.data.staticStyle - const oldStyleBinding: any = oldVnode.data.style || {} + const oldStaticStyle: any = oldData.staticStyle + const oldStyleBinding: any = oldData.normalizedStyle || oldData.style || {} // if static style exists, stylebinding already merged into it when doing normalizeStyleData const oldStyle = oldStaticStyle || oldStyleBinding const style = normalizeStyleBinding(vnode.data.style) || {} - vnode.data.style = style.__ob__ ? extend({}, style) : style + // store normalized style under a different key for next diff + // make sure to clone it if it's reactive, since the user likley wants + // to mutate it. + vnode.data.normalizedStyle = style.__ob__ + ? extend({}, style) + : style const newStyle = getStyle(vnode, true) diff --git a/test/unit/features/directives/style.spec.js b/test/unit/features/directives/style.spec.js index 469a5115849..1523b5a67eb 100644 --- a/test/unit/features/directives/style.spec.js +++ b/test/unit/features/directives/style.spec.js @@ -346,4 +346,25 @@ describe('Directive v-bind:style', () => { expect(style.marginTop).toBe('12px') }).then(done) }) + + // #5318 + it('should work for elements passed down as a slot', done => { + const vm = new Vue({ + template: `
`, + data: { + style: { color: 'red' } + }, + components: { + test: { + template: `
` + } + } + }).$mount() + + expect(vm.$el.children[0].style.color).toBe('red') + vm.style.color = 'green' + waitForUpdate(() => { + expect(vm.$el.children[0].style.color).toBe('green') + }).then(done) + }) })