<template>
  <el-cascader
    :options="options"
    :props="props"
    :show-all-levels="false"
    v-model="selectedValues"
    @change="handleSelectionChange"
    :key="selectedValues.toString()"
    ref="cascader"
  ></el-cascader>
</template>

<script>
export default {
  data() {
    return {
      selectedValues: [],
      options: [
        {
          value: 1,
          label: "Parent 1",
          children: [
            {
              value: 11,
              label: "Child 1-1",
              children: [
                {
                  value: 111,
                  label: "Child 1-11",
                },
                {
                  value: 121,
                  label: "Child 1-21",
                },
              ],
            },
            {
              value: 12,
              label: "Child 1-2",
            },
          ],
        },
        {
          value: 2,
          label: "Parent 2",
          children: [
            {
              value: 21,
              label: "Child 2-1",
            },
            {
              value: 22,
              label: "Child 2-2",
            },
          ],
        },
      ],
      props: {
        value: "value",
        label: "label",
        children: "children",
        multiple: true,
        emitPath: false,
        checkStrictly: true,
      },
    };
  },
  methods: {
    handleSelectionChange(selectedValues) {
      // 判断选中的值中是否包含父级选项
      const parentSelected = selectedValues.some((value) => {
        return this.options.some(
          (option) => option.value === value && option.children
        );
      });

      // 判断选中的值中是否包含子级选项
      const childSelected = selectedValues.some((value) => {
        return this.options.some(
          (option) =>
            option.children &&
            option.children.some((child) => child.value === value)
        );
      });

      if (parentSelected) {
        // 将父级选项的所有子级选项添加到选中的值中
        this.options.forEach((option) => {
          if (option.children && selectedValues.includes(option.value)) {
            option.children.forEach((child) => {
              if (!this.selectedValues.includes(child.value)) {
                this.selectedValues.push(child.value);
              }
            });
          }
        });
      } else if (childSelected) {
        // 将对应父级选项的值添加到选中的值中
        this.options.forEach((option) => {
          if (option.children) {
            option.children.forEach((child) => {
              if (
                selectedValues.includes(child.value) &&
                !this.selectedValues.includes(option.value)
              ) {
                const siblings = option.children.map((child) => child.value);
                if (
                  siblings.every((value) => this.selectedValues.includes(value))
                ) {
                  this.selectedValues.push(option.value);
                }
              }
            });
          }
        });
      }

      // 判断取消勾选的值中是否包含父级选项
      const parentDeselected = this.options.some((option) => {
        return (
          this.selectedValues.includes(option.value) &&
          option.children &&
          !selectedValues.includes(option.value)
        );
      });

      // 判断取消勾选的值中是否包含子级选项
      const childDeselected = selectedValues.some((value) => {
        return this.options.some(
          (option) =>
            option.children &&
            option.children.some((child) => child.value === value)
        );
      });

      if (parentDeselected) {
        // 将对应父级选项的所有子级选项从选中的值中删除
        this.options.forEach((option) => {
          if (option.children && this.selectedValues.includes(option.value)) {
            option.children.forEach((child) => {
              const index = this.selectedValues.indexOf(child.value);
              if (index !== -1) {
                this.selectedValues.splice(index, 1);
              }
            });
          }
        });
      } else if (childDeselected) {
        // 删除对应父级选项的值
        this.options.forEach((option) => {
          if (
            option.children &&
            option.children.some((child) =>
              selectedValues.includes(child.value)
            ) &&
            this.selectedValues.includes(option.value)
          ) {
            const siblings = option.children.map((child) => child.value);
            if (siblings.every((value) => !selectedValues.includes(value))) {
              const index = this.selectedValues.indexOf(option.value);
              if (index !== -1) {
                this.selectedValues.splice(index, 1);
              }
            }
          }
        });
      }
    },
  },
};
</script> 优化一下这个应用代码