Vue3 element-plus 下拉分頁 select分頁


由於用 input 實現下拉分頁不太理想,轉換了一個角度,用 select 實現,以下是具體實現(script-setup TS)

script-setup

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({ name: 'LabelSelectCpm' })
</script>

<script setup lang="ts">
import { ref, reactive } from 'vue'
// const emit = defineEmits([])

// select 綁定的 v-model
const value = ref()
const searchKeyword = ref()
//dom 事件節點
const dom = ref()
const loading = ref(false)
// select-options 數據源
const options = ref([])
// 分頁控制
const requsetObj = reactive({
    page: 1,
    size: 50,
})

/**
 *  加載接口數據
 * @return Promise
 */
const loadData = async () => {
    return new Promise((res, rej) => {
        setTimeout(() => {
            res(
                Array.from(
                    { length: requsetObj.size * requsetObj.page },
                    (v, i) => ({ label: `label${i}`, value: `value${i}` })
                )
            )
        }, 300)
    })
}

/**
 * @param {string} query 輸入的搜索關鍵詞
 * @param {function} fn 需要在接口數據返回后執行的回調
 */
const remoteMethod = (query: string, fn?: Function) => {
    loading.value = true
    if (query) {
        /* 記錄輸入的關鍵詞 */
        searchKeyword.value = query
        loadData().then((res: any) => {
            console.log(res)
            options.value = res
            loading.value = false
            fn && fn()
        })
    } else {
        /* 初始化數據邏輯 */
        loadData().then((res: any) => {
            console.log(res)
            options.value = res
            loading.value = false
            fn && fn()
        })
    }
}

const selectChange = (val: any) => {
    const selectVal = options.value.filter((e: any) => e.value == val)
    console.log('當前選中', selectVal)
}

/* 滾動監聽函數 */
const scrollAddEventFn = (e) => {
    const self = e.target as any
    if (self.scrollHeight - self.scrollTop <= self.clientHeight) {
        console.log('分頁查詢')
        requsetObj.page++
        remoteMethod(searchKeyword.value)
    }
}
const visibleChange = (isShow: any) => {
    if (isShow) {
        // 下拉框顯示時,渲染數據,初始化滾動監聽
        remoteMethod(searchKeyword.value, () => {
            /* 在數據渲染完之后的回調 */
            /* 初始化滾動監聽 (由於 dom 渲染未完成,所以需要開啟一個 timeout 在 1s 后實現監聽) */
            const parentDom = document.querySelectorAll(
                '.el-select-dropdown__wrap.el-scrollbar__wrap.el-scrollbar__wrap--hidden-default'
            ) as any
            setTimeout(() => {
                parentDom.forEach((e: any, idx: number) => {
                    if (
                        e.querySelector('.LabelSelectCpmBox') &&
                        e.querySelector('.LabelSelectCpmBox').children &&
                        e.querySelector('.LabelSelectCpmBox').children.length >
                            0
                    ) {
                        dom.value = parentDom[idx]
                        dom.value.addEventListener(
                            'scroll',
                            scrollAddEventFn,
                            false
                        )
                    }
                })
            }, 1000)
        })
    } else {
        // 移除滾動監聽
        dom.value?.removeEventListener('scroll', scrollAddEventFn, false)
        options.value = []
    }
}
</script>

template

<template>
    <div class="LabelSelectCpm">
        <el-select
            v-model="value"
            :multiple="false"
            filterable
            remote
            reserve-keyword
            placeholder="輸入關鍵詞搜索"
            :remote-method="remoteMethod"
            @change="selectChange"
            @visible-change="visibleChange"
            :loading="loading"
        >
            <div class="LabelSelectCpmBox">
                <el-option
                    v-for="item in options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                >
                </el-option>
            </div>
        </el-select>
    </div>
</template>

css 沒有額外的代碼,所以就不貼了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM