可分页+可远程搜索的select框实现(单选)

先看一下效果

在这里插入图片描述

接下来说明实现的方式,最后再贴出完整的相关代码

一、分页实现(滚动到底部会进行下一页的加载):

  • 监听滚动条是否滚到到底部
  • 到底部了判断是否要加载数据

1.下拉列表设置一个id(selected-content),用于声明滚动条事件

<div class="selected-content" id="selected-content" style="display: none">
      .....暂略
    </div>

2.在mounted中声明滚动条事件(selectScroll())

mounted () {
    let that = this;
    // 声明滚动条滚动事件
    document.getElementById('selected-content').addEventListener('scroll', this.selectScroll);
  },

3.监听事件

// 滚动条滚动事件,在mounted要声明该事件(select框分页)
    selectScroll () {
      let that = this;
      // 变量scrollTop是滚动条滚动时,距离顶部的距离
      that.scrollTop = document.getElementById('selected-content').scrollTop;
      // 变量divHeight是可视区的高度
      let divHeight = document.getElementById('selected-content').clientHeight;
      // 变量scrollHeight是滚动条的总高度
      let scrollHeight = document.getElementById('selected-content').scrollHeight;
      // 滚动条到底部的条件
      if (that.scrollTop + divHeight === scrollHeight) {
        console.log('到底部啦!!!!!!!!!!!!!!!!!!!');
        // 若总数除以每页的数量大于当前页码的,说明数据还没加载完,继续向后台加载数据
        if (that.totalTenants / that.pageSize > that.currentPageNumber) {
          that.loading = true;
          that.pageNumber++;
          // 获取数据
          that.searchTotalTenants();
        }
      }
    },

二、远程搜索实现
1.添加keyup事件(selectKeyDown()),键盘弹起时候进行后台搜索

<input class="el-input__inner"
          id="tentant-input"
          v-model="tenantName"
          type="text"
          @click="inputClick()"
          @keyup="selectKeyDown()"
          onautocomplete="off"
          placeholder="请选择"
          style="width: 200px">
// select框键盘弹起事件(键盘弹起时,触发搜索事件)
    selectKeyDown () {
      let that = this;
      that.pageNumber = 1;
      that.pageSize = 15;
      // 向后台查询时,将原来select框的值置空
      that.tenantOptions = [];
      // 重新获取数据
      that.searchTotalTenants();
      // 搜索时弹出下拉列表
      $('#selected-content').fadeIn(400);
    },

以上主体功能实现了,接下来说一下次要功能

1.清除input事件

// 清除input值事件
    deleteButtonClick () {
      let that = this;
      // 一系列的条件初始化(根据你的实际项目做修改)
      that.tenantName = '';
      // 清除选中的高亮颜色
      that.current = '';
      // 清空时做input的focus和下拉列表的显示
      $('#tentant-input').focus();
      $('#selected-content').fadeIn(400);
    },

2.高亮选中颜色的实现

  • 动态绑定一个class( v-bind:class="{ selected: index === current}")
  • 列表内容点击时候,在事件中将index赋值给current,这样就可以实现高亮选中颜色了
<div class="selected-content" id="selected-content" style="display: none">
      <ul class="el-scrollbar__view el-select-dropdown__list ul-content" >
        <li class="el-select-dropdown__item" v-bind:class="{ selected: index === current}"
            v-for="(i, index) in tenantOptions" :key="index" @click="contentClick(i.value, i.label, index)">
          <span>{{i.label}}</span>
        </li>
      </ul>
 </div>
// 下拉框内容点击事件
    contentClick (tenantId, tenantName, index) {
      let that = this;
      // 选择时设置字体颜色
      that.current = index;
      // 选取的值回显到input框(根据自己的项目进行修改即可)
      that.tenantIdValue = tenantId;
      that.tenantName = JSON.parse(JSON.stringify(tenantName));
      // 选值后关闭下拉框
      $('#selected-content').slideToggle(400);
    },

3.下拉列表的显隐

// select Input框点击事件
    inputClick () {
      // 弹出下拉框
      $('#selected-content').slideToggle(400);
    },

以上主次功能都已实现,接下来贴一下相关的完整代码

dom内容

<!--input框-->
    <div class="el-select el-select--small">
      <div class="el-input el-input--small el-input--suffix"
           @mouseover="tenantName? isDeleteButton=true : isDeleteButton=false"
           @mouseleave="isDeleteButton=false">
        <input class="el-input__inner" id="tentant-input" v-model="tenantName" type="text"
               @click="inputClick()" @keyup="selectKeyDown()" onautocomplete="off"
               placeholder="请选择" style="width: 200px">
        <!--点击删除select框的值时,将选中的样式去掉(current='')-->
        <span class="delete-selected" v-if="isDeleteButton" @click="deleteButtonClick()">
          <i class="iconfont icon-fail"></i>
        </span>
      </div>
    </div>
<!--下拉列表-->
    <div class="selected-content" id="selected-content" style="display: none">
      <ul class="el-scrollbar__view el-select-dropdown__list ul-content" >
        <li class="el-select-dropdown__item" v-bind:class="{ selected: index === current}"
            v-for="(i, index) in tenantOptions" :key="index" @click="contentClick(i.value, i.label, index)">
          <span>{{i.label}}</span>
        </li>
      </ul>
      <p class="tip-class" v-if="tenantOptions.length === 0">暂无数据</p>
      <p class="tip-class" v-if="loading">数据加载中...</p>
      <p class="tip-class" v-if="isAllLoaded">没有更多数据了~</p>
    </div>

js(ps:放在编辑器看好一点~)

mounted () {
    // 声明滚动条滚动事件
    document.getElementById('selected-content').addEventListener('scroll', this.selectScroll);
  },

methods方法:

// selectInput框点击事件
    inputClick () {
      // 弹出下拉框
      $('#selected-content').slideToggle(400);
    },
    // select框键盘弹起事件(键盘弹起时,触发搜索事件)
    selectKeyDown () {
      let that = this;
      that.pageNumber = 1;
      that.pageSize = 15;
      // 向后台查询时,将原来select框的值置空
      that.tenantOptions = [];
      // 重新获取数据
      that.searchTotalTenants();
      // 搜索时弹出下拉列表
      $('#selected-content').fadeIn(400);
    },
    // 查询所有租户
    searchTotalTenants () {
      let that = this;
      // 查询租户
      ApiService.searchAllTenants({
        name: that.tenantName, //
        type: that.operationStatus === '正式' ? 0 : 1, // 正式/测试
        pageNumber: that.pageNumber,
        pageSize: that.pageSize
      }).then(res => {
        if (res.statusCode === 'OK') {
          // 获取租户总条数
          that.totalTenants = parseInt(res.data.total);
          // select框数据的当前页码
          that.currentPageNumber = parseInt(res.data.current);
          // 获取数据成功,隐藏select框加载中提示
          that.loading = false;
          let reDatas = res.data.records;
          for (let i in reDatas) {
            // 将租户id、租户名字、租户类型(个人or公共)存起来
            let tempObj = {value: reDatas[i].id, label: reDatas[i].name, tenantType: reDatas[i].payType, softConcurrency: reDatas[i].softConcurrency, crcConcurrency: reDatas[i].crcConcurrency};
            that.tenantOptions.push(tempObj);
          }
          // 后台已经没有数据了,select框提示“没有更多数据”
          if (that.totalTenants / that.pageSize === that.currentPageNumber) {
            that.isAllLoaded = true;
          }
        } else {
          this.$notify({
            message: '请求租户数据错误:' + res.message,
            type: 'warning',
            offset: 80,
            duration: 2000
          });
          // 获取数据失败,隐藏select框加载中提示
          that.loading = false;
        }
      })
    },
    // 清除input值事件
    deleteButtonClick () {
      let that = this;
      that.tenantName = '';
      that.current = '';
      $('#tentant-input').focus();
      $('#selected-content').fadeIn(400);
    },
    // 滚动条滚动事件,在mounted要声明该事件(select框分页)
    selectScroll () {
      let that = this;
      // 变量scrollTop是滚动条滚动时,距离顶部的距离
      that.scrollTop = document.getElementById('selected-content').scrollTop;
      // 变量divHeight是可视区的高度
      let divHeight = document.getElementById('selected-content').clientHeight;
      // 变量scrollHeight是滚动条的总高度
      let scrollHeight = document.getElementById('selected-content').scrollHeight;
      // console.log('距顶部' + that.scrollTop + '可视区高度' + divHeight + '滚动条总高度' + scrollHeight);
      // 滚动条到底部的条件
      if (that.scrollTop + divHeight === scrollHeight) {
        console.log('到底部啦!!!!!!!!!!!!!!!!!!!');
        // 若总数除以每页的数量大于当前页码的,说明数据还没加载完,继续向后台加载数据
        if (that.totalTenants / that.pageSize > that.currentPageNumber) {
          that.loading = true;
          that.pageNumber++;
          // 获取数据
          that.searchTotalTenants();
        }
      }
    },
    // 下拉框内容点击事件
    contentClick (tenantId, tenantName, index) {
      let that = this;
      // 选择时设置字体颜色
      that.current = index;
      // 选取的值回显到input框
      that.tenantIdValue = tenantId;
      that.tenantName = JSON.parse(JSON.stringify(tenantName));
      // 选值后关闭下拉框
      $('#selected-content').slideToggle(400);
    },

CSS:

  • 样式是根据element-ui改的,如果不用element-ui,要自己折腾一下样式~
  • 有一些element-ui内置的样式没有贴出来,安装了element-ui应该都可以的~
.delete-selected {
    float: right;
    margin-top: -23px;
    position: inherit;
    right: -61px;
    color: #d7d3d3;
    cursor: pointer;
  }
  .selected {
    font-weight:bold;
    color:#01baad;
  }
  .el-select .el-input {
    width: 130px;
  }
  .selected-content {
    position: absolute;
    top: 86px;
    left: 165px;
    width: 200px;
    max-height: 250px;
    background: #ffffff;
    border-radius: 4px;
    border: solid 1px #e4e7ed;
    overflow: auto;
    z-index: 999;
    box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
  }
  .tip-class {
    text-align: center;
    height: 30px;
    line-height: 30px;
    color: #b8b4b4;
    font-size: 15px;
    background-color: #f4f4f4;
  }
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值