Vue+ElementUI 下拉框问题的一个解决方案

发布时间 2023-10-27 10:45:40作者: newbigapple

问题描述:Vue使用ElementUI使用下拉框组件时,点击空白处,无法隐藏展开的选项。build项目后,此类问题时有时无,不确定。
于是自己做了个组件封装一下原生下拉框,解决无法关闭下拉选项问题。代码如下:

<template>
  <div :ref="'div_my_select_component_'+rid" v-click-outside="handleClose">
    <el-select :key="rid" :ref="refName" v-model="selectModel" @change="handleChange"
               :size="size" :disabled="disabled" :clearable="clearable" :filterable="filterable"
               :filter-method="filterMethod"
               v-bind="$attrs"
               v-on="$listeners"
    >
      <el-option v-for="(item,index) in dataList"
                 :key="index"
                 :value="typeof (valueKey)=='function'? valueKey(item,index):item[valueKey]"
                 :label="typeof (labelKey)=='function'? labelKey(item,index):item[labelKey]"
                 v-if="optionIfFn?optionIfFn(item,index):true"
                 :disabled="optionDisabledFn?optionDisabledFn(item,index):false"
      ></el-option>
    </el-select>
  </div>
</template>
<script>
import Clickoutside from '../utils/clickoutside';


export default {
  name: 'MySelect',
  directives: {
    "click-outside": {
      bind(el, binding, vNode) {
        Clickoutside.bind(el, binding, vNode)
      },
      unbind(el) {
        Clickoutside.unbind(el)
      }
    }
  },
  props: {
    value: {
      type: [Number, String, Array]
    },
    dataList: {
      type: Array
    },
    valueKey: {
      type: [String, Function],
      default() {
        return 'value';
      }
    },
    labelKey: {
      type: [String, Function],
      default() {
        return 'label';
      }
    },
    size: String,
    disabled: Boolean,
    clearable: Boolean,
    filterable: Boolean,
    filterMethod: Function,
    optionIfFn: Function,
    optionDisabledFn: Function
  },

  data() {
    return {
      rid: null,
      refName: 'my_select_component',
      selectModel: null
    };
  },
  watch: {
    value: {
      handler(newValue, oldValue) {
        this.selectModel = newValue;
      },
      immediate: true
    },
    selectModel: {
      handler(newValue, oldValue) {
        this.$emit('input', newValue)
      }
    }
  },
  created() {
    this.rid = Math.random().toString().replace('.', '');
    this.refName += "_" + this.rid;

  },
  beforeCreate() {

  },

  beforeDestroy() {
    // console.log('beforeDestroy')

  },

  computed: {},

  mounted() {
  },

  methods: {
    handleChange(e) {
      this.$emit('change', e);
    },
    handleClose() {
      if (this.$refs[this.refName]) {
        this.$refs[this.refName].handleClose();
      }
    },
  },
}
;

</script>


调用示例
多选情况

  <my-select
                v-model="form.roleIds"
                multiple
                collapse-tags 
                placeholder="请选择"
                @change="$forceUpdate()"
                :data-list="roleOptions"
                label-key="name"
                value-key="roleId"
                :option-disabled-fn="function(item) {
                  return item.status === STATUS.DISABLE;
                }"
              ></my-select>

单选情况

  <my-select :data-list="CategoryDict" v-model="form.category" placeholder="请选择"
                       clearable @change="handleCategoryChange"
            ></my-select>