select下拉菜单自由扩展-输入框添加/options删除

背景
antdv select 官方使用dropdownRender对下拉菜单进行自由扩展

效果展示

可添加,删除

代码

<template>
  <div class="select-wrapper">
      <a-select v-model="value"
          style="width: 300px" 
          dropdownClassName="dropdown-class-name" 
          placeholder="请选择学历" 
          :open="open" 
          @select="selectOption" 
          :class="{'ant-select-open': open}" 
          option-label-prop="label"
          :filter-option="filterOption"
          show-search
          :disabled="disabled"
      >
          <div slot="dropdownRender" slot-scope="menu" @click="(e) => {e.stopPropagation()}">
              <v-nodes :vnodes="menu" />
              <a-divider style="margin: 4px 0" />
              <div style="padding: 4px 8px; cursor: pointer">
                  <a-input class="input-txt" v-model="text" placeholder="请输入其他学历" allowClear @blur="addItem" />
              </div>
          </div>
          <a-select-option v-for="(item,index) in items" :key="item" :value="item" :label="item">
              {{ item }}
              <a-icon v-if="index > 2" style="position: absolute;top:30%;right: 10%;" type="delete" @click.stop="deleteItem(item)" />
          </a-select-option>
      </a-select>
      <!--原来的,因为有遮罩的div导致不能使用自带的搜索和删除
      <div class="select_overlap" @mousedown="openSelect"></div>-->
      <!--最新方案,展开后隐藏遮罩即可使用组件本身的功能-->
      <div v-show="!open" class="select_overlap" @mouseup="openSelect"></div>
  </div>
</template>
<script>
export default {
  props: {
    value:{
      type: String,
      required: false
    },
    disabled:{
      type: Boolean,
      required: false,
      default: false
    },
  },
  components: {
      VNodes: {
          functional: true,
          render: (h, ctx) => ctx.props.vnodes
      }
  },
  data: () => ({ 
    items: ['大学本科', '硕士研究生','博士研究生'], 
    // value: '', 
    open: false, 
    clickHandle: null,
    text: '',
   }),
  methods: {
      /**
       * 删除分组选项
       */
      deleteItem (label) {
        const index = this.items.indexOf(label)
        this.items.splice(index, 1)
      },
      addItem() {
          this.items.push(this.text)
      },
      openSelect() {
          this.open = !this.open
      },
      selectOption(value) {
          // 单选时设置
          this.$emit('change',value)
          this.open = false
      },
      filterOption(input, option) {
          return option.componentOptions.propsData.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
      },
  },
  mounted() {
      this.clickHandle = (e) => {
          if (e.target && 'className' in e.target && this.open) {
              const className = e.target.className;
              if (className.indexOf('select_overlap') === -1) {
                  this.open = false
              }
          } else {
              this.open = false
          }
      }
      document.body.addEventListener('click', this.clickHandle)
  },
  beforeDestroy() {
      if (this.clickHandle) {
          document.body.removeEventListener('click', this.clickHandle)
          this.clickHandle = null
      }
  }
}
</script>

<style scoped>
.select-wrapper {
    position: relative;
    .select_overlap {
        cursor: pointer;
        height: 32px;
        width: 300px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        opacity: 0;
    }
}

</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JessicaLilyAn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值