美文网首页
vue源码分析(二十三)Vue之指令(v-show)

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

作者: vue爱好者 | 来源:发表于2020-04-22 08:24 被阅读0次

    我们打开文件 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个方法:
    1、bind // 生成DOM节点是时候会调用
    2、update // 数据更新的时候触发
    3、unbind // 组件销毁的时候,调用$destory函数

    bind

     bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) {
       // 递归搜索组件内存在是 'transition'属性
        vnode = locateNode(vnode)
        // vnode 虚拟节点是否存在 'transition'属性
        const transition = vnode.data && vnode.data.transition
        // 当前节点是'node'隐藏状态,就改为‘’空
        const originalDisplay = el.__vOriginalDisplay = el.style.display === 'none' ? '' : el.style.display
        // value和'transition'属性同时存在,那就是显示出来
        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 */
       // 先转换成布尔值,然后再进行对比,如果值相等就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'
        }
      }
    

    相关文章

      网友评论

          本文标题:vue源码分析(二十三)Vue之指令(v-show)

          本文链接:https://www.haomeiwen.com/subject/taqjuhtx.html