ElementPlus el-cascader级联选择器 实现一级菜单单选,二级菜单多选

需求:

利用el-cascader级联实现一级菜单单选,二级菜单多选的功能,如下图所示:

在这里插入图片描述

思路:

使用了多选multiply属性,这个属性下,选中的数据结构为:一级为length1的数组,二级为length2的数组。利用标识符,把最后选中的一级菜单的值与标识符做对比,如不同,则让标识符的值 = 一级菜单的值,然后新建数组,利用filter过滤出标识符与一级菜单的值相同的元素,在每次选中节点且赋值前,清空v-model,再将过滤后的数组赋值到v-model。

选择器选项:

<div class="content">
      <el-cascader v-model="casValue" :props="props" :options="options" @change="change" />
</div>

数据结构:

const options = [
  {
    
    
    value: 1,
    label: 'Asia',
    children: [
      {
    
    
        value: 2,
        label: 'China',
      },
      {
    
    
        value: 6,
        label: 'Japan',
      },
      {
    
    
        value: 10,
        label: 'Korea',
      },
    ],
  },
  {
    
    
    value: 14,
    label: 'Europe',
    children: [
      {
    
    
        value: 15,
        label: 'France',
      },
      {
    
    
        value: 19,
        label: 'UK',
      },
    ],
  },
];

功能逻辑:

const tag = ref(-1); // 标识符(重要)
const change = (item: any) => {
    
     // 逻辑代码
  item.forEach((i: any) => {
    
    
    if (i[0] != tag.value) {
    
    
      tag.value = i[0];
    }
  }); // 如切换勾选,则让标识符的值等于勾选的父级的value
  let filterd = item.filter((v: any) => v[0] == tag.value); // 过滤出与标识符相符的选项
  casValue.value = [];
  casValue.value.push(...filterd);
}

全部代码(demo):

<template>
  <div class="login">
    <div class="content">
      <el-cascader v-model="casValue" :props="props" :options="options" @change="change" />
    </div>
  </div>
</template>
<script lang="ts" setup>
import {
    
     reactive, ref } from 'vue';

const options = [
  {
    
    
    value: 1,
    label: 'Asia',
    children: [
      {
    
    
        value: 2,
        label: 'China',
      },
      {
    
    
        value: 6,
        label: 'Japan',
      },
      {
    
    
        value: 10,
        label: 'Korea',
      },
    ],
  },
  {
    
    
    value: 14,
    label: 'Europe',
    children: [
      {
    
    
        value: 15,
        label: 'France',
      },
      {
    
    
        value: 19,
        label: 'UK',
      },
    ],
  },
];
const casValue: any = ref([]);
const tag = ref(-1); // 标识符(重要)
const props = reactive({
    
    
  multiple: true,
});

const change = (item: any) => {
    
    
  item.forEach((i: any) => {
    
    
    if (i[0] != tag.value) {
    
    
      tag.value = i[0];
    }
  }); // 如切换勾选,则让标识符的值等于勾选的父级的value
  let filterd = item.filter((v: any) => v[0] == tag.value); // 过滤出与标识符相符的选项
  casValue.value = [];
  casValue.value.push(...filterd);
}

</script>

<style lang="scss" scoped>
.login {
    
    
  position: absolute;
  width: 100vw;
  height: 100vh;
  padding: 0 7.5% 0px 7.5%;
  box-sizing: border-box;
  background: white;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-image: url('../../assets/img/nbg2.jpeg');
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;

  .content {
    
    
    width: 356px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);

    .body {
    
    
      width: 100%;
      padding: 20px;
      border: 1px solid;
      border-radius: 20px;
      background: white;
    }
  }

  input::-webkit-outer-spin-button,
  input::-webkit-inner-spin-button {
    
    
    -webkit-appearance: none;
  }

  input[type='number'] {
    
    
    -moz-appearance: textfield;
    appearance: textfield;
  }

  .title {
    
    
    font-size: 24px;
    // margin-top: 80px;
    margin-bottom: 40px;
    font-weight: 600;
  }

  .tel {
    
    
    font-size: 16px;
    font-weight: 500;
    color: #b8bfcc;
    display: block;
    margin-bottom: 8px;
  }

  .container {
    
    
    display: flex;
    flex-direction: column;

    .tel {
    
    
      font-size: 16px;
      font-weight: 500;
      color: rgba(184, 191, 204, 1);
    }

    span {
    
    
      font-size: 20px;
    }

    .el-input {
    
    
      // width: 4px;
      height: 60px;
      margin-bottom: 20px;

      ::v-deep .el-input__inner {
    
    
        font-size: 18px !important;
        background: white;
      }
    }
  }

  .loginBtn {
    
    
    margin: 0;
    width: 100%;
    height: 60px;
    background: linear-gradient(129deg,
        rgba(0, 170, 255, 1) 0%,
        rgba(0, 127, 255, 1) 100%);
    border-radius: 3px;
    font-weight: 500;
    color: rgba(255, 255, 255, 1);
    outline: none;
    border: none;
    box-shadow: 0px 8px 20px 0px rgba(0, 170, 255, 0.1);
  }

  .btnContainer {
    
    
    position: relative;

    p {
    
    
      width: 196px;
      height: 35px;
      background: linear-gradient(129deg, #00aaff 0%, #007fff 100%);
      border-radius: 3px;
      opacity: 0.49;
      -webkit-filter: blur(6px);
      filter: blur(6px);
      position: absolute;
      top: 28px;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  }

  .el-button {
    
    
    display: flex;
    position: relative;
    font-size: 16px;
    line-height: 60px;
    padding: 0;

    ::v-depp span {
    
    
      text-align: center;
      margin: 0 auto;
    }
  }
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_42365757/article/details/127671228