二次封装element-plus的el-select组件

因为 element-plus的Virtualized Select 虚拟化选择器(el-select-v2)全选有bug

故封装了普通版el-select 并记录

上图

1.子组件

<el-select v-model="selected" filterable multiple clearable collapse-tags collapse-tags-tooltip :collapse-tags-tooltip-placement="tooltipPlacement" :placeholder="placeholder" :props="props.props" popper-class="custom-header" :max-collapse-tags="maxCollapseTags" style="width: 240px">
      <template #header>
         <el-checkbox v-model="isAllChecked" :indeterminate="isIndeterminate" @change="handleCheckAll">全选</el-checkbox>
      </template>
      <el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id" />
   </el-select>

js部分:

<script setup lang="ts">
import { ref, watch, onMounted } from 'vue';
import type { CheckboxValueType } from 'element-plus';

// 定义组件接收的属性
const props = defineProps({
   value: {
      type: Array,
      default: () => [],
   },
   options: {
    default() {
        return []
      },
      type: Array as () => Array<{ id: number, title: string }>,

   },
   placeholder: {
      type: String,
      default: '请选择',
   },
   maxCollapseTags: {
      type: Number,
      default: 3,
   },
   tooltipPlacement: {
      type: String,
      default: 'top',
   },
   props: {
      type: Object,
      default: () => ({
         label: 'title',
         value: 'id',
      }),
   },
});
onMounted(()=>{
   updateCheckAllStatus()
})

// 定义组件发出的事件
const emit = defineEmits(['update:value']);

// 定义组件内部状态
const selected = ref<any>(props.value);
const isAllChecked = ref(false);
const isIndeterminate = ref(false);

// 监听 value 的变化
watch(
   () => props.value,
   (newVal) => {
      selected.value = newVal;
      console.log(selected.value);
      
      updateCheckAllStatus();
   },
);

// 处理全选逻辑
const handleCheckAll = (val: CheckboxValueType) => {
   if (isAllChecked.value) {
      selected.value = props.options.map((option: any) => option.id);
   } else {
      selected.value = [];
   }
   emit('update:value', selected.value);
};

// 更新全选状态
const updateCheckAllStatus = () => {
   if (selected.value.length === props.options.length) {
      isAllChecked.value = true;
      isIndeterminate.value = false;
   } else if (selected.value.length > 0) {
      isAllChecked.value = false;
      isIndeterminate.value = true;
   } else {
      isAllChecked.value = false;
      isIndeterminate.value = false;
   }
};

// 监听 selected 的变化,同步给父组件
watch(selected, (newVal) => {
   emit('update:value', newVal);
   updateCheckAllStatus();
});

</script>

2.父组件:

<ElSelectV1 class="ml-1" :value="selectedValues" :options="options" :params="params" @update:value="handleValueUpdate" :placeholder="'请选择任务'"></ElSelectV1>

js部分:

<script setup lang="ts">
import ElSelectV1 from '@/components/Selector/index.vue';

const selectedValues = ref<any>();
const options = ref<any>([]);
let params = reactive<any>({});

// 处理子组件发出的更新事件
function handleValueUpdate(newValues: string[]) {
   selectedValues.value = newValues;
}

selectedValues:选择器已选中内容的id

options:选择器中所有的内容 (lable:展示名字,id:。。。)子组件中可修改

placeholder:输入框中的提示语。 默认为‘请选择’

handleValueUpdate:子组件更新后的回调函数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值