实现效果:
HTML结构:
图二:
<!--按钮 -->
<div class="add-new-user-head-icon" ref="selectDataRulesBtnRef"><app-svg-icon icon-name="add-sm" class="w-20 h-20 cursor-pointer" @click="handleAddRuleItem()"/></div>
<!-- 弹窗 -->
<div class="infinite-scroll" v-show="isShowScroll" @click.stop ref="selectDataRulesRef">
<div class="infinite-list">
<!-- 搜索输入框 -->
<div class="p-5">
<el-input v-model.trim="searchInputValue" @input="searchInputChange">
<template #prefix>
<app-svg-icon icon-name="search" class="w-19 h-19 search-icon" />
</template>
</el-input>
</div>
<!-- 滚动列表 -->
<ul class="border-t border-gray-200 py-4 overflow-y-auto flex-1">
<el-scrollbar height="200px">
<li
v-for="(item, index) in totalData.dataProcessingRulesRst"
:key="index"
class="cursor-pointer infinite-list-item overflow-hidden"
@click="handleSelectDataProcessingRule(item)"
>
<div class="flex-column">
<div class="w-250 text-ellipsis">{{ item.RuleName }}</div>
<div class="list-desc w-250 text-ellipsis">{{ '创自 ' + item.Creator + ' · ' + item.CreateTime }}</div>
</div>
</li>
</el-scrollbar>
</ul>
</div>
</div>
按钮以及弹窗区域都需要绑定ref获取dom
css样式
---弹窗的滚动列表样式----
.infinite-scroll {
.infinite-list {
position: absolute;
left: 215px;
right: 0px;
background: #ffffff;
width: 320px;
box-shadow: 0px 0px 0px 1px rgba(11, 11, 45, 0.09), 0px 8px 12px -4px rgba(82, 82, 82, 0.12), 0px 16px 24px -8px rgba(82, 82, 82, 0.12);
border-radius: 7px;
// height: 250px;
z-index: 9999;
padding: 0;
margin: 0;
list-style: none;
.list-desc {
font-size: 12px;
color: #6e7381;
}
}
.infinite-list .infinite-list-item {
padding-left: 5px;
display: flex;
align-items: center;
height: 50px;
margin: 10px;
}
.infinite-list .infinite-list-item:hover {
background: rgba(188, 189, 194, 0.2);
border-radius: 6px;
}
.infinite-list .infinite-list-item + .list-item {
margin-top: 10px;
}
}
js:
1、定义html区域绑定的ref
const selectDataRulesRef = ref(null)
const selectDataRulesBtnRef = ref(null)
2、定义变量v-show绑定--控制弹窗的显示隐藏
const isShowScroll = ref(false)
3、点击按钮实现基础的开关
const handleAddRuleItem = () => {
isShowScroll.value = !isShowScroll.value
}
2、在OnMounted生命周期里面
//点击规则列表弹窗区域关闭弹窗
nextTick(() => {
document.addEventListener('mouseup', e => {
// 如果点击的是按钮 则不执行下面的操作
if (selectDataRulesRef.value&&selectDataRulesBtnRef.value) {
if(selectDataRulesBtnRef.value.contains(e.target)){
return
}
if (!selectDataRulesRef.value.contains(e.target)) {
// 点击的区域不包含在弹窗区域之内就关闭弹窗
isShowScroll.value = false
// 点击按钮也属于弹窗区域外
// 点击按钮进过MOUNTED FALSE->TRUE
// 再次点击按钮进过MOUNTED FALSE->TRUE,导致弹窗不能关闭
//所以需要判断,如果点击的是按钮就不需要执行弹窗外关闭弹窗的逻辑
}
}
})
})