vue3 elementPlus select加载数据分页

在这里插入图片描述
摘要:

今天遇到一个vue3使用elementPlus的select选择商品数据的时候需要分页加载商品,但是找了一圈elementPlus没有分页的事件,只能自己写,自定义形式和嵌套一层option选项中滚动触发上拉加载数据!

自定义指令(推荐)

<template>
  <el-select v-model="_modelValue" remote reserve-keyword @visible-change="handleVisibleChange" @change="handelChange" :remote-method="remoteMethod" filterable :loading="loading" clearable v-loadMore="loadMore" :multiple="multiple" :disabled="disabled" :placeholder="placeholder" :teleported="false">
    <el-option v-for="item in optionsList" :key="item[optionName.value]" :label="item[optionName.label]" :value="item[optionName.value]" />
  </el-select>
</template>

<script lang="ts" setup>
const { proxy } = getCurrentInstance();
const { selectLoadMoreDefault } = proxy.constants;
const props = defineProps({
  options: {
    type: Array
  },
  modelValue: {
    type: [String, Number]
  },
  optionsName: {
    type: Object,
    default: () => ({})
  },
  total: {
    type: Number,
    default: 0
  },
  pageSize: {
    type: Number,
    default: 0
  },
  pageNum: {
    type: Number,
    default: 0
  },
  getList: {
    type: Function
  },
  placeholder: {
    type: String,
    default: '请输入/选择'
  },
  disabled: {
    type: Boolean,
    default: false
  },
  multiple: {
    type: Boolean,
    default: false
  },
  clearable: {
    type: Boolean,
    default: true
  },
  // 除分页参数的其他参数
  otherParams: {
    type: Object,
    default: () => ({})
  }
});
const emits = defineEmits(['changeData', 'update:modelValue']);
const pageSize = computed(
  () => props.pageSize || selectLoadMoreDefault.pageSize
);
const pageNum = computed(() => props.pageNum || selectLoadMoreDefault.pageNum);
const queryParams = ref({
  pageSize: pageSize.value,
  pageNum: pageNum.value,
  name: ''
});
const visible = ref(false);
const _modelValue = ref(props.modelValue);
watch(
  () => [props.modelValue, props.total],
  (val) => {
    _modelValue.value = val[0];
    emits('update:modelValue', val[0]);
    if (!val[1]) {
      queryParams.value.pageNum = 1;
    }
  }
);
const loading = ref(false);
const isMounted = ref(false);
const optionsList = computed(() => props.options);
onMounted(() => {
  isMounted.value = true;
});
onUnmounted(() => {
  isMounted.value = false;
});
// 下拉选属性配置
const optionName = computed(() => {
  return {
    label: props.optionsName?.label ?? 'label',
    value: props.optionsName?.value ?? 'value'
  };
});

const handelChange = (val) => {
  emits('changeData', val);
  emits('update:modelValue', val);
};
const loadMore = () => {
  let sum = queryParams.value.pageNum * queryParams.value.pageSize;
  if (sum >= props.total) return;
  visible.value && remoteMethod(queryParams.value.name, false);
};
const remoteMethod = (query, isEmpty = true) => {
  if (visible.value) {
    queryParams.value.name = query;
    queryParams.value.pageNum = isEmpty ? 1 : queryParams.value.pageNum + 1;
    setTimeout(() => {
      props.getList({ ...queryParams.value, ...props.otherParams }, isEmpty);
    }, 200);
  }
};
// 控制下拉框的显示隐藏
const handleVisibleChange = (isVisible) => {
  visible.value = isVisible;
};
</script>

Infinite Scroll的无限滚动 =》v-infinite-scroll

<template>
  <el-select style="width: 100%" v-if="isMounted" v-model="_modelValue" remote reserve-keyword @visible-change="handleVisibleChange" @change="handelChange" :remote-method="remoteMethod" filterable :loading="loading" clearable :multiple="multiple" :disabled="disabled" :placeholder="placeholder">
    <div v-infinite-scroll="loadMore" :infinite-scroll-delay="500" style="overflow-y: hidden">
      <el-option v-for="item in optionsList" :key="item[optionName.value]" :label="item[optionName.label]" :value="item[optionName.value]" />
    </div>
  </el-select>
</template>

<script lang="ts" setup>
const { proxy } = getCurrentInstance();
const { selectLoadMoreDefault } = proxy.constants;
const props = defineProps({
  options: {
    type: Array
  },
  modelValue: {
    type: [String, Number]
  },
  optionsName: {
    type: Object,
    default: () => ({})
  },
  total: {
    type: Number,
    default: 0
  },
  pageSize: {
    type: Number,
    default: 0
  },
  pageNum: {
    type: Number,
    default: 0
  },
  getList: {
    type: Function
  },
  placeholder: {
    type: String,
    default: '请输入/选择'
  },
  disabled: {
    type: Boolean,
    default: false
  },
  multiple: {
    type: Boolean,
    default: false
  },
  clearable: {
    type: Boolean,
    default: true
  },
  // 除分页参数的其他参数
  otherParams: {
    type: Object,
    default: () => ({})
  }
});
const emits = defineEmits(['changeData', 'update:modelValue']);
const pageSize = computed(
  () => props.pageSize || selectLoadMoreDefault.pageSize
);
const pageNum = computed(() => props.pageNum || selectLoadMoreDefault.pageNum);
const queryParams = ref({
  pageSize: pageSize.value,
  pageNum: pageNum.value,
  name: ''
});
const visible = ref(false);
const _modelValue = ref(props.modelValue);
watch(
  () => [props.modelValue, props.total],
  (val) => {
    _modelValue.value = val[0];
    emits('update:modelValue', val[0]);
    if (!val[1]) {
      queryParams.value.pageNum = 1;
    }
  }
);
const loading = ref(false);
const isMounted = ref(false);
const optionsList = computed(() => props.options);
onMounted(() => {
  isMounted.value = true;
});
// 下拉选属性配置
const optionName = computed(() => {
  return {
    label: props.optionsName?.label ?? 'label',
    value: props.optionsName?.value ?? 'value'
  };
});

const handelChange = (val) => {
  emits('changeData', val);
  emits('update:modelValue', val);
};
const loadMore = () => {
  let sum = queryParams.value.pageNum * queryParams.value.pageSize;
  if (sum >= props.total) return;
  visible.value && remoteMethod(queryParams.value.name, false);
};
const remoteMethod = (query, isEmpty = true) => {
  if (visible.value) {
    queryParams.value.name = query;
    queryParams.value.pageNum = isEmpty ? 1 : queryParams.value.pageNum + 1;
    setTimeout(() => {
      props.getList({ ...queryParams.value, ...props.otherParams }, isEmpty);
    }, 200);
  }
};
// 控制下拉框的显示隐藏
const handleVisibleChange = (isVisible) => {
  visible.value = isVisible;
};
</script>
Element Plus是一个基于Vue.js的开源UI组件库,它提供了一套丰富的界面元素和功能,包括分页加载数据的功能。在Element Plus中,分页通常通过`el-pagination`组件来实现。这个组件允许你在列表页面中添加分页控制,比如上一页、下一页、总页数以及每页显示的数量等。 使用`el-pagination`的基本步骤如下: 1. 引入组件:首先需要在模板文件中导入`el-pagination`组件,例如: ```html <template> <div> <!-- ...其他内容 --> <el-pagination :total="totalCount" :current-page="currentPage" @current-change="handleCurrentChange"></el-pagination> <!-- ...其他内容 --> </div> </template> ``` 2. 数据绑定:设置`total`属性为总数据量,`current-page`属性表示当前页码,`@current-change`则是当页码改变时触发的事件处理函数。 3. 定义方法:创建一个方法如`handleCurrentChange`来处理页码变化,并从服务器获取对应页的数据。 ```javascript <script> export default { data() { return { totalCount: 0, currentPage: 1, itemsPerPage: 10, // 每页显示项数 }; }, methods: { handleCurrentChange(page) { this.currentPage = page; // 根据新的页码请求并更新数据 this.fetchData(this.currentPage); }, fetchData(page) { // 这里通常是异步操作,实际项目中应替换为你的API请求 axios.get(`/api/data?page=${page}&limit=${this.itemsPerPage}`).then(response => { this.totalCount = response.data.total; // 更新总数据量 this.currentItems = response.data.data; // 获取并设置当前页的数据 }); }, }, }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值