diff --git a/src/core/vdom/patch.js b/src/core/vdom/patch.js index fb28d8cd341..ec70b9f685a 100644 --- a/src/core/vdom/patch.js +++ b/src/core/vdom/patch.js @@ -44,7 +44,7 @@ function sameVnode (a, b) { isTrue(a.isAsyncPlaceholder) && a.asyncFactory === b.asyncFactory && isUndef(b.asyncFactory.error) - ) + ) || sameStaticVnode(a, b) ) ) } @@ -57,6 +57,12 @@ function sameInputType (a, b) { return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB) } +function sameStaticVnode (a, b) { + return isTrue(a.isStatic) && + isTrue(b.isStatic) && + (isTrue(b.isCloned) || isTrue(b.isOnce)) +} + function createKeyToOldIdx (children, beginIdx, endIdx) { let i, key const map = {} @@ -518,10 +524,9 @@ export function createPatchFunction (backend) { // note we only do this if the vnode is cloned - // if the new node is not cloned it means the render functions have been // reset by the hot-reload-api and we need to do a proper re-render. - if (isTrue(vnode.isStatic) && - isTrue(oldVnode.isStatic) && - vnode.key === oldVnode.key && - (isTrue(vnode.isCloned) || isTrue(vnode.isOnce)) + if ( + sameStaticVnode(oldVnode, vnode) && + vnode.key === oldVnode.key ) { vnode.componentInstance = oldVnode.componentInstance return diff --git a/test/unit/features/directives/once.spec.js b/test/unit/features/directives/once.spec.js index eca8be0a3ef..90fb7e85be9 100644 --- a/test/unit/features/directives/once.spec.js +++ b/test/unit/features/directives/once.spec.js @@ -176,6 +176,42 @@ describe('Directive v-once', () => { }).then(done) }) + it('should work inside v-for in component', done => { + const vm = new Vue({ + data: { + comp: 'comp1', + list: [ + { id: 0 } + ] + }, + components: { + comp1: { + template: 'comp1' + }, + comp2: { + template: 'comp2' + } + }, + template: ` +