el-select选择器 下拉菜单组件封装element-ui

前言

我们都知道elementui的选择器组件(下拉菜单)局限性很多,比如说选项不能展示更多行内容,数据量太大的话卡顿(因为没有分页)等等。博主这里分享一个自己封装的组件,解决了这些所有问题,可展示多行内容,单选或多选,分页,禁用,输入搜索,在使用时更加的灵活。


组件使用截图

el-select选择器 下拉菜单组件封装element-ui_第1张图片
el-select选择器 下拉菜单组件封装element-ui_第2张图片

组件代码

<template>
  <!-- 会员自定义选择(多选/单选/分页) -->
  <el-select
    ref="select0"
    value-key="memberId"
    :style="{ width: inputwidth }"
    v-model="keyword"
    filterable
    :multiple="multiple"
    clearable
    remote
    :disabled="nochange"
    :remote-method="phoneinput"
    @change="projectnameClick"
    @click.native="myOnClick"
    placeholder="请选择或输入姓名/手机号搜索"
  >
    <el-option
      class="member-item"
      v-for="(item,index) in list"
      :key="item.memberId+new Date()+index"
      :label="item.memberName+' '+item.mobile+' '+item.companyName+'/'+item.deptName"
      :value="item"
    >
      <div class="member-item">
        <div>
          <div>{{ item.memberName }}</div>
          <div>{{ item.mobile }}</div>
          <div v-if="item.technicianNames">专属老师:{{ item.technicianNames }}</div>
          <div v-else style="color:#909399">暂无专属老师</div>
        </div>
        <div>{{ item.companyName + '/' + item.deptName }}</div>
      </div>
    </el-option>
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      layout="total, prev, next, jumper"
      @pagination="getpageList"
    />
  </el-select>
</template>
<script>
import {memberList} from "@/api/comm";

export default {
  name: "SelectMemberInput",
  components: {},
  props: {
    value: {
      type: [Array, String, Number],
    },
    //禁用状态
    nochange:{
      type: Boolean,
      default: false,
      required: false
    },
    //input宽度 不是必传项
    inputwidth: {
      type: String,
      default: "210px",
      required: false,
    },
    //是否多选 默认不多选 不是必传项
    multiple: {
      type: Boolean,
      default: false,
      required: false,
    },

  },
  model: {
    prop: "value",
    event: "input",
  },
  data() {
    return {
      keyword: "",
      queryParams: {
        keyword: "",
        memberIds: "",
        pageNum: 1,
        pageSize: 10
      },
      list: [],
      total:0
    };
  },
  created() {

  },
  mounted() {
  },
  watch: {
    value: {
      handler(newVal, oldVal) {
        this.queryParams.pageNum = 1;
        this.getList('', newVal ? newVal.toString() : '');
        this.keyword = {
          memberId:newVal
        };
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    getpageList(){
       memberList(this.queryParams).then((response) => {
        this.list = response.rows;
        this.total = response.total;
      });
    },
    getList(keyword, memberIds) {
      this.queryParams.keyword = keyword;
      this.queryParams.memberIds = memberIds;
      memberList(this.queryParams).then((response) => {
        this.list = response.rows;
        this.total = response.total;
      });
    },
    //选择
    phoneinput: function (keyword) {
      this.keyword = keyword;
      this.getList(keyword, '');
    },
    myOnClick:function (){
      this.getList();
    },
    projectnameClick: function (item) {
      this.$emit("input", item.memberId);
      this.$emit("selinfo", item);//传item对象 父组件可接受取用label
    }
  }
};
</script>
<style lang="scss" scoped>
.select-box {
  display: flex;
  align-items: center;
}
.member-item {
  display: flex;
  min-width: 400px;
  height: 76px;
  border-bottom: 1px solid #dcdbb6;
  justify-content: space-between;
  align-items: center;
  line-height: 20px;
}
.user-item {
  display: flex;
  min-width: 400px;
  height: 60px;
  border-bottom: 1px solid #dcdbb6;
  justify-content: space-between;
  align-items: center;
  line-height: 26px;
}
.el-select-dropdown__item {
  padding: 0 22px 0 18px !important;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {
  content: "" !important;
}
::v-deep .el-input-group__prepend div.el-select .el-input__inner {
  background-color: #fff;
}
::v-deep .el-input.is-disabled .el-input__inner {
  color: #606266!important;
}
</style>

组件的查询数据替换成自己的查询哦~
这里分页也是引用的组件,可以自己写。或者先关注博主,以后会分享出来

使用

引入组件试试吧~

END

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