Vue3实现下拉选择框多选功能的方法详解
作者:SeaCassie
在vue的实际开发过程中,我们如何将以选中的值直接渲染到页面中,下面这篇文章主要给大家介绍了关于Vue3实现下拉选择框多选功能的相关资料,需要的朋友可以参考下
起因:
项目采用vue3+elmentui-plus +ts 搭建成的。用户界面设计上需要一个带全选的下拉选择框。而element plus 官网 提供的下拉多选框是
这种形式是没有全选按钮的,并且样式也不符合想像中的全选的操作。故开始想法子去结合一个新的条件去封装一个新的组件。
效果展示:
设计原理:
由于用户更加热衷于带有全选的下拉框,并且不喜欢右侧的√的选择标识,而需要换成和多选框一直的选中框,于是,根据已有的条件,我采用 el-select + el-checkbox的形式去编写这个组件。
组件代码构成 创建子组件selectCheckBox.vue文件
html 部分
<el-select v-model="menusTitle" multiple collapse-tags collapse-tags-tooltip :placeholder="props.placeholder" clearable @clear="clearData" > <!-- @change="changeSelectMenu" --> <el-checkbox v-model="checkedAll" @change="selectAll">全选</el-checkbox> <el-option v-for="(item, index) in menuList" :key="item[props.id]" :value="item[props.id]" > <el-checkbox :label="item[props.label]" size="large" @change="changeCheckBox(item, index)" :checked="isChecked(item, index)" v-model="checkBoxObj[index]" /> </el-option> </el-select>
js部分
<script lang="ts" setup> import { ref, reactive, defineProps, defineEmits } from "vue"; const props = defineProps({ list: { type: Array, required: true }, id: { type: String, required: true }, label: { type: String, required: true }, modelValue: { type: Array }, placeholder: { type: String, default: "选择" }, }); const emit = defineEmits(["update:modelValue"]); const value = ref(""); const checkedAll = ref("false"); const menus = ref([]); const menuList = props.list; const checkBoxObj = ref({}); menuList.forEach((res, index) => { checkBoxObj.value[index] = false; }); const menusTitle = ref([]); const changeSelectMenu = (val) => {}; const selectAll = (value) => { menus.value = []; menusTitle.value = []; if (value) { menuList.forEach((item, index) => { menus.value.push(item[props.id]); menusTitle.value.push(item[props.label]); checkBoxObj.value[index] = true; }); } else { menus.value = []; menusTitle.value = []; menuList.forEach((item, index) => { checkBoxObj.value[index] = false; }); } emit("update:modelValue", menus.value); }; const isChecked = (item) => { return menus.value.indexOf(item[props.id]) > -1; }; const changeCheckBox = (item, index) => { let i = menus.value.indexOf(item[props.id]); if (i == -1) { menus.value.push(item[props.id]); menusTitle.value.push(item[props.label]); } else { menus.value.splice(i, 1); menusTitle.value.splice(i, 1); } if (menus.value.length == menuList.length) { checkedAll.value = true; } else { checkedAll.value = false; } emit("update:modelValue", menus.value); }; const clearData = () => { menus.value = []; menusTitle.value = []; emit("update:modelValue", menus.value); checkedAll.value = false; menuList.forEach((item, index) => { checkBoxObj.value[index] = false; }); }; </script>
css部分:
<style lang="scss" scoped> .el-select-dropdown { .el-checkbox { display: flex; align-items: center; padding-left: 20px; width: 100%; box-sizing: border-box; } .el-select-dropdown__item { // background-color: red !important; padding: 0; display: flex; align-items: center; } } </style>
父组件调用
html 引入部分
<selectCheckBox v-model="value3 " :list="options" id="value" label="label" placeholder="选择项目" ></selectCheckBox>
js引入部分
import selectCheckBox from "@_components/dataClassification/selectCheckBox.vue"; const value3 = ref([]); const options = [ { value: "1", label: "项目一", }, { value: "2", label: "项目二", }, { value: "3", label: "项目三", }, ];
总结
该组件 还在升级过程中,二次封装组件处理。进一步的封装过程目标是,做一个类el-select的参数的组件。今日留做记录.