页面组件
// 自定义指令loadMore
<template>
<el-select v-load-more="loadMore">
<el-option label="北京"/>
<el-option label="上海"/>
<el-option label="天津"/>
</el-select>
</template>
<script setup>
// 触发自定义指令的函数
const loadMore = () => {
...
}
</script>
新建自定义指令文件 src/directive/index.js
// 导出函数,在main.js文件中使用
const loadMore = {
beforeMount(el, binding) {
// 监视器的回调
function callback(records) {
// 观察会监视属性的新增、删除,以及值的变化
// 所以在点击select时,会添加上aria-describedby属性并赋值,所以records是个列表,
// 遍历一下,我们要的标签属性是aria-describedby,以及它的值oldValue
records.map((record) => {
if (record.attributeName == 'aria-describedby' && record.oldValue) {
// 根据aria-describedby的值,也就是oldValue,我们获取id为oldValue的下拉框DOM
let poper = document.getElementById(record.oldValue)
if (poper) {
// 再获取popup的子元素scrollbar,监听滚动事件loadMores
const optionDom = poper.querySelector('.el-scrollbar .el-select-dropdown__wrap');
optionDom.addEventListener('scroll', loadMores.bind(optionDom))
}
}
})
}
// scroll时的事件
function loadMores() {
let condition = this.scrollHeight - this.scrollTop <= this.clientHeight +30
if (condition) {
binding.value && binding.value()
}
}
// 获取select-trigger,因为它身上有一个属性aria-describedby
// (我看其他教程 不是aria-describedby这个名字,可能是版本不一样,官方有所改动吧)
// 这个属性的值和下拉框popup的id是相同的
const selectDom = el.querySelector('.select-trigger')
// 使用观察器,callback回调在上面已经定义了
// 因为下拉框未显示时,select-trigger身上没有aria-describedby属性
let observer = new MutationObserver(callback);
// observer.observe('观察的DOM', '观察的属性'),这里我们要监视select的属性aria-describedby
// MutationObserver观察器具体配置可以自己百度一下
observer.observe(selectDom, {
attributes: true,
attributeOldValue: true
})
}
}
export default function directive(app) {
// 注册自定义指令app.directive('指令名', 指令事件)
app.directive('loadMore', loadMore)
}
在main.js中导入自定义指令directive
...
import directive from './directive/index.js'
const app = createApp(App)
// 往函数中传入app
directive(app)