element-ui select实现关键词高亮并实现关联搜索

 如图。利用select实现搜索并且关键词高亮显示,支持滚动加载。

step1:基本页面结构

  <div class="search-wrap">
          <div class="search-ipt-element">
            <div class="search-prepend">
              <div
                class="search-prepend-inner"
                @click="showCityFlag=true"
              >
                <span>
                  <i class="el-icon-map-location fs20 theme-color" />
                </span>
                <span :class="[curCityName.length>3?'ellipsis':'' ,'city-name']">{{ curCityName }}</span>
              </div>
            </div>
            <el-select
              class="hxstyle-input-select-ele"
              v-model="query.searchName"
              clearable
              filterable
              remote
              v-loadmore="loadmore"
              :remote-method="remoteSearch"
              @clear="clearKeyword"
              placeholder="搜索小区名称/地址"
            >
              <el-option
                v-for="item in communityList"
                :key="item.value"
                :label="item.name"
                :value="item.code"
                @click.native="handleSelect(item)"
              >
                <div class="search-key-item">
                  <div class="search-key-item-cont">
                    <div
                      class="search-key-item-title"
                      v-html="item.parseName"
                    >
                    </div>
                    <div class="search-key-item-sub">
                      {{ item.address }}
                    </div>
                  </div>
                  <div class="search-key-item-num">
                    {{ item.houseTypeCount }}个户型
                  </div>
                </div>
              </el-option>
              <p
                class="loading-txt"
                v-if="loading"
              >
                <i class="el-icon-loading"></i>
                玩命加载中...
              </p>
              <div
                class="option-empty"
                slot="empty"
              >
                在<span class="option-empty-tip">{{curCityName}}</span>,未搜索到与"<span class="option-empty-tip">{{query.searchName}}</span>"相关的⼩区
              </div>
            </el-select>
            <div
              slot
              class="append-btn"
              @click="querySearch"
            >搜索</div>
          </div>
        </div>

 step:实现远程搜索:

data() {
    return {
      scrollShow: false,
      showCityFlag: false,
      communityList: [],
      loading: false,
      hasLocated: false,
      query: {
        searchName: "",
        cityCode: "",
        isMatchAddr: true,
        pageNo: 1,
        size: 20,
      },
      selectParams: {
        collectType: "2",
        provinceId: "",
        cityId: "",
        areaId: "",
        bedroom: -1,
        livingRoom: -1,
        kitchen: -1,
        pageNo: 1,
        size: 20,
        bathroom: -1,
      },
     
    };

methods:{   
//每次更新关键词。我们需要重新设置关键词并且把pageNo重置为1
    remoteSearch(data) {
      console.log("remoteSearch---data:", data);
      this.query.searchName = data;
      this.query.pageNo = 1;
      this.communityList = [];
      this.querySearch();
    },
//点击搜索item的逻辑与本案例无关
    handleSelect(){
    },
//搜索关键词请求接口的逻辑
    querySearch() {
      getCommunityList(this.query)
        .then((res) => {
          this.communityList = res.data.list || [];
          this.communityList = this.setHightLight(
            this.communityList,
            this.query.searchName
          );
        })
        .catch((err) => {
          throw new Error(err);
        });
    },
//设置高亮的逻辑
     setHightLight(arr, keyword) {
      if (arr && arr.length > 0 && keyword) {
        arr = arr.filter((item) => {
          let reg = new RegExp(this.query.searchName, "g");
          let replaceString = `<span style="color:#ff8c00;padding:0">${keyword.trim()}</span>`;
          if (item.name.match(reg)) {
            //为了不影响原始name,我们这里给item重新设置一个parseName,模板中显示的是parseName
            item.parseName = item.name.replace(reg, replaceString);
            return item;
          }
        });
        return arr;
      }
    },
//滚动加载更多逻辑
   loadmore() {
      this.loading = true;
      this.query.pageNo++;
      console.log("trigger----loadermore", this.query.pageNo);
      getCommunityList(this.query)
        .then((res) => {
          this.loading = false;
          if (this.communityList.length == res.data.total) {
            return;
          } else {
            let list = res.data.list || [];
            this.communityList = this.communityList.concat(list);
            this.setHightLight(this.communityList, this.query.searchName);
          }
        })
        .catch((err) => {});
    },
}

step3:实现下拉加载:这里采用了网上其他博友的方案,通过设置一个自定义指令来实现滚动加载更多。在根目录下新建一个directive.js文件,然后在需要的页面引入

import Vue from 'vue'
let sDirective = {}
export default sDirective.install = function(vue, options) {
  Vue.directive('loadmore', {
    bind (el, binding) {
      const selectDom = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
      selectDom.addEventListener('scroll', function () {
        const isEnd = this.scrollHeight - this.scrollTop <= this.clientHeight
        if (isEnd) {
          binding.value()
        }
      })
    }
  })
}

到此已经实现了这个效果:

有几个要注意的点:

1 关键词不要通过watch监听的方式去走请求,最好通过remote方法得到最新值以后重新赋值来处理

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值