Vue3 Element-plus 封装Select下拉复选框选择器

废话不多说,样式如下,代码如下,需要自取

cpp 复制代码
<template>
  <el-select
    v-model="selectValue"
    class="checkbox-select"
    multiple
    :placeholder="placeholder"
    :style="{ width: width }"
    @change="changeSelect"
  >
    <div class="checkboxWrapper">
      <el-checkbox v-model="checked"> 全选 </el-checkbox>
    </div>
    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
      <el-checkbox :model-value="selectValue.includes(item.value)">
        {{ item.label }}
      </el-checkbox>
    </el-option>
  </el-select>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useVModel } from '@vueuse/core'

interface Option {
  label: string
  value: number
}

interface Props {
  modelValue: number[]
  options: Option[]
  placeholder?: string
  width?: string
}

interface Emits {
  (e: 'update:modelValue', value: number[]): void
  (e: 'change', value: number[]): void
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: '请选择',
  width: '200px',
})

const emit = defineEmits<Emits>()

defineOptions({
  name: 'CheckboxSelect',
})

// 使用useVModel处理数据同步
const selectValue = useVModel(props, 'modelValue', emit)

// 计算全选状态
const checked = computed({
  get: () => {
    const resValues = props.options.map((item) => item.value)
    return selectValue.value.length === resValues.length
  },
  set: (value: boolean) => {
    const resValues = props.options.map((item) => item.value)
    if (!value) {
      // 如果checkbox为false,则为反选,选择数组为空
      emit('update:modelValue', [])
    } else {
      // 如果checkbox为true,则为全选,选择数组添加所有数据
      emit('update:modelValue', [...resValues])
    }
  },
})

// 选择变化处理
const changeSelect = (val: number[]) => {
  emit('change', val)
}
</script>

<style scoped>
.checkbox-select {
  width: 100%;
}

.checkboxWrapper {
  padding: 0px 20px;
}

/* 选项复选框样式 */
:deep(.el-select-dropdown__item .el-checkbox) {
  width: 100%;
  margin: 0;
}

:deep(.el-select-dropdown__item .el-checkbox .el-checkbox__label) {
  padding-left: 8px;
}
</style>
cpp 复制代码
 <CheckboxSelect
	v-model="searchForm.statusList"
	:options="statusOptions"
	placeholder="请选择状态"
	width="200px"
	@change="changeHandle"
/>

// 搜索表单
const searchForm = reactive({
  statusList: [] as number[], // 多选数组
})

// 状态选项
const statusOptions = ref([
  { label: '启用', value: 1 },
  { label: '禁用', value: 2 },
])

// 选择变化处理
const changeHandle = (val: number[]) => {
  console.log(val, '状态选择变化')
}
相关推荐
幸运小圣43 分钟前
SSE 与 WebSocket 新手入门:前端实时通信完全指南【JavaScript】
前端·javascript·websocket
艾伦野鸽ggg44 分钟前
25级开学 JS 考核题解
前端·javascript
meilindehuzi_a1 小时前
LangChain.js + Milvus 向量长期记忆实战:对话写入、语义检索与 RAG 增强
javascript·langchain·milvus
leoZ2311 小时前
2026-09-08-mysql-57-init-walkthrough
前端·javascript·数据库·vue.js·opencv·mysql·adb
艾伦野鸽ggg1 小时前
JavaScript 原型链与原型对象详解
javascript·原型模式
qq_350897211 小时前
trea实用工具
vue.js·uniapp
paopaokaka_luck1 小时前
非遗文物数字化系统(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
前端·javascript·vue.js·人工智能·数据分析·echarts
mONESY2 小时前
让大模型「听话」输出 JSON:LangChain OutputParser 结构化输出实战,从手写正则到 Zod Schema 四层进化
javascript
研☆香2 小时前
js中使用的正则表达式
开发语言·javascript·正则表达式
BS30813_vx2 小时前
31754+基于 Spring Boot + Vue 的网络文学交流分享平台设计与实现
vue.js·spring boot·后端