Skip to content

Commit

Permalink
unbind v-show if no longer present during patch (fix #4484)
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Dec 21, 2016
1 parent 5c34b1b commit a977642
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/core/vdom/modules/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function updateDirectives (oldVnode: VNodeWithData, vnode: VNodeWithData) {

function _update (oldVnode, vnode) {
const isCreate = oldVnode === emptyNode
const isDestroy = vnode === emptyNode
const oldDirs = normalizeDirectives(oldVnode.data.directives, oldVnode.context)
const newDirs = normalizeDirectives(vnode.data.directives, vnode.context)

Expand Down Expand Up @@ -71,7 +72,7 @@ function _update (oldVnode, vnode) {
for (key in oldDirs) {
if (!newDirs[key]) {
// no longer present, unbind
callHook(oldDirs[key], 'unbind', oldVnode)
callHook(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy)
}
}
}
Expand Down Expand Up @@ -103,9 +104,9 @@ function getRawDirName (dir: VNodeDirective): string {
return dir.rawName || `${dir.name}.${Object.keys(dir.modifiers || {}).join('.')}`
}

function callHook (dir, hook, vnode, oldVnode) {
function callHook (dir, hook, vnode, oldVnode, isDestroy) {
const fn = dir.def && dir.def[hook]
if (fn) {
fn(vnode.elm, dir, vnode, oldVnode)
fn(vnode.elm, dir, vnode, oldVnode, isDestroy)
}
}
13 changes: 13 additions & 0 deletions src/platforms/web/runtime/directives/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default {
el.style.display = value ? originalDisplay : 'none'
}
},

update (el: any, { value, oldValue }: VNodeDirective, vnode: VNodeWithData) {
/* istanbul ignore if */
if (value === oldValue) return
Expand All @@ -44,5 +45,17 @@ export default {
} else {
el.style.display = value ? el.__vOriginalDisplay : 'none'
}
},

unbind (
el: any,
binding: VNodeDirective,
vnode: VNodeWithData,
oldVnode: VNodeWithData,
isDestroy: boolean
) {
if (!isDestroy) {
el.style.display = el.__vOriginalDisplay
}
}
}
17 changes: 17 additions & 0 deletions test/unit/features/directives/show.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,21 @@ describe('Directive v-show', () => {
expect(vm.$el.firstChild.style.display).toBe('block')
}).then(done)
})

it('should support unbind when reused', done => {
const vm = new Vue({
template:
'<div v-if="tester"><span v-show="false"></span></div>' +
'<div v-else><span @click="tester=!tester">show</span></div>',
data: { tester: true }
}).$mount()
expect(vm.$el.firstChild.style.display).toBe('none')
vm.tester = false
waitForUpdate(() => {
expect(vm.$el.firstChild.style.display).toBe('')
vm.tester = true
}).then(() => {
expect(vm.$el.firstChild.style.display).toBe('none')
}).then(done)
})
})

0 comments on commit a977642

Please sign in to comment.