vue 比较实用的directive封装 contextMenu

  • 其中用到vue directive extend 的用法,不理解可以看官网介绍
  • 实用方式
  
// directive.js
import Vue from 'vue'
import index from './index.vue'
import { isParentNode, on, off, preventDefault } from '@/utils/dom'
function createInstance(options) {
  return new (Vue.extend(index))({
    el: document.createElement('div'),
    propsData: options
  })
}

function handlerContextMenu(el, binding, vnode) {
  const trigger = binding.modifiers.contextmenu? 'contextmenu': undefined
  const instance = createInstance({ list: binding.value.menu, trigger, targetDom: el, id: binding.value.id, node: binding.value.node })
   el.__contextMenuInstance__ = instance  
  append(instance.$el)
}
function ContextMenu() {
  return {
    bind(el, binding, vnode) {
      handlerContextMenu(el, binding, vnode)
    },
    unbind(el, binding, vnode) {
      remove(el.__contextMenuInstance__.$el)
    }
  }
}

function append(el, parent = document.body) {
  const style = getComputedStyle(parent)
  if (['absolute', 'fixed', 'relative'].indexOf(style.position) === -1) {
    parent.style.position = 'relative'
  }
  parent.appendChild(el)
}

function remove(el) {
  var parent = el.parentNode;
  parent.removeChild(el)
}

export default ContextMenu

  // index.vue





// dom.js
export const on = (() => {
  if(document.addEventListener) {
    return function(element, event, handler, useCapture = false) {
      if (element && event && handler) {
        element.addEventListener(event, handler, useCapture);
      }
    }
  } else {
    return function(element, event, handler) {
      if(element && event && handler) {
        element.attachEvent('on' + event, handler)
      }
    }
  }
})();

export function off(target, event, handler) {
  target.removeEventListener(event, handler);
}


export function isParentNode(element, rootParent = window) {
  let node = element;
  
  while( node &&  node.tagName !== 'HTML' && node.nodeType === 1) {
    // console.log(node)
    if(node == rootParent) {
      return true
    }
    node = node.parentNode;
  }
  return null
}


export function preventDefault(event) {
  if (typeof event.cancelable !== 'boolean' || event.cancelable) {
    event.preventDefault();
  } else {
    event.stopPropagation();
  }
}


你可能感兴趣的:(vue 比较实用的directive封装 contextMenu)