记录菌 2025-02-12 15:57 采纳率: 50%
浏览 59

vue2封装下拉分页组件回显问题

问题描述

我的项目使用的是vue2和elementui框架。elementui框架中没有封装分页下拉框组件。因此需要自己设计一个组件。下面描述功能:

  1. 暂时不考虑多选下拉框,只考虑单选的情况。
  2. 不使用滚动下拉分页的方式,而是使用elementui中的Pagination 分页。
  3. 回显功能:切换分页清空用户选中的条件也是合理的,但是编辑操作时回显数据,应该显示到用户点击的那一页(目前怎么实现感到困惑)。

AI回答参考:
正常查询,然后将用户选中的数据加载第一页的第一条。
个人想法:
页面加载时,将用户选中的数据传到后端,然后定位到用户查询的页,返回给前端。不知道大家业务里面这种情况是怎么实现的?

样式效果:

img

封装组件代码如下:(目前没有做回显)

<template>
  <el-select
    v-model="copyValue"
    :disabled="disabled"
    filterable
    clearable
    placeholder="请选择"
    :filter-method="filterMethod"
    @clear="selectClear"
    @change="updateValue"
    :style="{ width: selectWidth + 'px' }"
    @focus="focusMethod"
  >
    <el-option
      v-for="item in dataList"
      :key="item.value"
      :label="item[labelKey]"
      :value="item[valueKey]"
    />
    <div style="float: right;margin-right:10px;padding-bottom: 10px">
      <el-pagination
        :current-page="pageInfo.pageNo"
        :page-size="pageInfo.pageSize"
        layout=" prev, pager, next,total"
        :total="pageInfo.total"
        @current-change="handleCurrentChange"
      />
    </div>
  </el-select>
</template>

<script>
export default {
  name: 'PaginationSelect',
  props: {
    // 绑定值
    value: String,
    // 下拉列表
    dataList: Array,
    // option的label在列表中对应的key
    labelKey: String,
    // option的value在列表中对应的key
    valueKey: String,
    // 分页信息
    pageInfo: Object,
    disabled: false,
    elSelectClass: Boolean,
    selectWidth: {
      type: [String, Number],
      default: 300
    }
  },
  data() {
    return {
      copyValue: this.value
    }
  },
  watch: {
    value: {
      handler: function(val) {
        this.copyValue = val
      },
      deep: true
    }
  },
  methods: {
    // 更新值
    updateValue(val) {
      this.$emit('selectChange', this.copyValue)
    },
    filterMethod: function(query) {
      this.copyValue = query
      this.$emit('selectPageChange', 1, this.pageInfo.pageSize, query)
    },
    focusMethod: function() {
      if (!this.dataList || (this.dataList && this.dataList.length === 0)) {
        this.filterMethod()
      }
    },
    selectClear: function() {
      this.$emit('selectPageChange', 1, this.pageInfo.pageSize, '')
    },
    // 翻页
    handleCurrentChange(val) {
      this.$emit('selectPageChange', val, this.pageInfo.pageSize)
      this.copyValue = ''
    },
    resetFormFields() {
      this.copyValue = ''
    },
    openEdit(value) {
      this.copyValue = value
    }
  }
}
</script>

<style scoped>
.elPaginationSelect{
  width: 100%;
  border: none !important;
}
.elPaginationSelect .el-input input{
  border: none !important;
  width: 100%;
}
</style>


  • 写回答

2条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2025-02-12 15:57
    关注
    让【道友老李】来帮你解答,本回答参考gpt编写,并整理提供,如果还有疑问可以点击头像关注私信或评论。
    如果答案让您满意,请采纳、关注,非常感谢!
    ## 问题描述 在使用 Vue 2 和 Element UI 框架的项目中, Element UI 中未封装分页下拉框组件。因此,我们需要自己实现一个包含分页功能的下拉框组件。以下是实现的具体要求:
    1. 当前仅考虑单选下拉框,不考虑多选。
    2. 使用 Element UI 中的 Pagination 进行分页,而非滚动下拉方式。
    3. 实现回显功能,即在编辑操作时,组件能够显示用户之前选择的选项并定位到相应的页码。

    实现思路

    1. 数据请求与分页:根据所选的条件请求数据,返回相应的选项列表及分页信息。
    2. 回显功能:在组件加载时,使用父组件传递的选中值,调用接口获取该选项在当前条件下所在的页,并将其显示在下拉框内。
    3. 用户交互:通过 Element UI 的 el-select 组件与 el-pagination 组件实现条件选择和分页。

    样式效果

    PaginationSelect Component

    组件代码实现

    下面是一个简单的 PaginationSelect 组件实现代码,包含了分页与回显的基本逻辑:

    <template>
      <el-select
        v-model="copyValue"
        :disabled="disabled"
        filterable
        clearable
        placeholder="请选择"
        :filter-method="filterMethod"
        @clear="selectClear"
        @change="updateValue"
        :style="{ width: selectWidth + 'px' }"
        @focus="focusMethod"
      >
        <el-option
          v-for="item in dataList"
          :key="item[valueKey]"
          :label="item[labelKey]"
          :value="item[valueKey]"
        />
        <div style="float: right; margin-right: 10px; padding-bottom: 10px;">
          <el-pagination
            :current-page="pageInfo.pageNo"
            :page-size="pageInfo.pageSize"
            layout="prev, pager, next, total"
            :total="pageInfo.total"
            @current-change="handleCurrentChange"
          />
        </div>
      </el-select>
    </template>
    <script>
    export default {
      name: 'PaginationSelect',
      props: {
        value: String,
        dataList: Array,
        labelKey: String,
        valueKey: String,
        pageInfo: Object,
        disabled: {
          type: Boolean,
          default: false,
        },
        selectWidth: {
          type: [String, Number],
          default: 300,
        },
      },
      data() {
        return {
          copyValue: this.value,
        };
      },
      watch: {
        value: {
          handler(val) {
            this.copyValue = val;
          },
          deep: true,
        },
      },
      methods: {
        updateValue(val) {
          this.$emit('selectChange', this.copyValue);
        },
        filterMethod(query) {
          this.copyValue = query;
          this.$emit('selectPageChange', 1, this.pageInfo.pageSize, query);
        },
        focusMethod() {
          // Logic to handle focus event, if necessary
          if (!this.dataList || (this.dataList && this.dataList.length === 0)) {
            this.filterMethod();
          }
        },
        selectClear() {
          this.$emit('selectPageChange', 1, this.pageInfo.pageSize, '');
        },
        handleCurrentChange(val) {
          this.$emit('selectPageChange', val, this.pageInfo.pageSize);
          this.copyValue = '';
        },
        openEdit(value) {
          this.copyValue = value;
          // Logic to fetch the correct page based on the selected value
          // For example:
          this.findSelectedItemPage(value);
        },
        findSelectedItemPage(value) {
          // Mock function to simulate fetching the page of the selected item
          // Replace this with actual API call to get the item page
          const selectedItemIndex = this.dataList.findIndex(item => item[this.valueKey] === value);
          if (selectedItemIndex !== -1) {
            const pageSize = this.pageInfo.pageSize;
            const pageNo = Math.floor(selectedItemIndex / pageSize) + 1;
            this.$emit('selectPageChange', pageNo, pageSize);
          }
        },
      },
    };
    </script>
    

    使用示例

    父组件内容

    在父组件中使用该 PaginationSelect 组件,可以传递必要的 props 以及处理分页和选择改变的事件。

    <template>
      <pagination-select
        :value="selectedValue"
        :data-list="options"
        :page-info="pageInfo"
        @selectChange="onSelectChange"
        @selectPageChange="onPageChange"
        :disabled="isDisabled"
      />
    </template>
    <script>
    import PaginationSelect from './PaginationSelect.vue';
    export default {
      components: { PaginationSelect },
      data() {
        return {
          selectedValue: '', // 最初的选中值
          options: [], // 从后端获取的选项列表
          pageInfo: {
            pageNo: 1,
            pageSize: 5,
            total: 0,
          },
          isDisabled: false,
        };
      },
      methods: {
        fetchData(pageNo, query) {
          // 伪代码,替换成真实的数据请求
          // axios.get(url, { params: { pageNo, query } }).then(result => {
          //   this.options = result.data.items;
          //   this.pageInfo.total = result.data.total;
          // });
        },
        onSelectChange(value) {
          this.selectedValue = value;
          // 进一步处理逻辑
        },
        onPageChange(pageNo, pageSize) {
          this.fetchData(pageNo, this.selectedValue); // 重新获取数据
        },
      },
      mounted() {
        this.fetchData(this.pageInfo.pageNo); // 组件加载时请求数据
      },
    };
    </script>
    

    总结

    通过上述流程和代码示例,我们成功实现了一个带分页下拉框的选择组件,并确保了编辑时能够正确回显选中状态,并根据选中的数据自动调整分页。这样用户在进行选择和编辑操作时,可以获得更好的体验。

    评论

报告相同问题?

问题事件

  • 修改了问题 2月12日
  • 创建了问题 2月12日