Element-plus dropdown复用优化

182 阅读1分钟

在列表页面中使用el-dropdown会生成大量dom以及EventListener,特别是在无限加载列表中。 例如以下情况 一个无限加载的网格页面,我们通常v-for循环item,并且嵌套dropdown,此时的dom列表将会是

2.png

1.png

大量的dom被初始化,连带着一个element-plus的经典问题,内存泄漏 github.com/element-plu…

我们可以通过添加一个统一的dropdown组件,通过ref控制

<div>
    <el-dropdown ref="dropdownRef" trigger="click" :teleported="false">
      <div class="w-1 h-1 absolute top-0 left-0 bottom-0 right-0 m-auto"></div>
      <template #dropdown>
        <el-dropdown-item @click="rename(currentItem)">重命名</el-dropdown-item>
        <el-dropdown-item @click="copyProject(currentItem)">复制</el-dropdown-item>
        <el-dropdown-item @click="handleDel(currentItem)">删除</el-dropdown-item>
      </template>
    </el-dropdown>
</div>

设置ref

<script setup>
const dropdownRef = useTemplateRef('dropdownRef')
let currentItem = null
function handleDropdown(event, item) {
  currentItem = item
  const target = event.target
  if (!target) return
  const triggeringElementRef = dropdownRef.value.triggeringElementRef
  let parent = target
  // 获取到目标节点的dom
  while (!parent.classList.contains('dropdown-trigger')) {
    parent = parent.parentElement
  }
  // 将dropdown生成的triggerElement插入到目标节点
  parent.insertBefore(triggeringElementRef._.vnode.el, null)
  // 更新popper参数
  dropdownRef.value.popperRef.updatePopper()
  // 展示
  dropdownRef.value.handleOpen()
}
<script>

此时dom节点中只会有一个dropdown组件,无限加载也不用担心生成大量无效dom以及Event。

image.png