我們打開(kāi)文件 src/platforms/web/runtime/directives/show.js
/* @flow */
import { enter, leave } from '../modules/transition'
// recursively search for possible transition defined inside the component root
function locateNode (vnode: VNode): VNodeWithData {
return vnode.componentInstance && (!vnode.data || !vnode.data.transition)
? locateNode(vnode.componentInstance._vnode)
: vnode
}
export default {
bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) {
vnode = locateNode(vnode)
const transition = vnode.data && vnode.data.transition
const originalDisplay = el.__vOriginalDisplay =
el.style.display === 'none' ? '' : el.style.display
if (value && transition) {
vnode.data.show = true
enter(vnode, () => {
el.style.display = originalDisplay
})
} else {
el.style.display = value ? originalDisplay : 'none'
}
},
update (el: any, { value, oldValue }: VNodeDirective, vnode: VNodeWithData) {
/* istanbul ignore if */
if (!value === !oldValue) return
vnode = locateNode(vnode)
const transition = vnode.data && vnode.data.transition
if (transition) {
vnode.data.show = true
if (value) {
enter(vnode, () => {
el.style.display = el.__vOriginalDisplay
})
} else {
leave(vnode, () => {
el.style.display = 'none'
})
}
} 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
}
}
}
可以看到有3個(gè)方法:
1、bind // 生成DOM節(jié)點(diǎn)是時(shí)候會(huì)調(diào)用
2、update // 數(shù)據(jù)更新的時(shí)候觸發(fā)
3、unbind // 組件銷(xiāo)毀的時(shí)候,調(diào)用$destory函數(shù)
bind
bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) {
// 遞歸搜索組件內(nèi)存在是 'transition'屬性
vnode = locateNode(vnode)
// vnode 虛擬節(jié)點(diǎn)是否存在 'transition'屬性
const transition = vnode.data && vnode.data.transition
// 當(dāng)前節(jié)點(diǎn)是'node'隱藏狀態(tài),就改為‘’空
const originalDisplay = el.__vOriginalDisplay = el.style.display === 'none' ? '' : el.style.display
// value和'transition'屬性同時(shí)存在,那就是顯示出來(lái)
if (value && transition) {
vnode.data.show = true
enter(vnode, () => {
el.style.display = originalDisplay
})
} else {
// value 存在那就display 為‘’空否則就是'none'隱藏
el.style.display = value ? originalDisplay : 'none'
}
},
update
update (el: any, { value, oldValue }: VNodeDirective, vnode: VNodeWithData) {
/* istanbul ignore if */
// 先轉(zhuǎn)換成布爾值,然后再進(jìn)行對(duì)比,如果值相等就return
// 下面的邏輯就和'bind'差不多了
if (!value === !oldValue) return
vnode = locateNode(vnode)
const transition = vnode.data && vnode.data.transition
if (transition) {
vnode.data.show = true
if (value) {
enter(vnode, () => {
el.style.display = el.__vOriginalDisplay
})
} else {
leave(vnode, () => {
el.style.display = 'none'
})
}
} else {
el.style.display = value ? el.__vOriginalDisplay : 'none'
}
}