Skip to content

Commit 7065f11

Browse files
yyx990803ztlevi
authored andcommitted
fix(directive): should invoke unbind & inserted on inner component root element change
fix vuejs#6513
1 parent 5b22e10 commit 7065f11

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/core/vdom/patch.js

+10
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,16 @@ export function createPatchFunction (backend) {
670670
for (let i = 0; i < cbs.create.length; ++i) {
671671
cbs.create[i](emptyNode, ancestor)
672672
}
673+
// #6513
674+
// invoke insert hooks that may have been merged by create hooks.
675+
// e.g. for directives that uses the "inserted" hook.
676+
const insert = ancestor.data.hook.insert
677+
if (insert.merged) {
678+
// start at index 1 to avoid re-invoking component mounted hook
679+
for (let i = 1; i < insert.fns.length; i++) {
680+
insert.fns[i]()
681+
}
682+
}
673683
}
674684
ancestor = ancestor.parent
675685
}

test/unit/features/options/directives.spec.js

+38
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,42 @@ describe('Options directives', () => {
227227
}).$mount()
228228
expect('Failed to resolve directive: test').toHaveBeenWarned()
229229
})
230+
231+
// #6513
232+
it('should invoke unbind & inserted on inner component root element change', done => {
233+
const dir = {
234+
bind: jasmine.createSpy('bind'),
235+
inserted: jasmine.createSpy('inserted'),
236+
unbind: jasmine.createSpy('unbind')
237+
}
238+
239+
const Child = {
240+
template: `<div v-if="ok"/><span v-else/>`,
241+
data: () => ({ ok: true })
242+
}
243+
244+
const vm = new Vue({
245+
template: `<child ref="child" v-test />`,
246+
directives: { test: dir },
247+
components: { Child }
248+
}).$mount()
249+
250+
const oldEl = vm.$el
251+
expect(dir.bind.calls.count()).toBe(1)
252+
expect(dir.bind.calls.argsFor(0)[0]).toBe(oldEl)
253+
expect(dir.inserted.calls.count()).toBe(1)
254+
expect(dir.inserted.calls.argsFor(0)[0]).toBe(oldEl)
255+
expect(dir.unbind).not.toHaveBeenCalled()
256+
257+
vm.$refs.child.ok = false
258+
waitForUpdate(() => {
259+
expect(vm.$el.tagName).toBe('SPAN')
260+
expect(dir.bind.calls.count()).toBe(2)
261+
expect(dir.bind.calls.argsFor(1)[0]).toBe(vm.$el)
262+
expect(dir.inserted.calls.count()).toBe(2)
263+
expect(dir.inserted.calls.argsFor(1)[0]).toBe(vm.$el)
264+
expect(dir.unbind.calls.count()).toBe(1)
265+
expect(dir.unbind.calls.argsFor(0)[0]).toBe(oldEl)
266+
}).then(done)
267+
})
230268
})

0 commit comments

Comments
 (0)