Vue3 realizes the function of multiple selection in the drop-down selection box

origin:

The project is built with vue3+elmentui-plus +ts. The user interface design requires a drop-down selection box with select all. However, the drop-down multi-select box provided by the official website of element plus insert image description here
has no button for selecting all in this form, and the style does not conform to the expected operation of selecting all. So I started to think of ways to combine a new condition to encapsulate a new component.

Show results:

insert image description here
insert image description here
insert image description here
insert image description here

Design principle:

Since users are more keen on the drop-down box with full selection, and don’t like the √ selection mark on the right, they need to replace it with the same selection box as the multi-selection box, so, according to the existing conditions, I use el-select + el-checkbox form to write this component.

Component code composition creates a subcomponent selectCheckBox.vue file

html part

<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 part

<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 part:

<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>

parent component call

html import part

 <selectCheckBox
          v-model="value3 "
          :list="options"
          id="value"
          label="label"
          placeholder="选择项目"
        ></selectCheckBox>

js import part

import selectCheckBox from "@_components/dataClassification/selectCheckBox.vue";
const value3 = ref([]);
const options = [

  {
    value: "1",
    label: "项目一",
  },
  {
    value: "2",
    label: "项目二",
  },
  {
    value: "3",
    label: "项目三",
  },
];

Summarize

The component is still in the process of upgrading, and the secondary packaging component is processed. The goal of the further encapsulation process is to make a parameter component of the class el-select. Keep it for the record today.

Guess you like

Origin blog.csdn.net/weixin_44358678/article/details/127358044