基于antd-vue封装的下拉选择框滑动加载并且带搜索还可以新增的功能

还是那句话,只有你想不到的,没有产品不敢想的。

这个也无需求也是emmmmm头一回接。

那就是下拉框数据很多的时候不想要一次性查出来,想要滑动加载,那第一反应很简单咯,分页查询嘛

<a-select
              v-decorator="[
                'organizationId',
                {
                  initialValue: showData.organizationName,
                },
              ]"
              show-search
              allow-clear
              placeholder="请选择"
              :filter-option="false"
              @popupScroll="popupScroll"
              @change="change"
              @search="handleSearch"
            >
              <a-select-option
                v-for="item in list"
                :key="item.id"
                :value="item.id"
              >
                {{ item.name }}
              </a-select-option>
            </a-select>

```bash
//查询参数,分页查
parmas:{
        keyword:'',
        page:1,
        pageSize:10
      },
//查数据
getList(option) {
//防重复,防抖节流
      if(this.loading){
        return
      }
      this.loading= true
      //接口
      listApi(this.parmas).then((res) => {
        if (res.errorCode == "200") {
        	//判断一下数据是否为空
          if(res.data.length == 0){
            this.loading= false
            return
          }
          //list赋值
          this.list= res.data
          //记录总数
          this.total= res.total
          this.loading= false
        }
      }).catch( err => {
        if(err){
          this.loading= false
        }
      });
    },

基本的获取数据的方法是老生常谈了,然后再来看滑动加载数据,肯定是先滑动加载方法

// 下拉列表滑动加载
    popupScroll(e) {
      const { clientHeight, scrollHeight, scrollTop } = e.target;
      //判断一下滚动条
      if (scrollHeight - scrollTop > clientHeight && !this.loading) {
      //计算一下当前所查分页是否还有数据,如果小于总数则查,大于则不查,防抖节流,减少服务器损耗
        if(this.parmas.page * 10 < this.total){
          this.parmas.page += 1
          this.getList()
        }
      } 
    },

滑动加载肯定是要保留之前的数据,后查出来的跟排队似的,一个个贴上去成一个队伍,那肯定是是不能直接赋值了,所以得改一下获取数据的方法

//查数据
getList(option) {
//防重复,防抖节流
      if(this.loading){
        return
      }
      this.loading= true
      //接口
      listApi(this.parmas).then((res) => {
        if (res.errorCode == "200") {
        	//判断一下数据是否为空
          if(res.data.length == 0){
            this.loading= false
            return
          }
          //list赋值,运用...运算把之前查到的数据和后查的数据拼接起来
         this.list = [...this.list , ...res.data]
          //记录总数
          this.total= res.total
          this.loading= false
        }
      }).catch( err => {
        if(err){
          this.loading= false
        }
      });
    },

除此之外,产品有希望数据太多了,我想要查询怎么办。当然很多人肯定想框架自己提供了可以搜索啊。

但是我的宝,你要明白你滑动加载了啊,你只能搜索你查出来的数据啊,所以我们还是要借助接口,传入查询条件的时候,返回新的数据。

但是她查新的数据,清除掉数据的时候当前希望保留之前我已经查过的数据,介绍服务器端的损耗嘛,那当然吧之前的数据备份啊。

至于这个备份嘛,可以深度克隆,也可以直接赋值

定一个newarray:【】来接受备份数据,等于每次查的时候都备份一下

也就是上述代码多加一行代码

this.list = [...this.list , ...res.data]
//备份一下
this.newarray  = [...this.list]

接下来肯定是查询方法处理啊

handleSearch(e) {
查询肯定是要清空当前得容器
      this.list= []
      if (!e || e == "") {//清空查询关键词的操作
        this.parmas.keyword = null;
        //清空肯定是要把之前备份的数据还给容器,还要计算当查询的页数
        //这块有人提出来有问题,不应该向下取整,应该向上取整
      	***//我们的需求是数据是整10整100的,所以计算分页的时候不会出现余数,所向下取整是没错的。但是如果数据不是整十整百的,出现余数的话,当前页数应该是向上取整Math.ceil()才对***
        this.parmas.page = Math.floor(this.newarray.length / 10)
        this.list= this.newarray  
      }else{//查询处理
        this.parmas.page = 1;
        this.parmas.keyword = e
        this.getList('search')
      }
    },

接下来查询数据的处理就看你怎么处理了,可以写两个方法,一个查询,一个滑动加载的,本质上他们是一个方法,但是我比较懒,所以公用一个方法

也就是上述的getList方法多加几行代码搞定,首先加入option分辨一下单签操作是查询还是滑动加载,然后根据相应操作处理一下

//查数据
getList(option) {
//防重复,防抖节流
      if(this.loading){
        return
      }
      this.loading= true
      //接口
      listApi(this.parmas).then((res) => {
        if (res.errorCode == "200") {
        	//判断一下数据是否为空
          if(res.data.length == 0){
            this.loading= false
            return
          }
          //list赋值,运用...运算把之前查到的数据和后查的数据拼接起来
         if(option){
         //查询直接赋值
            this.list= res.data
          }else{
          //否则拼接数据
            this.list= [...this.list, ...res.data]
            this.newarray  = [...this.list]
          }
          //记录总数
          this.total= res.total
          this.loading= false
        }
      }).catch( err => {
        if(err){
          this.loading= false
        }
      });
    },

你以为完了吗,你天真了,如果我选择的没有我想要的怎么办呢?那新增一个呗,还能咋办呐,真的是

<a-select
              v-decorator="[
                'organizationId',
                {
                  initialValue: showData.organizationName,
                  rules: [{ required: true, message: '请选择部门' }],
                },
              ]"
              show-search
              allow-clear
              placeholder="请选择部门"
              :filter-option="false"
              @popupScroll="popupScroll"
              @change="getOrgName"
              @search="handleSearch"
            >
              <div slot="dropdownRender" slot-scope="menu">
                <v-nodes :vnodes="menu" />
                <div
                  class="add-node"
                  @mousedown="(e) => e.preventDefault()"
                  @click="addItemShow"
                >
                  新增数据
                </div>
              </div>
              <a-select-option
                v-for="item in list"
                :key="item.id"
                :value="item.id"
              >
                {{ item.name }}
              </a-select-option>
            </a-select>

注意到VNodes没有,要加的就是它呢,废话不多说,先引入啊
components: {
VNodes: {
functional: true,
render: (h, ctx) => ctx.props.vnodes,
}
},

我这边为了处理方便把这个新增的方法抽出来了,你也可以写在一起,新增可以写个弹框来新增

<a-modal
      v-model="visible"
      title="新增"
      @cancel="cancel"
      width="560px"
    >
      <a-row>
        <a-form
          :form="form"
        >
          <a-form-item>
            <a-input
              v-decorator="[
                'organizationName',
                {
                  rules: [{ required: true, message: '数据不能为空' }],
                },
              ]"
              allow-clear
              :maxLength="30"
              placeholder="请输入"
            >
            </a-input>
          </a-form-item>
        </a-form>
      </a-row>
      <div slot="footer">
        <a-button @click="cancel">取消</a-button>
        <a-button type="primary" @click="submit" :disabled="loading"
          >确定</a-button
        >
      </div>
    </a-modal>
addItemShow(){
this.visible = true
}

新增成功之后当然是直接查数据了,渲染啊,如果拆成组件记得回调父组件的方法。

如有其它问题,请联系我~

你可能感兴趣的:(vue.js,javascript,前端)