实现思路
Select 选择器 | Element Plus
1、select方法@visible-change这个方法是下拉框出现/隐藏时触发,当显示的时候将两个按钮插入到下拉框里面,是基于原生插入DOM的这种方式;
2、通过vue3 ref获取selectDOM,在获取select的popperPaneRef.$el (select下拉框的DOM),在基于js方法创建div `document.createElement('div')` 而div里面放入两个按钮使用div.appendChild插入按钮;
3、最后将div按钮插入到 popperPaneRef.$el(select下拉框的DOM)里就可以了,在将element-button-mini的css按钮样式复制,添加到原生按钮身上;
4、这里是无法使用el-button这种组件因为不解析,只能使用原生button,为其添加ele的样式;
具体实现看代码
<template><el-table :data="tableData" border style="width: 100%"><el-table-column align="right" label="Date" prop="date" width="280"><template #header><div class="headers-slot"><p v-if="!isShowSelect"> Date <span @click="isShowSelect = !isShowSelect"> 🔍 </span> </p><div v-else>🔍 <el-selectv-model="value3"multipleplaceholder="Select"style="width: 180px"@visible-change="visibleChange"ref="filterSelect"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"/></el-select></div></div></template></el-table-column><el-table-column label="Name" prop="name" width="180"/><el-table-column label="Address" prop="address"/></el-table>
</template><script setup>
import {reactive, ref} from "vue";const value3 = ref([])
const filterSelect = ref()
let isShowSelect = ref(false)
const options = reactive([{value: 'key-1',label: '今天',},{value: 'key-2',label: '明天',},{value: 'key-3',label: '后天',},{value: 'key-4',label: '昨天',},{value: 'key-5',label: '前天',},
])let tableData = ref([{date: '今天',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '明天',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '后天',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '昨天',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '前天',name: 'Tom222',address: 'No. 189, Grove St, Los Angeles',},
])const visibleChange = (visible) => {console.log(visible,filterSelect)// 下拉框显示隐藏if (visible ) {const ref = filterSelect.value// 拿到下拉选项的对象let popper = ref.popperPaneRef// 在拿到它的DOM元素if (popper.$el) popper = popper.$el// 判断是否有添加按钮if (!Array.from(popper.children).some(v => v.className === 'select-btn-box')) {// 插入按钮let el = document.createElement('div')let cancelBtn = document.createElement('button')let confirmBtn = document.createElement('button')el.className = 'select-btn-box'cancelBtn.className = 'select-cancel-mini-btn'confirmBtn.className = 'select-confirm-mini-btn'cancelBtn.innerText = '取消'confirmBtn.innerText = '确定'el.appendChild(cancelBtn)el.appendChild(confirmBtn)// 调用确认和取消函数cancelBtn.onclick = () => cancelHandle()confirmBtn.onclick = () => confirmHandle()popper.appendChild(el)}}
}const cancelHandle = () => {console.log('取消',value3.value)isShowSelect.value = false
}const confirmHandle = () => {console.log('确认',value3.value)isShowSelect.value = false
}
</script>
<style>
.headers-slot {display: flex;align-items: center;justify-content: space-around;
}
/*这些是按钮css,复制底层ele-btn-mini的
*/
.custom-button {display: inline-block;line-height: 1;white-space: nowrap;cursor: pointer;background: #fff;color: #fff;-webkit-appearance: none;text-align: center;box-sizing: border-box;outline: 0;margin: 0;padding: 10px 15px;font-size: 14px;border-radius: 4px;
}
.select-btn-box{display: flex;border-top: 1px solid #dfe6ec;width: 100%;height: 44px;align-items: center;justify-content:flex-end ;
}
.select-cancel-mini-btn{display: inline-block;display: inline-block;line-height: 1;white-space: nowrap;cursor: pointer;background: #FFFFFF;border: 1px solid #DCDFE6;border-color: #DCDFE6;color: #606266;-webkit-appearance: none;text-align: center;-webkit-box-sizing: border-box;box-sizing: border-box;outline: none;margin: 0;-webkit-transition: 0.1s;transition: 0.1s;font-weight: 400;-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;padding: 7px 15px;font-size: 12px;border-radius: 3px;margin-right: 10px;
}
.select-cancel-mini-btn:hover{background-color:#e4f2fe ;color: #349cfb;border-color: #afd9fd;
}
.select-confirm-mini-btn:hover{background-color: #339bfa;
}
.select-confirm-mini-btn{display: inline-block;line-height: 1;white-space: nowrap;cursor: pointer;background: #fff;border: 1px solid #dcdfe6;-webkit-appearance: none;text-align: center;box-sizing: border-box;outline: none;margin: 0;transition: 0.1s;font-weight: 500;-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;padding: 12px 20px;font-size: 14px;border-radius: 4px;color: #fff;background-color: #0080f5;border-color: #409eff;padding: 7px 15px;font-size: 12px;border-radius: 3px;margin-right: 10px;
}
span{cursor: pointer;
}
</style>