Skip to content

Commit a977642

Browse files
committed
unbind v-show if no longer present during patch (fix #4484)
1 parent 5c34b1b commit a977642

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

Diff for: src/core/vdom/modules/directives.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function updateDirectives (oldVnode: VNodeWithData, vnode: VNodeWithData) {
2020

2121
function _update (oldVnode, vnode) {
2222
const isCreate = oldVnode === emptyNode
23+
const isDestroy = vnode === emptyNode
2324
const oldDirs = normalizeDirectives(oldVnode.data.directives, oldVnode.context)
2425
const newDirs = normalizeDirectives(vnode.data.directives, vnode.context)
2526

@@ -71,7 +72,7 @@ function _update (oldVnode, vnode) {
7172
for (key in oldDirs) {
7273
if (!newDirs[key]) {
7374
// no longer present, unbind
74-
callHook(oldDirs[key], 'unbind', oldVnode)
75+
callHook(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy)
7576
}
7677
}
7778
}
@@ -103,9 +104,9 @@ function getRawDirName (dir: VNodeDirective): string {
103104
return dir.rawName || `${dir.name}.${Object.keys(dir.modifiers || {}).join('.')}`
104105
}
105106

106-
function callHook (dir, hook, vnode, oldVnode) {
107+
function callHook (dir, hook, vnode, oldVnode, isDestroy) {
107108
const fn = dir.def && dir.def[hook]
108109
if (fn) {
109-
fn(vnode.elm, dir, vnode, oldVnode)
110+
fn(vnode.elm, dir, vnode, oldVnode, isDestroy)
110111
}
111112
}

Diff for: src/platforms/web/runtime/directives/show.js

+13
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export default {
2525
el.style.display = value ? originalDisplay : 'none'
2626
}
2727
},
28+
2829
update (el: any, { value, oldValue }: VNodeDirective, vnode: VNodeWithData) {
2930
/* istanbul ignore if */
3031
if (value === oldValue) return
@@ -44,5 +45,17 @@ export default {
4445
} else {
4546
el.style.display = value ? el.__vOriginalDisplay : 'none'
4647
}
48+
},
49+
50+
unbind (
51+
el: any,
52+
binding: VNodeDirective,
53+
vnode: VNodeWithData,
54+
oldVnode: VNodeWithData,
55+
isDestroy: boolean
56+
) {
57+
if (!isDestroy) {
58+
el.style.display = el.__vOriginalDisplay
59+
}
4760
}
4861
}

Diff for: test/unit/features/directives/show.spec.js

+17
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,21 @@ describe('Directive v-show', () => {
6464
expect(vm.$el.firstChild.style.display).toBe('block')
6565
}).then(done)
6666
})
67+
68+
it('should support unbind when reused', done => {
69+
const vm = new Vue({
70+
template:
71+
'<div v-if="tester"><span v-show="false"></span></div>' +
72+
'<div v-else><span @click="tester=!tester">show</span></div>',
73+
data: { tester: true }
74+
}).$mount()
75+
expect(vm.$el.firstChild.style.display).toBe('none')
76+
vm.tester = false
77+
waitForUpdate(() => {
78+
expect(vm.$el.firstChild.style.display).toBe('')
79+
vm.tester = true
80+
}).then(() => {
81+
expect(vm.$el.firstChild.style.display).toBe('none')
82+
}).then(done)
83+
})
6784
})

0 commit comments

Comments
 (0)