From f2bd882073919add805bf359ecdf632faf9abfcd Mon Sep 17 00:00:00 2001 From: laoxiong Date: Tue, 9 May 2017 23:21:49 +0800 Subject: [PATCH] Fix: nested child elements can not be updated correctly, fix #5618 (#5627) * fix:nested elements can not be updated correctly * add tests * ensure nestedIndex is always passed down --- .../instance/render-helpers/render-list.js | 5 +++- src/core/vdom/helpers/normalize-children.js | 7 +++-- .../features/component/component-slot.spec.js | 21 ++++++++++++++ test/unit/modules/vdom/create-element.spec.js | 28 +++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/core/instance/render-helpers/render-list.js b/src/core/instance/render-helpers/render-list.js index 22cc8583..09ec4cdd 100644 --- a/src/core/instance/render-helpers/render-list.js +++ b/src/core/instance/render-helpers/render-list.js @@ -1,6 +1,6 @@ /* @flow */ -import { isObject } from 'core/util/index' +import { isObject, isDef } from 'core/util/index' /** * Runtime helper for rendering v-for lists. @@ -28,5 +28,8 @@ export function renderList ( ret[i] = render(val[key], key, i) } } + if (isDef(ret)) { + (ret: any)._isVList = true + } return ret } diff --git a/src/core/vdom/helpers/normalize-children.js b/src/core/vdom/helpers/normalize-children.js index cc400e1a..700b9b23 100644 --- a/src/core/vdom/helpers/normalize-children.js +++ b/src/core/vdom/helpers/normalize-children.js @@ -1,7 +1,7 @@ /* @flow */ import VNode, { createTextVNode } from 'core/vdom/vnode' -import { isFalse, isDef, isUndef, isPrimitive } from 'shared/util' +import { isFalse, isTrue, isDef, isUndef, isPrimitive } from 'shared/util' // The template compiler attempts to minimize the need for normalization by // statically analyzing the template at compile time. @@ -58,7 +58,10 @@ function normalizeArrayChildren (children: any, nestedIndex?: string): Array { expect(vm.$el.textContent).toBe('2foo') }).then(done) }) + + it('the elements of slot should be updated correctly', done => { + const vm = new Vue({ + data: { n: 1 }, + template: '
{{ i }}
', + components: { + test: { + template: '
' + } + } + }).$mount() + expect(vm.$el.innerHTML).toBe('
1
') + const input = vm.$el.querySelector('input') + input.value = 'b' + vm.n++ + waitForUpdate(() => { + expect(vm.$el.innerHTML).toBe('
12
') + expect(vm.$el.querySelector('input')).toBe(input) + expect(vm.$el.querySelector('input').value).toBe('b') + }).then(done) + }) }) diff --git a/test/unit/modules/vdom/create-element.spec.js b/test/unit/modules/vdom/create-element.spec.js index f937cbc5..c2f0d048 100644 --- a/test/unit/modules/vdom/create-element.spec.js +++ b/test/unit/modules/vdom/create-element.spec.js @@ -152,4 +152,32 @@ describe('create-element', () => { }).$mount() expect('Avoid using observed data object as vnode data').toHaveBeenWarned() }) + + it('nested child elements should be updated correctly', done => { + const vm = new Vue({ + data: { n: 1 }, + render (h) { + const list = [] + for (let i = 0; i < this.n; i++) { + list.push(h('span', i)) + } + const input = h('input', { + attrs: { + value: 'a', + type: 'text' + } + }) + return h('div', [[...list, input]]) + } + }).$mount() + expect(vm.$el.innerHTML).toBe('0') + const el = vm.$el.querySelector('input') + el.value = 'b' + vm.n++ + waitForUpdate(() => { + expect(vm.$el.innerHTML).toBe('01') + expect(vm.$el.querySelector('input')).toBe(el) + expect(vm.$el.querySelector('input').value).toBe('b') + }).then(done) + }) })