Skip to content

Commit ada90e5

Browse files
committed
revert directive bind invocation timing, add inserted hook for directives
1 parent 32971d8 commit ada90e5

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

src/core/vdom/modules/directives.js

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,18 @@ import { mergeVNodeHook } from 'core/vdom/helpers'
55

66
export default {
77
create: function bindDirectives (oldVnode: VNodeWithData, vnode: VNodeWithData) {
8-
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', () => {
9-
applyDirectives(oldVnode, vnode, 'bind')
8+
let hasInsert = false
9+
forEachDirective(oldVnode, vnode, (def, dir) => {
10+
callHook(def, dir, 'bind', vnode, oldVnode)
11+
if (def.inserted) {
12+
hasInsert = true
13+
}
1014
})
15+
if (hasInsert) {
16+
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', () => {
17+
applyDirectives(oldVnode, vnode, 'inserted')
18+
})
19+
}
1120
},
1221
update: function updateDirectives (oldVnode: VNodeWithData, vnode: VNodeWithData) {
1322
applyDirectives(oldVnode, vnode, 'update')
@@ -27,28 +36,43 @@ export default {
2736

2837
const emptyModifiers = Object.create(null)
2938

30-
function applyDirectives (
39+
function forEachDirective (
3140
oldVnode: VNodeWithData,
3241
vnode: VNodeWithData,
33-
hook: string
42+
fn: Function
3443
) {
3544
const dirs = vnode.data.directives
3645
if (dirs) {
37-
const oldDirs = oldVnode.data.directives
38-
const isUpdate = hook === 'update' || hook === 'componentUpdated'
3946
for (let i = 0; i < dirs.length; i++) {
4047
const dir = dirs[i]
4148
const def = resolveAsset(vnode.context.$options, 'directives', dir.name, true)
42-
const fn = def && def[hook]
43-
if (fn) {
44-
if (isUpdate && oldDirs) {
49+
if (def) {
50+
const oldDirs = oldVnode && oldVnode.data.directives
51+
if (oldDirs) {
4552
dir.oldValue = oldDirs[i].value
4653
}
4754
if (!dir.modifiers) {
4855
dir.modifiers = emptyModifiers
4956
}
50-
fn(vnode.elm, dir, vnode, oldVnode)
57+
fn(def, dir)
5158
}
5259
}
5360
}
5461
}
62+
63+
function applyDirectives (
64+
oldVnode: VNodeWithData,
65+
vnode: VNodeWithData,
66+
hook: string
67+
) {
68+
forEachDirective(oldVnode, vnode, (def, dir) => {
69+
callHook(def, dir, hook, vnode, oldVnode)
70+
})
71+
}
72+
73+
function callHook (def, dir, hook, vnode, oldVnode) {
74+
const fn = def && def[hook]
75+
if (fn) {
76+
fn(vnode.elm, dir, vnode, oldVnode)
77+
}
78+
}

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Vue from 'vue'
33
describe('Options directives', () => {
44
it('basic usage', done => {
55
const bindSpy = jasmine.createSpy('bind')
6+
const insertedSpy = jasmine.createSpy('inserted')
67
const updateSpy = jasmine.createSpy('update')
78
const componentUpdatedSpy = jasmine.createSpy('componentUpdated')
89
const unbindSpy = jasmine.createSpy('unbind')
@@ -14,7 +15,7 @@ describe('Options directives', () => {
1415
}
1516

1617
const vm = new Vue({
17-
template: '<div v-if="ok" v-test:arg.hello="a">{{ msg }}</div>',
18+
template: '<div class="hi"><div v-if="ok" v-test:arg.hello="a">{{ msg }}</div></div>',
1819
data: {
1920
msg: 'hi',
2021
a: 'foo',
@@ -28,11 +29,20 @@ describe('Options directives', () => {
2829
expect(binding.value).toBe('foo')
2930
expect(binding.expression).toBe('a')
3031
expect(binding.oldValue).toBeUndefined()
32+
expect(el.parentNode).toBeNull()
33+
},
34+
inserted (el, binding, vnode) {
35+
insertedSpy()
36+
assertContext(el, binding, vnode)
37+
expect(binding.value).toBe('foo')
38+
expect(binding.expression).toBe('a')
39+
expect(binding.oldValue).toBeUndefined()
40+
expect(el.parentNode.className).toBe('hi')
3141
},
3242
update (el, binding, vnode, oldVnode) {
3343
updateSpy()
3444
assertContext(el, binding, vnode)
35-
expect(el).toBe(vm.$el)
45+
expect(el).toBe(vm.$el.children[0])
3646
expect(oldVnode).not.toBe(vnode)
3747
expect(binding.expression).toBe('a')
3848
if (binding.value !== binding.oldValue) {
@@ -54,6 +64,7 @@ describe('Options directives', () => {
5464

5565
vm.$mount()
5666
expect(bindSpy).toHaveBeenCalled()
67+
expect(insertedSpy).toHaveBeenCalled()
5768
expect(updateSpy).not.toHaveBeenCalled()
5869
expect(componentUpdatedSpy).not.toHaveBeenCalled()
5970
expect(unbindSpy).not.toHaveBeenCalled()

0 commit comments

Comments
 (0)