elementui中select下拉框添加分页(可搜索)

本文介绍了一种解决大量数据导致的Select下拉框高度过高的问题,通过添加分页功能来提高用户体验。详细展示了HTML、CSS和JS代码实现分页Select组件的步骤,包括搜索、分页、焦点处理等关键功能。此外,还提供了组件在父组件中的使用示例以及数据交互的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近遇到这样的需求,select下拉框的数据太多,导致高度很高,影响美观,所以给select下拉框添加分页功能。新建一个组件。

首先是HTML部分

这里没什么说的 ,直接嵌套即可

    <el-select
      v-model="value1"
      placeholder="选择埋点"
      :clearable="false"
      style="width: 240px"
      size="mini"
      refs="mySelect"
      :reserve-keyword="true"
      filterable
      popper-class="sele"
      :filter-method="filter"
      @change="fun"
      @focus="funx"
      @blur="funb"
      @visible-change="hidden"
    >
      <el-option
        v-for="item in optionfen"
        :key="item.value"
        :label="item.value"
        remote
        :value="item.label"
        placeholder="请输入"
      >
      </el-option>

      <div  style="bottom: -10px">
        <el-pagination
          small
          @current-change="handleCurrentChange"
          :current-page="currentpage"
          :page-size="pageSize"
          layout="prev, pager,next,total"
          :total="options.length"
        >
        </el-pagination>
      </div>
    </el-select>

CSS部分

.drop >>> .el-input__inner {
  background: #5183ff !important;
  color: white;
  border: none;
  height: 26px;
  padding: 10px 22px 10px 10px;
  text-align: center;
}
.drop {
  width: 250px;
}
.drop >>> .el-select .el-input .el-select__caret {
  display: none;
}

JS部分

这里因为数据是一次性返回的 所以自行实现了分页和搜索

export default {
  data() {
    return {
      options: [],  //总数据
      options1: [],  //搜索的数据
      optionfen: [],  //当前页码的数据
      value1: "",  //输入框的值
      currentpage: 1,   //当前页码
      pageSize: 10,   //每页展示的条数
      val: "",   
    };
  },
  props: {
  //向父组件传递数据
    funName: {
      type: String,
      require: true,
    },
    //接收返回值
    renderingAllKeys: {
      type: Array,
      require: true,
    },
  },
  computed: {},
  mounted() {},
  methods: {
  //分页的实现,currentpage 为页码,每页展示的数据为10(可自行更改pageSize)条,分别是在总数据options中
  //下标从(currentpage -1)*10开始的十条数据
    handleCurrentChange(val) {
      this.optionfen = [];
      this.currentpage = val;
      let start = (val - 1) * this.pageSize;
      let end = Number(start) + Number(this.pageSize);
      //此处需要判断如果计算的结束下标大于总数据的长度,则需要修改结束下标
      if (end > this.options.length) {
        end = this.options.length;
      }
      for (let i = start; i < end; i++) {
      //将取到的数据展示在页面
        this.optionfen.push(this.options[i]);
      }
    },
    //选择数据后将相关数据发送给父组件
    fun() {
      let arr = [];
      this.val = this.value1;
      for (let j in this.optionfen) {
        if (this.value1 == this.optionfen[j].label) {
          arr.push(this.optionfen[j]);
        }
      }
      this.$emit(`${this.funName}`, arr);
    },
    // 获得焦点
    //获得焦点的时候跳转到当前value所在的页码
    funx() {
      this.val = this.value1;
      let flag = false;
      for (let i in this.options1) {
        if (this.options1[i].label == this.value1) {
          flag = true;
          let num = Math.floor((i + 10) / 10);
          this.currentpage = Number(num);
          this.handleCurrentChange(Number(num));
        }
      }
      //如果没有就默认展示第一页
      if (!flag) {
        this.currentpage = 1;
        this.handleCurrentChange(1);
      }
    },
    // 失去焦点
    //前面每次操作都将输入框内的value值存储一份到val中,就是为了防止用户搜索的时候中途关闭选择框,这个时候输入框显示的就是
    //用户输入一半的value值,加上这层逻辑就可以在用户输入的数据在总数据中不存在的时候(也就是无效数据),关闭选择框
    //之后让输入框依旧显示上一次的正确value值
    funb() {
      this.value1 = this.val;
      $(".drop >>> .el-input__inner").css({
        color: "white",
      });
    },
    hidden(bool) {
      // 隐藏select列表
      if (!bool) {
      //关闭select下拉框的时候重置页码及数据,并移除事件监听
        this.optionfen = [];
        this.options = this.options1;
        let start = 0;
        let end = Number(start) + Number(this.pageSize);
        if (end > this.options1.length) {
          end = this.options1.length;
        }
        for (let i = start; i < end; i++) {
          this.optionfen.push(this.options1[i]);
        }
        // 移除mousedown事件监听
        removeEventListener("mousedown", function () {}, false);
      } else {
        // 打开select列表
        // 增加mousedown事件监听  当点击分页时移除输入框的默认事件 ,让他不会失去焦点(blur),如果不加,就会
        //出现当用户点击分页之后,输入框会失去焦点,这个时候如果用户需要输入数据进行搜索就需要先删除输入框的值再输入,体验不好。
        //(elementUI下拉框的默认样式,当可搜索时点击输入框可直接输入,不需要删除上次数据)
        document.addEventListener(
          "mousedown",
          function (e) {
            // console.log(e)
            if (
              e.target.tagName === "LI" ||
              (e.target.tagName == "I" && e.target.localName == "i")
            ) {
              e.preventDefault();
            }
          },
          false
        );
        this.funx();
      }
    },
    //搜索方法,将符合的数据存入options中,并分页展示
    filter(val) {
      this.optionfen = [];
      this.value1 = val;
      let arr = [];
      let value = val.toLowerCase();
      for (let i in this.options1) {
        if (this.options1[i].label.toLowerCase().indexOf(value) >= 0) {
          arr.push(this.options1[i]);
        }
      }
      this.options = arr;
      this.handleCurrentChange(1);
    },
  },
  //监听来自父组件的数据,当数据更新时,重置展示
  watch: {
    renderingAllKeys: {
      //深度监听,可监听到对象、数组的变化
      handler(newV) {
		 if(newV.length>0){
        	   this.options1 = newV;
               this.options = newV;
               this.optionfen=[]
               this.currentpage=1  //标记重置
               let start=(this.currentpage-1)*this.pageSize
               let end=Number(start)+Number(this.pageSize)
               if(end>this.options1.length){
                   end=this.options1.length
               }
               for(let i=start;i<end;i++){
                   this.optionfen.push(this.options1[i])
               }
               this.value1 = newV[0].label;  //指标重置
               this.val = newV[0].label;  //指标重置
               this.fun()
           }else{
               this.options1=[]
               this.options=[]
               this.optionfen=[]
               this.value1=""
           }
		      },
      deep: false,
    },
  },
};

父组件中使用该组件

renderingAllKeys向子组件传递父组件的数据

<dropdown
          funName="downBase"
          :renderingAllKeys="renderingAllKeys"
          :maxNum="1"
          @downBase="getDropdownInfo"
        />

父组件中使用getDropdownInfo获取来自子组件的数据

    getDropdownInfo(data) {
      this.selectTypeArr = data;
		//拿到数据执行需要的逻辑
    },

效果图

可以使用Element UI组件库中的`<el-select>`组件和`<el-option>`组件来实现下拉框分页搜索功能。以下是一个简单的示例代码: ```html <template> <div> <el-select v-model="selectedItem" filterable remote :remote-method="fetchData" :loading="isLoading"> <el-option v-for="item in items" :key="item.id" :label="item.name" :value="item.id"></el-option> </el-select> <el-pagination :current-page="currentPage" :page-size="pageSize" :total="total" @current-change="handleCurrentChange"></el-pagination> </div> </template> <script> export default { data() { return { selectedItem: null, items: [], total: 0, currentPage: 1, pageSize: 10, isLoading: false } }, methods: { fetchData(query) { this.isLoading = true; setTimeout(() => { // 发送ajax请求获取数据 // ... // 将获取到的数据设置到items和total中 this.items = [{id: 1, name: 'Option 1'}, {id: 2, name: 'Option 2'}]; this.total = 2; this.isLoading = false; }, 1000); }, handleCurrentChange(currentPage) { this.currentPage = currentPage; // 重新发送数据请求 this.fetchData(); } } } </script> ``` 在上面的代码中,我们使用`<el-select>`组件来展示下拉框,设置`filterable`属性为`true`表示启用搜索功能,设置`remote`属性为`true`表示启用远程搜索功能,然后使用`:remote-method`属性来绑定搜索方法`fetchData`。在`fetchData`方法中,我们可以使用`setTimeout`模拟异步请求数据的过程,并将获取到的数据设置到`items`和`total`中。同时,我们还使用了`<el-pagination>`组件来展示分页器,并使用`@current-change`事件来监听分页器页码的变化,然后重新发送数据请求。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值