vue.js 如何在Element-Plus中获取el-popover组件的根DOM元素?

wwtsj6pe  于 12个月前  发布在  Vue.js
关注(0)|答案(1)|浏览(373)

我在Vue项目中使用Element-Plus中的el-popover组件来创建一个popover效果。代码如下:

<el-button ref="saveButtonRef" class="misc-button" :loading="saveLoading" @click="OnSheetSave">Save</el-button>
<el-popover ref="savePopoverRef" :virtual-ref="saveButtonRef" :visible="showSaveList" placement="top-start" :width="500" virtual-triggering>
   ...el-popover Content...
</el-popover>

字符串
我希望当鼠标在saveButtonRef和savePopoverRef示例之外单击时,弹出框关闭。因此,我添加了一个事件侦听器:

document.addEventListener('click', handleClickPopoverOutside);

function handleClickPopoverOutside(event) {
    if (showSaveList.value) {
        const buttonElement = saveButtonRef.value.$el;
        const popoverElement = savePopoverRef.value.$el;
        if (buttonElement && !buttonElement.contains(event.target) && popoverElement && !popoverElement.contains(event.target)) {
            OnSaveSheetPoPoverClose();     // Close Popover Instance
        }
    }
}


然而,这并没有像预期的那样工作。当我点击savePopoverRef示例时,它仍然会触发OnSaveSheetPopoverClose()函数。我发现原因是因为savePopoverRef. value.$el返回#text。是否有一种方法可以正确获取el-popover组件的根DOM元素,或者是否有其他方法可以在点击弹出框外部时关闭弹出框?
如上所述,我希望在saveButtonRef和savePopoverRef示例之外单击时能够通过触发函数OnSaveSheetPoverClose()来关闭弹出框。而且我不希望将saveButtonRef的virtual-ref从saveButtonRef更改,因为这会影响我的其他逻辑。

kb5ga3dv

kb5ga3dv1#

为了在Vue中以编程方式隐藏弹出窗口,我采用了相反的方法来处理事件。这更容易,更通用。
1.通过window.addEventListener全局监听单击事件(在窗口对象上)
1.通过@click.stop停止按钮和弹出事件
这样,我就可以捕获弹出窗口之外发生的点击事件,同时让弹出内容处理它们的点击事件。
下面是一个示例演示:

<link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css" />
<script src="//unpkg.com/vue@3"></script>
<script src="//unpkg.com/element-plus"></script>

<body>
  <div id="app">
    <el-button 
    class="misc-button"
    @click.stop="toggleDialog"
    >
    Show Dialog
    </el-button>
    
    <el-button 
    ref="saveButtonRef"
    class="misc-button"
    :loading="saveLoading"
    @click.stop="OnSheetSave"
    >
    Save
    </el-button>

    <el-popover 
    :visible="showSaveList"
    placement="top-start" 
    :width="300"
    virtual-triggering
    >
      <div style="min-width: 100px; min-height: 100px;border: 1px dashed red;" @click.stop>
        Your pop-up content goes here. Clicking anywhere on the popup won't close the modal, but clicking outside triggers the event handler and closes the modal
      </div>
    </el-popover>

  </div>
  <script>
    const App = {
      data() {
        return {
          showSaveList: false,
        };
      },
      methods: {
        OnSaveSheetPoPoverClose() {
         console.log('OnSaveSheetPoPoverClose got called');
         this.toggleDialog(); // hide dialog and remove the event listener
         this.OnSheetSave();
        },
        
        OnSheetSave(){
          console.log('OnSheetSave got called');
        },
        
        toggleDialog() {
          if (this.showSaveList) {
              this.showSaveList = false;
              window.removeEventListener('click', this.OnSaveSheetPoPoverClose);
          } else {
             this.showSaveList = true;
             window.addEventListener('click', this.OnSaveSheetPoPoverClose);
          }
        },    
      },     
    };
    const app = Vue.createApp(App);
    app.use(ElementPlus);
    app.mount("#app");
        
  </script>
</body>

字符串

说明

有一个Show Dialog按钮,它显示弹出窗口并添加事件侦听器,确保每次单击都会调用OnSaveSheetPoPoverClose
为了防止公共元素触发OnSaveSheetPoPoverClose,我使用@click.stop停止了它们的click事件(防止它传播)。
注意事项
确保在适当的时候删除事件侦听器。

相关问题