从零开始Vue3+Element Plus后台管理系统(28) ——带分页的el-select

1,802 阅读1分钟

image.png

该需求来源于实时搜索客户名称,使用el-select相比用弹窗嵌套表格轻便不少。但是当远程搜索获得的数据量大时,怎么加上分页呢?

基于对 element plus 了解的不够全面,一开始我以为会是个比较麻烦的活,结果,贴心的 el-select 早就考虑到了开发人员的需求,直接把分页组件放进去就好了。

elemen-plus 版本 2.4.3 提供了footer 插槽,可以把分页放在 footer 插槽中。在之前的版本中,分页也可以放在 default 插槽中,只是需要调整下样式给分页留个位置。 若非特殊情况,推荐升级 element-plus。

代码中的Pagination 是二次封装的 el-pagination,具体可以参考文章juejin.cn/post/719259…

<template>
  <el-select
    v-model="value"
    reserve-keyword
    placeholder="输入关键字选择"
    :remote-method="remoteMethod"
    :loading="loading"
    clearable
    filterable
    remote
  >
    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />

    <template #footer>
      <Pagination
        :small="true"
        layout="prev, pager, next"
        v-model:page="pagination.pageNum"
        v-model:size="pagination.pageSize"
        :total="total"
        @pagination="getData"
        class="justify-center h-10 p-2 bg-white"
      />
    </template>
    <template #loading>
      <div v-loading="loading" element-loading-text="加载中" class="h-20"></div>
    </template>
  </el-select>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import clientApi from '~/api/client'
import { reactive } from 'vue'

interface ListItem {
  value: string
  label: string
}

const props = defineProps({
  modelValue: { type: [Array, String, Number], default: () => [] }
})

const pagination = reactive({
  pageNum: 1,
  pageSize: 10
})
let total = ref(0)
const emits = defineEmits(['update:modelValue'])

const value = computed({
  get: () => props.modelValue,
  set: (val) => {
    emits('update:modelValue', val)
  }
})

let keyword = ref('')
function getData() {
  loading.value = true
  clientApi
    .getClientList({
      keyword: keyword.value
    })
    .then((res: any) => {
      total.value = res.total
      options.value = res?.list?.map((val) => ({
        label: `${val.name} (${val.province},${val.city}) `,
        value: val.id
      }))
    })
    .finally(() => {
      loading.value = false
    })
}

const options = ref<ListItem[]>([])
const loading = ref(false)

const remoteMethod = (query: string) => {
  if (query) {
    keyword.value = query
    getData()
  } else {
    options.value = []
  }
}
</script>

有空时翻翻 vue、element 这些常用工具的文档,还是挺有好处的,了解更多解决方式,避免重复造轮子,有效提升开发效率。如果你就喜欢造轮子,也可以博取百家之长,造出更好的轮子。