Closed MR-ZiWeiter closed 3 months ago
原因:由于在shadow-dom的事件传递机制不同导致的
事件捕获阶段: 事件首先从文档的根节点开始向下传播。 在 Shadow DOM 中,事件会先到达 Shadow Root 节点,然后继续向下传播到 Shadow DOM 内部的元素。
事件冒泡阶段: 事件从内部元素开始向上冒泡。 在 Shadow DOM 中,事件首先从内部元素冒泡到 Shadow Root 节点,然后再冒泡到外部 DOM 结构。
步凑 1、在子应用中将容器的container存储
mount(props) { document.parentContainer = props.container; // 其他代码 ... }
2、将element-ui目录下node_modules/element-ui/src/utils/clickoutside.js拷贝下来到自己的目录 3、改变该文件内容
node_modules/element-ui/src/utils/clickoutside.js
// import Vue from 'vue'; // import { on } from 'element-ui/src/utils/dom'; const nodeList = []; const ctx = '@@clickoutsideContext'; let startClickTarget; let seed = 0; // !Vue.prototype.$isServer && on(document, 'mousedown', e => { // console.log(e); // startClick = e // }); // 添加事件监听器到 Shadow DOM 的根节点 (document.parentContainer || document).addEventListener('mousedown', (event) => { startClickTarget = event.composedPath()[0]; }, true); // 第三个参数为 true,监听捕获阶段 // 添加事件监听器到 Shadow DOM 的根节点 (document.parentContainer || document).addEventListener('mouseup', (event) => { nodeList.forEach(node => node[ctx].documentHandler(event.composedPath()[0], startClickTarget)); }, true); // 第三个参数为 true,监听捕获阶段 // !Vue.prototype.$isServer && on(document.parentContainer || document, 'mouseup', e => { // console.log(document.parentContainer) // nodeList.forEach(node => node[ctx].documentHandler(e, startClick)); // }); function createDocumentHandler(el, binding, vnode) { return function(mouseup = {}, mousedown = {}) { if (!vnode || !vnode.context || !mouseup || !mousedown || el.contains(mouseup) || el.contains(mousedown) || el === mouseup || (vnode.context.popperElm && (vnode.context.popperElm.contains(mouseup) || vnode.context.popperElm.contains(mousedown)))) return; if (binding.expression && el[ctx].methodName && vnode.context[el[ctx].methodName]) { vnode.context[el[ctx].methodName](); } else { el[ctx].bindingFn && el[ctx].bindingFn(); } }; } /** * v-clickoutside * @desc 点击元素外面才会触发的事件 * @example * ```vue * <div v-element-clickoutside="handleClose"> * ``` */ export default { bind(el, binding, vnode) { console.log(el); nodeList.push(el); const id = seed++; el[ctx] = { id, documentHandler: createDocumentHandler(el, binding, vnode), methodName: binding.expression, bindingFn: binding.value }; }, update(el, binding, vnode) { el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); el[ctx].methodName = binding.expression; el[ctx].bindingFn = binding.value; }, unbind(el) { let len = nodeList.length; for (let i = 0; i < len; i++) { if (nodeList[i][ctx].id === el[ctx].id) { nodeList.splice(i, 1); break; } } delete el[ctx]; } };
4、注册该指令覆盖原有的即可
Vue.directive('clickoutside', clickoutside)
由于缺乏足够的信息(github、stackblitz、codesandbox等可复现仓库),我们暂时关闭了该 Issue。请修改(不要回复) Issue 提供最小重现以重新开启。谢谢。如果只是单独的技术咨询,可移步 https://qiankun.umijs.org/#-community 交流~
原因:由于在shadow-dom的事件传递机制不同导致的
事件捕获阶段: 事件首先从文档的根节点开始向下传播。 在 Shadow DOM 中,事件会先到达 Shadow Root 节点,然后继续向下传播到 Shadow DOM 内部的元素。
事件冒泡阶段: 事件从内部元素开始向上冒泡。 在 Shadow DOM 中,事件首先从内部元素冒泡到 Shadow Root 节点,然后再冒泡到外部 DOM 结构。
步凑 1、在子应用中将容器的container存储
2、将element-ui目录下
node_modules/element-ui/src/utils/clickoutside.js
拷贝下来到自己的目录 3、改变该文件内容4、注册该指令覆盖原有的即可