• vue组件内的元素转移到指定位置


    应用场景:

    组件内的dom默认是在 组件内,有时候会出现一些问题:我们封装的组件使用了actionsheet 啊,popup啊,这些 如果不直接在body下,会出现一些样式层叠问题(因为z-index)。这时候如果可以将 引发问题的dom 挪到body下,就好了。

    一些理解:

    1、来源

    下面的代码摘自于 vux 的previewer组件源代码,而它又是 借鉴于 https://github.com/calebroseland/vue-dom-portal     。
    两者大同小异,仅仅是多做了一步操作:给指令所在元素加了 一个 v-transfer-dom 类名(猜想:提醒开发者 该元素的用途)。

    2、代码思想

    用一个注释标签 替换 目标元素,目标元素被挪到指定的元素下(默认body)。

    学习代码:

    // Thanks to: https://github.com/calebroseland/vue-dom-portal
    
    /**
     * Get target DOM Node
     * @param {(Node|string|Boolean)} [node=document.body] DOM Node, CSS selector, or Boolean
     * @return {Node} The target that the el will be appended to
     */
    function getTarget (node) {
      if (node === void 0) {
        return document.body
      }
    
      if (typeof node === 'string' && node.indexOf('?') === 0) {
        return document.body
      } else if (typeof node === 'string' && node.indexOf('?') > 0) {
        node = node.split('?')[0]
      }
    
      if (node === 'body' || node === true) {
        return document.body
      }
    
      return node instanceof window.Node ? node : document.querySelector(node)
    }
    
    function getShouldUpdate (node) {
      // do not updated by default
      if (!node) {
        return false
      }
      if (typeof node === 'string' && node.indexOf('?') > 0) {
        try {
          const config = JSON.parse(node.split('?')[1])
          return config.autoUpdate || false
        } catch (e) {
          return false
        }
      }
      return false
    }
    
    const directive = {
      inserted (el, { value }, vnode) {
        el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom'
        const parentNode = el.parentNode
        var home = document.createComment('')
        var hasMovedOut = false
    
        if (value !== false) {
          parentNode.replaceChild(home, el) // moving out, el is no longer in the document
          getTarget(value).appendChild(el) // moving into new place
          hasMovedOut = true
        }
        if (!el.__transferDomData) {
          el.__transferDomData = {
            parentNode: parentNode,
            home: home,
            target: getTarget(value),
            hasMovedOut: hasMovedOut
          }
        }
      },
      componentUpdated (el, { value }) {
        const shouldUpdate = getShouldUpdate(value)
        if (!shouldUpdate) {
          return
        }
        // need to make sure children are done updating (vs. `update`)
        var ref$1 = el.__transferDomData
        // homes.get(el)
        var parentNode = ref$1.parentNode
        var home = ref$1.home
        var hasMovedOut = ref$1.hasMovedOut // recall where home is
    
        if (!hasMovedOut && value) {
          // remove from document and leave placeholder
          parentNode.replaceChild(home, el)
          // append to target
          getTarget(value).appendChild(el)
          el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: true, target: getTarget(value) })
        } else if (hasMovedOut && value === false) {
          // previously moved, coming back home
          parentNode.replaceChild(el, home)
          el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: false, target: getTarget(value) })
        } else if (value) {
          // already moved, going somewhere else
          getTarget(value).appendChild(el)
        }
      },
      unbind: function unbind (el, binding) {
        el.className = el.className.replace('v-transfer-dom', '')
        if (el.__transferDomData && el.__transferDomData.hasMovedOut === true) {
          el.__transferDomData.parentNode && el.__transferDomData.parentNode.appendChild(el)
        }
        el.__transferDomData = null
      }
    }
    
    export default directive
  • 相关阅读:
    java中检测网络是否相通
    springBoot学习资料
    mybatis-Plus 增强版用法收藏
    idea生成springBoot 报错403
    java中所有开源注解收集
    JsonCpp操作数组对象
    第三方库 jsoncpp 读写json
    c++ 判断是64还是32位系统
    c++ 读写结构体到文件
    c/c++ 按照行读取文件
  • 原文地址:https://www.cnblogs.com/fan-zha/p/11165639.html
Copyright © 2020-2023  润新知