基于Element的select组件的二次开发

基于Element的select组件的二次开发

近况

哎呀呀,也是好久好久没有更新博客,一个是因为需求太多,另一个是因为太懒(哈哈,这个是主要原因),最近都在做Element的需求,因为是之前的项目,vue3和Element-Plus也还没开始用,准备多学习学习在小项目上练练手。

需求

好啦废话不多说啦,最近接到这么一个需求,在基础的饿了么的选择器中加入头像,姓名,描述等信息。大致就是这样样子:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021051715011831.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p3ZDg2MjM3NTY5OA==,size_16,color_FFFFFF,t_70

看到这里并没有什么问题,因为select组件是支持自定义options的样式的。无良的产品要求选择完之后要在输入框里也显示头像,类似这个效果:
在这里插入图片描述

WTF,真是想分分钟想提刀的节奏。但是气归气,但是又无法拒绝,所以只能默默地打开了度娘。搜了一圈是之后也没发现啥有用的东西,哎,还是自己来吧。

实现思路

  • 如何在input框内还能显示img图片呢?
    我的思路就是用一个div绝对定位在input内,在selectchange事件中触发,并且用自己写的一个input来遮盖el-select组件,达到以假乱真的效果。
  • 多选如何实现?
    el-selcet组件是支持多选的,所以选择的事件不是很难,比较麻烦的是要自己去定义每个item的样式和删除功能。
  • 多选带来的样式问题?
    在选择多个达到两行的时候,所选择的人物会超过原来input的高,会导致样式错误,我的思路是监听选择人物数量的同时去获取选择人物div的高,将它的高赋值给input

具体实现

  • 隐藏el-select原有样式,只是隐藏并不是display:none哦,用自己的input覆盖样式。
    在这里插入图片描述

注意看,el-select是被我visibility: hidden;隐藏掉了并且定位到我自己写的input下。

  • 点击自己画的input的时候来触发el-selcet的下拉框弹出事件
 	this.$refs.select.handleFocus();
  • el-selectchange事件中做处理
 handleSelectChange(v) {
      this.form.queryStaff = v;
      this.inputValue = "";// input内输入的值
      this.form.queryStaffPlaceholder = v.name; //input的placeholder
      this.isShowUserInfo = true;//是否显示头像信息
      this.$refs.form.validateField("queryStaff"); //触发一次表单验证
    },

注意:因为我们不止要拿到选择的姓名,所以el-select绑定的value应该是对象,并且设置value-key="id",才能完成对对象的绑定。

  • 多选的时候遇到样式错乱的解决办法
watch: {
  "form.enjoypeople": {
      handler(val) {
        if (val.length) {
          this.$nextTick(() => {
            let height = this.$el.querySelector(".form1-tag").clientHeight;
            this.$refs.input_enjoy_dryform1.style.height =
              height > 4
                ? this.$el.querySelector(".form1-tag").clientHeight + 4 + "px"
                : 32 + "px";
          });
        }
      },
      deep: true,
    },
}

具体代码(多选为例):

			<div class="record-meeting__elinput">
                <div class="el-input_dry">
                  <input
                    ref="input_enjoy_dry"
                    @focus="handleQueryMutipleStaffFocus"
                    @click.stop="handleQueryEnjoyClick"
                    @blur="handleQueryMutipleStaffBlur"
                    :placeholder="
                      form.enjoypeople1.length ? '' : '请选择AI人员'
                    "
                    v-model="inputMultipleValue"
                  />
                  <div
                    class="multiple-tag form-tag"
                    style="bottom: 0px;top:auto; "
                    @click="handleMutipleStaffClick"
                    v-if="isShowUserMultipleInfo"
                  >
                    <div
                      v-for="(item, index) in form.enjoypeople1"
                      :key="index"
                      class="multiple-tag__item"
                    >
                      <img
                        :src="
                          item.personFiles.length
                            ? item.httpUrl + item.personFiles[0].fileurl
                            : require('@/assets/img/user.png')
                        "
                      />
                      <span>{{ item.name }}</span>
                      <i
                        class="el-tag__close el-icon-close"
                        @click.stop="handleMultipleDel(index)"
                      ></i>
                    </div>
                  </div>
                </div>
                <el-select
                  v-model="form.enjoypeople"
                  multiple
                  ref="selcet_enjoy"
                  filterable
                  remote
                  reserve-keyword
                  value-key="id"
                  @change="handleSelectMutipleChange"
                  v-loadmore="handleenjoyPopupScroll"
                  :remote-method="remoteMethodsearchpeople"
                  placeholder="请选择参会人"
                  style="width:320px;position: absolute;
    display: block;visibility: hidden;height:0;bottom: 184px;"
                  :loading="loading"
                >
                  <el-option
                    v-for="(item, index) in curSelectOptionssearchpeople"
                    :key="index"
                    :label="item.name"
                    :value="item"
                  >
                    <div class="select-item">
                      <img
                        :src="
                          item.personFiles.length
                            ? item.httpUrl + item.personFiles[0].fileurl
                            : require('@/assets/img/user.png')
                        "
                      />
                      <div>
                        <p>{{ item.name }}</p>
                        <p :title="item.description">{{ item.description }}</p>
                      </div>
                    </div>
                  </el-option>
                </el-select>
              </div>
//点击出现下拉框
  handleQueryEnjoyClick() {
      this.$refs.selcet_enjoy.handleFocus();
    },
   handleSelectMutipleChange(v) {
      this.inputMultipleValue = "";
      this.isShowUserMultipleInfo = true;
    },
    //input Focus 事件
    handleQueryMutipleStaffFocus() {
      if (!this.form.enjoypeople.length) {
      //为了避免触发两次出现弹框
        return;
      }
      this.isShowUserMultipleInfo = false;
      this.handleQueryEnjoyClick();
    },
    //点击删除事件
     handleMultipleDel(index) {
      this.form.enjoypeople.splice(index, 1);
    },
    //失焦事件 如果有之前有选择的内容,显示选择的内容
  handleQueryMutipleStaffBlur() {
      if (this.form.enjoypeople.length) {
        this.isShowUserMultipleInfo = true;
      }
    },

最后实现效果

在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值