fix style diffing on cached/slot elements (fix #5318)

This commit is contained in:
Evan You 2017-04-03 14:13:57 +08:00
parent 6622839068
commit a12d32a56d
3 changed files with 30 additions and 3 deletions

View File

@ -40,6 +40,7 @@ declare interface VNodeData {
class?: any;
staticStyle?: { [key: string]: any };
style?: Array<Object> | Object;
normalizedStyle?: Object;
props?: { [key: string]: any };
attrs?: { [key: string]: string };
domProps?: { [key: string]: any };

View File

@ -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)

View File

@ -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: `<test><div :style="style"/></test>`,
data: {
style: { color: 'red' }
},
components: {
test: {
template: `<div><slot/></div>`
}
}
}).$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)
})
})