Skip to content

Commit

Permalink
fix(directive): should invoke unbind & inserted on inner component ro…
Browse files Browse the repository at this point in the history
…ot element change

fix vuejs#6513
  • Loading branch information
yyx990803 authored and hefeng committed Jan 25, 2019
1 parent e06a4d5 commit 957d0dc
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/core/vdom/patch.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,16 @@ export function createPatchFunction (backend) {
for (let i = 0; i < cbs.create.length; ++i) {
cbs.create[i](emptyNode, ancestor)
}
// #6513
// invoke insert hooks that may have been merged by create hooks.
// e.g. for directives that uses the "inserted" hook.
const insert = ancestor.data.hook.insert
if (insert.merged) {
// start at index 1 to avoid re-invoking component mounted hook
for (let i = 1; i < insert.fns.length; i++) {
insert.fns[i]()
}
}
}
ancestor = ancestor.parent
}
Expand Down
38 changes: 38 additions & 0 deletions test/unit/features/options/directives.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,42 @@ describe('Options directives', () => {
}).$mount()
expect('Failed to resolve directive: test').toHaveBeenWarned()
})

// #6513
it('should invoke unbind & inserted on inner component root element change', done => {
const dir = {
bind: jasmine.createSpy('bind'),
inserted: jasmine.createSpy('inserted'),
unbind: jasmine.createSpy('unbind')
}

const Child = {
template: `<div v-if="ok"/><span v-else/>`,
data: () => ({ ok: true })
}

const vm = new Vue({
template: `<child ref="child" v-test />`,
directives: { test: dir },
components: { Child }
}).$mount()

const oldEl = vm.$el
expect(dir.bind.calls.count()).toBe(1)
expect(dir.bind.calls.argsFor(0)[0]).toBe(oldEl)
expect(dir.inserted.calls.count()).toBe(1)
expect(dir.inserted.calls.argsFor(0)[0]).toBe(oldEl)
expect(dir.unbind).not.toHaveBeenCalled()

vm.$refs.child.ok = false
waitForUpdate(() => {
expect(vm.$el.tagName).toBe('SPAN')
expect(dir.bind.calls.count()).toBe(2)
expect(dir.bind.calls.argsFor(1)[0]).toBe(vm.$el)
expect(dir.inserted.calls.count()).toBe(2)
expect(dir.inserted.calls.argsFor(1)[0]).toBe(vm.$el)
expect(dir.unbind.calls.count()).toBe(1)
expect(dir.unbind.calls.argsFor(0)[0]).toBe(oldEl)
}).then(done)
})
})

0 comments on commit 957d0dc

Please sign in to comment.