Преглед на файлове

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

Evan You преди 9 години
родител
ревизия
a12d32a56d
променени са 3 файла, в които са добавени 30 реда и са изтрити 3 реда
  1. 1 0
      flow/vnode.js
  2. 8 3
      src/platforms/web/runtime/modules/style.js
  3. 21 0
      test/unit/features/directives/style.spec.js

+ 1 - 0
flow/vnode.js

@@ -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 };

+ 8 - 3
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)
 

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