element-ui —Cascader 级联选择器(选中方式处理)

2023-11-16

目前Vue Element的 el-cascader 级联选择器,多选或者选择任意一级,需要点击左侧的checkbox才能选中。

目标:点击label选中,已选中状态再次点击label取消选中

有两种方式实现

  • 通过添加点击事件
  • 通过css样式控制

方法一:通过点击事件

<!-- 改造前 -->

<template>
  <div>
    <el-cascader
        v-model="cascaderValue"
        :options="options"
        :props="{ multiple: true,checkStrictly:true }"
        clearable>
    </el-cascader>
    {{cascaderValue}}
  </div>
</template>

改造点

  • 可以通过 scoped slot 对级联选择器的备选项的节点内容进行自定义
  • 添加点击事件 @click="onClick(node)" 将选中的数据进行处理
  • 区分单选/多选 单选:
  1. 将选中的数据赋值到v-model

多选

  1. 将之前选择的数据保存
  2. 处理:未选勾选选中/已选取消选中
  3. 将选中的数据赋值到v-model
<!-- 改造后 -->

<template>
  <div>
    <el-cascader
        v-model="cascaderValue"
        :options="options"
        :props="{ multiple: true,checkStrictly:true }"
        clearable>
          <!-- 重点:第一步,增加slot-scope -->
          <template slot-scope="{ node, data }">
            <span style="display:block" @click="onClick(node)">{{ data.label }}</span>
          </template>
    </el-cascader>
    {{cascaderValue}}
  </div>
</template>

<script>

export default {
  name: 'Test',
  data () {
    return {
      cascaderValue: [],
      options: [
        {
          value: 1,
          label: '东南',
          disabled: true,
          children: [
            {
              value: 2,
              label: '上海',
              disabled: true,
              children: [
                { value: 3, label: '普陀' },
                { value: 4, label: '黄埔' },
                { value: 5, label: '徐汇' }
              ]
            }
          ]
        },
        {
          value: 6,
          label: '西北',
          disabled: true,
          children: [
            { value: 7, label: '陕西' },
            { value: 8, label: '新疆' }
          ]
        },
        {
          value: 9,
          label: '东北'
        }
      ]
    }
  },
  methods: {
    // 单选的情况
    // onClick (node) {
    //   if (!node.isDisabled) {
    //     this.cascaderValue = node.path
    //   }
    // },
    // 多选的情况
    onClick (node) {
      if (node.isDisabled) {
        return
      }

      // 定义一个数组,用于处理数据
      const data = []

      // 将之前选择的数据保存
      if (this.cascaderValue.length) {
        this.cascaderValue.forEach(n => {
          data.push(n)
          console.log('之前的值', data)
        })
      }

      // 处理:
      // 未选状态:将当前点击的node.path(是一个数组[1,2,3]),添加到data中
      // 已选状态:已选中的从data数组中查找node.path删除
      if (!node.checked) {
        data.push(node.path)
        console.log('未选->选中', data)
      } else {
        if (data.length) {
          // 将[ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 2, 5 ] ]数据转为["1,2,3", "1,2,4", "1,2,5"],因为数组不能比较
          const map = data.map(n => n.join(','))
          // 找出node.path删除
          const idx = map.findIndex(q => q === node.path.join(','))
          if (idx > -1) {
            data.splice(idx, 1)
          }
          console.log('已选->取消选中', data)
        }
      }

      // 最后双向绑定v-model的数据
      this.cascaderValue = data
    }
  }
}
</script>

多选存在问题:当使用el-cascader属性 clearable 的时候,会出现删除错误的问题,因为级联选择器绑定的数据是按照指定的格式添加。

因此需要在 “数据赋值到v-model” 以前对数据进行处理

  1. 将之前选择的数据保存
  2. 处理:未选勾选选中/已选取消选中
  3. 将options树形数据转为数组数据
  4. 将满足条件的数据过滤出来
  5. 将选中的数据赋值到v-model
<template>
  <div>
    <!-- 多选 -->
    <el-cascader
        v-model="cascaderValue"
        :options="options"
        :props="{ multiple: true,checkStrictly:true }"
        clearable>
          <!-- 重点:增加slot-scope -->
          <template slot-scope="{ node, data }">
            <span style="display:block" @click="onClick(node)">{{ data.label }}</span>
          </template>
    </el-cascader>
    {{cascaderValue}}
  </div>
</template>

<script>

export default {
  name: 'Test',
  data () {
    return {
      cascaderValue: [],
      options: [
        {
          value: 1,
          label: '东南',
          disabled: true,
          children: [
            {
              value: 2,
              label: '上海',
              disabled: true,
              children: [
                { value: 3, label: '普陀' },
                { value: 4, label: '黄埔' },
                { value: 5, label: '徐汇' }
              ]
            }
          ]
        },
        {
          value: 6,
          label: '西北',
          disabled: true,
          children: [
            { value: 7, label: '陕西' },
            { value: 8, label: '新疆' }
          ]
        },
        {
          value: 9,
          label: '东北'
        }
      ]
    }
  },
  computed: {
    // 1.第一步,将树形数据转数组数据
    // ["1,2,3", "1,2,4", "1,2,5", "6,7", "6,8", "9"]
    gradeLabelToList () {
      return this.treeToList(this.options)
    }
  },
  methods: {
    // 单选的情况
    // onClick (node) {
    //   if (!node.isDisabled) {
    //     this.cascaderValue = node.path
    //   }
    // },
    // 多选的情况
    onClick (node) {
      if (node.isDisabled) {
        return
      }

      // 定义一个数组,用于处理数据
      const data = []

      // 将之前选择的数据保存
      if (this.cascaderValue.length) {
        this.cascaderValue.forEach(n => {
          data.push(n)
          console.log('之前的值', data)
        })
      }

      // 处理:
      // 未选状态:将当前点击的node.path(是一个数组[1,2,3]),添加到data中
      // 已选状态:已选中的从data数组中查找node.path删除
      if (!node.checked) {
        data.push(node.path)
        console.log('未选->选中', data)
      } else {
        if (data.length) {
          // 将[ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 2, 5 ] ]数据转为["1,2,3", "1,2,4", "1,2,5"],因为数组不能比较
          const map = data.map(n => n.join(','))
          // 找出node.path删除
          const idx = map.findIndex(q => q === node.path.join(','))
          if (idx > -1) {
            data.splice(idx, 1)
          }
          console.log('已选->取消选中', data)
        }
      }

      // 如果不添加以下代码,当使用组件的属性 clearable 的时候,会出现删除错误的问题,因为数据是有顺序的
      const joinData = data.map(n => n.join(','))
      // 将满足条件的数据过滤出来
      const tempData = this.gradeLabelToList.filter(n => joinData.find(m => m === n))
      let retData = []
      // 再将数据数据构造回[ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 2, 5 ] ]
      retData = tempData.map(n => n.split(',').map(Number))

      // 最后双向绑定v-model的数据
      this.cascaderValue = retData
    },
    treeToList (tree, out, pid) {
      if (out === undefined) {
        out = []
      }
      tree.forEach(n => {
        const path = pid ? `${pid},` : ''
        const data = `${path}${n.value}`
        if (n.children) {
          this.treeToList(n.children, out, data)
        } else {
          out.push(data)
        }
      })
      return out
    }
  }
}
</script>

方法二:通过CSS样式

还有另一种方法,仅根据css样式,扩大radio或者checkbox的区域达到选中效果

存在问题:无法展开下一级

// css样式
<style lang="less">
  .el-cascader-panel .el-radio,
  .el-checkbox {
    width: 100%;
    height: 100%;
    z-index: 10;
    position: absolute;
    top: 10px;
    right: 10px;
  }

  .el-cascader-panel .el-radio__input,
  .el-checkbox__input {
    visibility: hidden;
  }
</style>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

element-ui —Cascader 级联选择器(选中方式处理) 的相关文章

随机推荐

  • Nokogiri的使用 抓取csdn博客內容 rails

    Nokogiri 锯 使使用 Ruby 中的 XML 和 HTML 变得轻松而轻松 提供了一个明智的 易于理解的 API 阅读 编写 修改 和 查询 文档 它依赖于 libxml2 CRuby 和 xerces JRuby 等原生解析器 速
  • 光流法( Optical Flow Method)

    在计算机视觉中 光流法即可用于运动目标检测 也可以用于目标跟踪 本文主要介绍光流法在运动目标检测和目标跟踪中的区别与联系 1 光流与光流场 光流的概念最初是由 Gibson 于 1950 年首先提出来的 当人的眼睛观察运动物体时 物体的景象
  • 没有计算机网络地址怎么办,教大家电脑没有ip地址mac地址怎么办

    近日有关于电脑没有ip地址mac地址怎么办的问题受到了很多网友们的关注 大多数网友都想要知道电脑没有ip地址mac地址怎么办的具体情况 那么关于到电脑没有ip地址mac地址怎么办的相关信息 小编也是在网上进行了一系列的信息 那么接下来就由小
  • C#Replace

    在C 的字符串操作过程中 有时候需要替换字符串中的某个子字符串 此时就可以使用到字符串类自带的Replace方法来实现 Replace方法将查找到所有符合被替换的子字符串 然后将之全部替换为目标字符串 Replace方法有2个方法重载实现
  • 奇偶排序,双调排序,双调查找

    奇偶排序 奇偶排序是排序方法的一种 复杂度为O n 2 好处是可以利用处理器的并行 第一遍扫描a i a i 1 i为奇数 如果这两个次序不正确 就交换它们的次序 第二遍扫描偶数 双调排序 所谓双调序列 Bitonic Sequence 是
  • matlab 获取矩阵大小、行数、列数、元素总个数——size()/length()/numel()

    1 size size 获取数组的行数和列数 s size A 当只有一个输出参数时 返回一个行向量 该行向量的第一个元素时数组的行数 第二个元素是数组的列数 r c size A 当有两个输出参数时 size函数将数组的行数返回到第一个输
  • docker容器内开启22 ssh_Docker 添加容器SSH服务

    很多时候我们需要登陆到容器内部操作 此时我们就需要开启容器的SSH支持了 下面的小例子将具体介绍三种分配IP地址的方法 分别是pipworl分配 commit分配 Docker分配等 该系列文章只是本人的学习笔记 文章中的文字描述是 Lin
  • java_MD5加密源码

    package com lt util import java io UnsupportedEncodingException import java security MessageDigest import java security
  • 使用Kinect2作为Oculus游戏应用的输入设备

    注 文章写于2015年8月 眼下VR游戏Demo已经完结 所以把上一次预研的一些经验分享出来 希望对大家有所帮助 背景 初接触Oculus时 从网上下载了一大堆的Demo来体验 可是 操作体验大都比較差 特别是FPS类 这也让我们意识到 对
  • BMP转JPG(法二)RGB数据经过YUV交织

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家拍砖 源码下载地址 http download csdn net detail chenyujing1234 4441643 编译平台 VS20
  • ORACLE not available如何解决

    出现Oracle不可用可以一般情况下有两种办法解决 1 先关闭数据库 在打开数据库 SQL gt shutdown immediate SQL gt startup open 先用这种方式看看问题解决了没有 如果没有再用第二种办法试试 2
  • svn服务器 系统重装恢复吗,请教一下好不好把svn版本库还原到以前的版本?

    1 Linux系统安装svn服务 yuminstall subversion2 新建一个目录用于存储SVN所有文件 mkdir p cbroot svnserver cbweb3 在上面创建的文件夹中为项目project 1 创建一个版本仓
  • 操作系统 虚拟存储器的概念

    虚拟存储器 程序装入内存时可能会出现如下问题 程序太大 要求的空间超出了内存总容量 有大量作业要求运行 但内存不能容下所有作业 常规存储器管理方式的特征 一次性 要求作业全部装入内存才能运行 驻留性 许多不用或暂时不用的程序占用了大量内存空
  • linux命令strings

    linux命令strings 其man信息如下 strings 1 GNU Development Tools strings 1 NAME strings 显示文件中的可打印字符 总览 SYNOPSIS strings a all f p
  • 二维线段树【模板——给出对应注释】

    闲话少说 直接看注释反而会更容易读懂这段二维线段树的模板 include
  • elasticsearch启动报错:master not discovered yet

    通过命令启动 bin elasticsearch E node name hotnode E cluster name geektime E path data hot data E node attr my node type hot 报
  • 违反 GPL 协议赔偿 50 万,国内首例!

    整理 祝涛 出品 CSDN ID CSDNnews 近日 一起关于GPL版权纠纷案裁判文书公示 在一审中 法院指出GPL 3 0协议是一种民事法律行为 具有合同性质 可认定为授权人与用户间订立的著作权协议 属于我国 合同法 调整的范围 来源
  • C++ Primer阅读笔记--数组的使用

    1 理解复杂的数组声明 阅读复杂数组声明时 建议由内向外阅读 int ptrs 10 ptrs是一个含有10个整型指针的数组 int refs 10 错误 不存在引用的数组 int Parray 10 arr Parray指向一个含有10个
  • Qt之TCP心跳包

    Qt之TCP心跳包 当Qt作为客户端程序 而服务器需要监控客户端的在线状态时 就需要Qt端发送心跳包 心跳包可以是TCP也可以是UDP 这里介绍TCP心跳包的实现方法 心跳包通常要单开一个线程 在进程运行的过程中一直执行 代码示例 h文件
  • element-ui —Cascader 级联选择器(选中方式处理)

    目前Vue Element的 el cascader 级联选择器 多选或者选择任意一级 需要点击左侧的checkbox才能选中 目标 点击label选中 已选中状态再次点击label取消选中 有两种方式实现 通过添加点击事件 通过css样式