vue 实现模糊查询 + 前端分页效果 组件

vue 实现模糊查询 + 前端分页效果

在这里插入图片描述

查询 + 分页组件

<!-- 查询企业 编号 公司 组件 -->
<template>
  <div class="search_business xSelect_container" v-clickoutside="clickoutside">
    <el-input
      class="xSelect_wrap"
      :style="
        labelWType == 1
          ? 'width: calc(100% - 94px)'
          : 'width: calc(100% - 112px)'
      "
      style="height: '32px'"
      v-model="input"
      @input="inputChange"
      placeholder="请输入"
      @focus="inputFocus"
    ></el-input>
    <span
      :style="labelWType == 1 ? 'width:94px' : 'width:112px'"
      class="xSelect_label"
      ><span class="xSelect_check" v-show="isCheck"></span>
      <span> {{ selectOptions.title }}</span>
    </span>
    <div class="search_ul" ref="optionwrapper"  :style="{display: displayFlag}" >
      <ul ref="optionul">
        <li
          v-for="(item, idx) in currentPageData"
          :key="item.id"
          ref="optionitem"
          @click="itemClick(item)"
          @mouseover="move($event, idx)"
          @mouseout="out($event)"
          :class="item.name == currentName ? 'active' : ''"
        >
          <span>{{ item.code }}</span>
          <span>{{ item.name }}</span>
        </li>
      </ul>
      <el-pagination
        v-show="total"
        :current-page="cPage"
        :page-size="10"
        layout="total, prev, next"
        :total="total"
        @prev-click="prevPageClick"
        @next-click="nextPageClick"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
import Clickoutside from "@/utils/clickoutside";
export default {
  name: "SearchBusiness",
  components: {},
  directives: {
    Clickoutside,
  },
  props: {
    //给 label 设置宽度 默认94 类型2 为110
    labelWType: {
      type: Number,
      default: 1,
    },
    isCheck: {
      type: Boolean,
      default() {
        return false;
      },
    },
    defaultConfig: {
      type: Object,
      default: () => {},
    },
    cPage: {
      type: Number,
      default: 1,
    },
    currentName: {
      type: String,
      default: "",
    },
    clearBName: {
      type: Boolean,
      default :false
    },
  },
  data() {
    return {
      input: "",
      timer: null, //定时器
      selectOptions: this.defaultConfig,
      currentPageData: [], // 展示的10条数据
      pageSize: 10,
      total: 0,
      displayFlag: "none",
      liClickFlag:false,//是否点击了小 li
    };
  },
  watch: {
    defaultConfig: {
      handler(newV) {
        this.selectOptions = newV;
      },
      deep: true,
    },
    "defaultConfig.options"(newV) {
      this.total = newV.length;
      this.setCurrentPageData();
    },
    "cPage"() {
      this.setCurrentPageData();
    },
    clearBName(val){
      if(val){
        this.input = "";
        this.$store.commit("clearBName", false);
      }
    },
    // 当前数据 
    currentPageData(val){
      // console.log('当前的数据', val);
      if(val.length >= 1){
        this.displayFlag = "block";
      }else{
        this.displayFlag = "none";
        this.$emit("changeSelect", {});
      }
    },
    input(newV){
      // console.log('监听的input',this.input,"newV",newV);
      if(newV && !this.liClickFlag){
        this.displayFlag = "block";
      }else{
        this.displayFlag = "none";
      }
    }
  },
  computed: {
    optionWrapper() {
      //选项的节点
      return this.$refs.optionwrapper;
    },
    subjectList() {
      //选项的 item
      return this.$refs.optionitem;
    },
  },
  mounted() {
    this.$refs.optionwrapper.style.transition = 2 + "s";
  },
  methods: {
    inputChange() {
      let _this = this;
      clearInterval(this.timer);
      this.timer = setTimeout(function () {
        // console.log("当前的value", _this.input);
        _this.$emit("inputChange", _this.input);
      }, 500);
    },
    itemClick(item, idx) {
      this.$emit("changeSelect", item, idx);
      this.input = item.name;
      this.displayFlag = "none";
      this.liClickFlag = true;
    },
    inputFocus(){
      if(this.input){
        this.displayFlag = "block";
      }else{
        this.displayFlag = "none";
      }
    },
    move(event, idx) {
      for (let item of this.subjectList) {
        item.classList.remove("hover");
      }
      event.currentTarget.classList.add("hover");
    },
    out(event) {
      event.currentTarget.classList.remove("hover");
    },
    // 设置当前页
    setCurrentPageData() {
      let begin = (this.cPage - 1) * this.pageSize;
      let end = this.cPage * this.pageSize;
      this.currentPageData = this.selectOptions.options.slice(begin, end);
      // console.log("currentPageData",this.currentPageData);
    },
    // 上一页
    prevPageClick(val) {
      this.$emit("pageClick",val)
    },
    // 下一页
    nextPageClick(val) {
      this.$emit("pageClick",val)
    },
    //点击外层的时候 触发的事件
    clickoutside() {
      if(this.displayFlag){
        this.displayFlag = "none";
      }else{
        this.displayFlag = "block";
      }
    },
  },
};
</script>
<style  lang="scss" scoped>
::v-deep .el-input__inner {
  height: 32px !important;
}
::v-deep .el-pagination {
  padding: 2px 20px !important;
}
.search_business {
  position: relative;
  .search_ul {
    z-index: 10;
    position: absolute;
    overflow: hidden;
    top: 35px;
    left: 10px;
    width: 350px;
    height: 370px;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    background-color: #fff;
    box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
    box-sizing: border-box;

    ul {
      height: 330px;
      overflow: hidden;
      padding: 5px 10px 2px;
      cursor: pointer;
      color: #515a6e;
      li {
        margin-bottom: 3px;
        height: 30px;
        line-height: 30px;
        background: #fff;
        span:nth-child(1) {
          float: left;
          width: 70px;
        }
        span:nth-child(2) {
          padding-left: 10px;
          float: left;
          width: 256px;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          border-left: 1px solid #666;
        }
      }
    }
    .active {
      color: #e82323;
      background: #f5f7fa !important;
      font-weight: 700;
    }
    .hover {
      color: #e82323;
      background: #f5f7fa !important;
    }
  }
}
</style>

点击外层 指令 Clickoutside.js

const clickoutsideContext = '@@clickoutsideContext'

export default {
  bind(el, binding, vnode) {
    const documentHandler = e => {
      if (vnode.context && !el.contains(e.target)) {
        vnode.context[el[clickoutsideContext].methodName]()
      }
    }
    el[clickoutsideContext] = {
      documentHandler,
      methodName: binding.expression,
      arg: binding.arg || 'click'
    }
    document.addEventListener(el[clickoutsideContext].arg, documentHandler)
  },

  update(el, binding) {
    el[clickoutsideContext].methodName = binding.expression
  },

  unbind(el) {
    document.removeEventListener(el[clickoutsideContext].arg, el[clickoutsideContext].documentHandler)
  },

  install(Vue) {
    Vue.directive('clickoutside', {
      bind: this.bind,
      unbind: this.unbind
    })
  }
}

使用该 组件 实现模糊查询 + 前端 分页

  • html
	<SearchBusiness :defaultConfig="BusinessName" @inputChange="bNameInputChange" @pageClick="pageClick" :cPage="cPage" 
          @changeSelect="bNameChangeSelect" :currentName="bNameCurrentName" :clearBName="clearBName"  />
  • data
   // 企业编号 相关开始
   BusinessName: {
     title: "企业编号:",
     options: [],
   },
   cPage: 1,//当前页
   bNameCurrentName:"",//当前选中
  
  // 当输入的值 清空的时候 当前页设置为 1
  watch:{
    custno(newV){
      if(!newV){
        this.cPage = 1;
      }
    }
  },
  // 计算属性 去vuex 之中拿到 一开始请求回来的 所有数据 
  computed:{
    customerNumber() {
      return this.$store.state.creditMag.customerData;
    },
  }
  • methods
    // 企业编号的 改变
    bNameInputChange(val){
      // console.log('企业编号的失去焦点', val,this.customerNumber.length);
      this.BusinessName.options = [];
      if(!val){
        this.BusinessName.options = [];
      }else{
        for(let i = 0; i < this.customerNumber.length - 1; i++ ){
        	// 实现 前端 模糊 查询 
          if(val && this.customerNumber[i].name.toLowerCase().indexOf(val.toLowerCase()) !== -1 || this.customerNumber[i].code.indexOf(val) !== -1){
          	// 把数据存储起来 为了 传递到子组件之中!
            this.BusinessName.options.push(this.customerNumber[i])
          }
        }
      }
      // console.log('this.BusinessName.options',this.BusinessName.options.length,this.BusinessName.options);
    },
    // 控制 分页页数
    pageClick(val){
      this.cPage = val;
    },
    // 下拉选中修改的时候 切换
    bNameChangeSelect(item){
      this.custno = item.name;
      this.bNameCurrentName = item.name;
    },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值