UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

136 lines (113 loc) • 3.39 kB
// Thanks to: https://github.com/airyland/vux/blob/v2/src/directives/transfer-dom/index.js // 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) { node = document.body; } if (node === true) { return document.body; } return node instanceof window.Node ? node : document.querySelector(node); } // 指令定义 function beforeMount(el: any, { value }) { if (el.dataset && el.dataset.transfer !== 'true') { return false; } el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom'; const parentNode = el.parentNode; // 没有父节点 if (!parentNode) { return; } const home = document.createComment(''); let hasMovedOut = false; if (value !== false) { // moving out, el is no longer in the document parentNode.replaceChild(home, el); // 移动到新的地方 getTarget(value).appendChild(el); hasMovedOut = true; } if (!el.__transferDomData) { el.__transferDomData = { parentNode: parentNode, home: home, target: getTarget(value), hasMovedOut: hasMovedOut, }; } } /** * 所在组件的 VNode 更新时调用 * * el: HTMLElement, binding: VNodeDirective */ function updated(el: Record<string, any>, { value }) { if (el.dataset && el.dataset.transfer !== 'true') { return false; } // need to make sure children are done updating (vs. `update`) // 需要确保孩子完成更新(相对于 `update`) const ref$1 = el.__transferDomData; // 没有创建节点初始化创建 if (!ref$1) { beforeMount(el, { value }); return; } // homes.get(el) const parentNode = ref$1.parentNode; const home = ref$1.home; // recall where home is const hasMovedOut = ref$1.hasMovedOut; 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); } } // 指令与元素解绑时调用 function unmounted(el) { if (el.dataset && el.dataset.transfer !== 'true') { return false; } el.className = el.className.replace('v-transfer-dom', ''); const ref$1 = el.__transferDomData; if (!ref$1) { return; } // 移除节点 if (el.__transferDomData.hasMovedOut === true) { el.__transferDomData.parentNode && el.__transferDomData.parentNode.appendChild(el); } el.__transferDomData = null; } export default { beforeMount, unmounted, updated, };