vue源碼分析(二十三)Vue之指令(v-show)

我們打開(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'
    }
  }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容