Build a Multiple Choices Cascader by ant-design-vue

2023-05-16

Preface

I need to make a cascader which can support multiple choices. However, I didn't find any ui which supports that until 2018.11.18. That was a little pity.

Main

I check the element-ui and find multiple cascader was in toDoList while ant-design refuse to support that directly. Maybe because they have already implemented TreeSelect. Here is what TreeSelect looks like:

Almost the result I want except the ui. It doesn't look like a cascader but a tree.

Anyway, I built a multiple cascader component based on select and cascader in ant-design-vue. Here is the result:

The principle is easy. I use the input in select and hide the popup. And then I hide the input in cascader and show the popup. So, MultipleCascader is equal to input in select plus popup in cascader and use transform to let them stay together.

Talking about the event, you have to listen and change the data to show correctly. That is a little troublesome.

Anyway, here is the earliest demo in codesandbox. I am not sure if the demo would be always able to visit.

The latest version is in here.

So, here is the earliest code:

App.vue

<template>
  <div id="app" class="app"><MultipleCascader /></div>
</template>

<script>
import MultipleCascader from './components/MultipleCascader'
export default {
  name: 'app',
  components: {
    MultipleCascader
  }
}
</script>

<style scoped></style>

MultipleCascader.vue

<template>
  <div class="multi_cascader">
    <a-cascader
      size="large"
      class="multi_cascader__cascader"
      :popupVisible="cascaderPopupVisible"
      :popupClassName="'multi_cascader__cascader_popup' + timestamp"
      changeOnSelect
      expandTrigger="hover"
      :options="cascaderOptions"
      :fieldNames="{ label: 'label', value: 'id', children: 'children' }"
      v-model="cascaderValues"
      ref="cascader"
      :showSearch="{ cascaderFilter }"
      @change="cascaderChange"
    ></a-cascader>
    <a-select
      size="large"
      class="multi_cascader__select"
      dropdownClassName="hide"
      mode="multiple"
      :value="selectValues"
      allowClear
      placeholder="Please select"
      :options="selectOptions"
      @focus="cascaderPopupVisible = true"
      @deselect="deleteOption"
      @change="selectChange"
      @search="selectSearch"
    ></a-select>
  </div>
</template>

<script>
export default {
  name: 'MultipleCascader',
  data: function() {
    return {
      timestamp: Date.now(),
      selectOptions: [],
      selectValues: [],
      cascaderPopupVisible: false,
      cascaderValues: [],
      cascaderOptions: [
        {
          id: 1,
          value: '1',
          label: '1',
          children: [
            { id: 1.1, value: 1.1, label: '1-1' },
            {
              id: 1.2,
              value: 1.2,
              label: '1-2',
              children: [
                { id: 1.21, value: 1.21, label: '1-2-1' },
                { id: 1.22, value: 1.22, label: '1-2-2' }
              ]
            }
          ]
        },
        { id: 2, value: 2, label: '2' }
      ]
    }
  },
  mounted() {
    document.addEventListener('click', this.hideCascaderPopup)
  },
  destroyed() {
    document.removeEventListener('click', this.hideCascaderPopup)
  },
  methods: {
    cascaderChange(values, options) {
      // you may have different logic with the selected option, here I just want the last one.
      let targetValue = values.slice(-1).pop()
      let targetOption = options.slice(-1).pop()
      let selectedValIndex = this.selectValues.indexOf(targetValue)
      if (selectedValIndex >= 0) {
        this.selectValues.splice(selectedValIndex, 1)
        this.selectOptions.splice(selectedValIndex, 1)
      } else {
        this.selectValues.push(targetValue)
        this.selectOptions.push(targetOption)
      }
    },
    deleteOption(value) {
      let selectedValIndex = this.selectValues.indexOf(value)
      this.cascaderChange([value], [this.selectOptions[selectedValIndex]])
    },
    selectChange(values, vNodes) {
      if (values.length === 0) {
        this.selectValues = []
        this.selectOptions = []
      }
    },
    selectSearch(keyword) {
      let searchInput = this.$refs.cascader.$el.querySelector('input')
      if (searchInput) {
        searchInput.value = keyword
        searchInput.dispatchEvent(new Event('input'))
      }
    },
    cascaderFilter(inputValue, path) {
      return path.some(
        option =>
          option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1
      )
    },
    hideCascaderPopup(event) {
      let cascaderPopup = document.querySelector(
        '.multi_cascader__cascader_popup' + this.timestamp
      )
      let isClickCascaderPopup =
        cascaderPopup && cascaderPopup.contains(event.target)
      if (isClickCascaderPopup) {
        return
      }
      this.cascaderPopupVisible = false
    }
  }
}
</script>

<style scoped>
.multi_cascader {
  height: 100vh;
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
}
.multi_cascader__select {
  width: 50%;
  margin-top: 0;
  margin-bottom: auto;
  transform: translate(0, -100%);
}
.multi_cascader__cascader {
  width: 50%;
  margin-top: auto;
  margin-bottom: 0;
  opacity: 0;
}
</style>

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

Build a Multiple Choices Cascader by ant-design-vue 的相关文章

随机推荐

  • Ubuntu18.04LTS 文件系统简记

    Ubuntu18 04LTS 文件系统 了解Linux文件系统是熟悉掌握使用Linux系统的第一步 首先安装名为tree的工具 sudo apt install tree 运行 tree help 查看tree命令的详细用法 运行 tree
  • windows下nvm安装node之后npm命令找不到问题解决办法

    主要关键解解决办法 xff1a 61 61 61 适 用于所有东西的安装 安装有关环境配置类的软件及其他 xff0c 一般情况下切记不要安装到c盘programfiles下 xff0c 否则会出现各种问题的报错 xff01 xff01 xf
  • [问题2014S14] 复旦高等代数II(13级)每周一题(第十四教学周)

    问题2014S14 设 V 为酉空间 证明 不存在 V 上的非零线性变换 varphi 使得对 V 中任一向量 v 均有 varphi v v 61 0 注 本题是复旦高代教材 P326 习题 9 1 5 的推广
  • 8B10B编解码及FPGA实现

    概述 在使用ALTERA的高速串行接口时 xff0c GXB模块里硬件实现了8B10B编码 xff0c 用户只是 傻瓜 式的使用 xff0c 笔者也一直没有弄清楚 网上搜索了一些学习资料 xff0c 结合参考文献希望能够对其进行消化 另外
  • 零碎记录- spring security oauth2 资源服务器中设置放行路径

    在资源服务器配置类中重写configure方法 xff0c 添加放行信息 使用了 64 EnableResouceServer xff0c 且继承了ResourceServerConfigurerAdapter的类作为资源服务器配置信息类
  • Golang 新手可能会踩的 50 个坑

    译文 xff1a Golang 新手可能会踩的 50 个坑 原文 xff1a 50 Shades of Go Traps Gotchas and Common Mistakes 翻译已获作者授权 xff0c 转载请注明来源 不久前发现在知乎
  • 手把手教你使用TF服务将TensorFlow模型部署到生产环境 ...

    介 绍 将机器学习 xff08 ML xff09 模型应用于生产环境已成为一个火热的的话题 许多框架提供了旨在解决此问题的不同解决方案 为解决这一问题 xff0c 谷歌发布了TensorFlow xff08 TF xff09 服务 xff0
  • Centos/Linux下如何查看网关地址/Gateway地址

    Centos Linux下如何查看网关地址 Gateway地址 xff1f Linux下查看网关的命令还是很多的 xff0c 不过如果IP是DHCP获取 xff0c 那么有些命令是不适用的 xff0c 当然也有通用的查询网关命令 1 ifc
  • 教你Java生成文件时怎么设置编码格式

    OutputStreamWriter允许用户指定编码方式 xff0c 代码为 xff1a FileInputStream fis 61 new FileInputStream 34 文件路径 34 xff1b OutputStreamWri
  • One input and More output use 'tee'

    2008 05 22 In preparation for my Luma media player I wanted to create a simple audio player with visualization Based upo
  • 简单的任务调度(自整理)

    为什么80 的码农都做不了架构师 xff1f gt gt gt 任务调度 使用 Quartz 框架实现 1 8 6 的版本 开源框架 什么是任务调度 xff1a 即是某个时间点做某件时间 xff01 核心有是什么 xff1a 以时间为关注点
  • Laravel5.5集成七牛云上传、管理(删除、查询)

    一 为什么使用七牛云存储 1 使用七牛带宽和CDN xff0c 速度快 xff0c 不占用开发者服务器 2 支持图片任意格式 任意分辨率自动生成 xff0c 可以用来做图片服务器 3 小流量免费 xff1a 存储空间 10GB xff0c
  • centos为用户添加sudo功能

    su chmod a 43 w etc sudoers vim etc sudoers 找到root ALL 61 ALL ALL这行 复制出新的一行 xff0c 并且将root改为daniel xff08 当前用户名 xff09 chmo
  • Reverse Linked List

    本题是反转一个单链表 xff0c 题目提示使用迭代和递归两种方式 xff0c 属于比较基础的题目 一 迭代方式 xff1a 总体思路是从左到右遍历链表结点 xff0c 依次反转连接关系 每次处理相邻的两个结点 xff0c 从 lt None
  • angularJS1笔记-(17)-ng-bind-html指令

    angular不推荐大家在绑定数据的时候绑定html 但是如果你非要这么干也并不是不可以的 举个例子 xff1a lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt me
  • 旧电脑diy文件服务器,2021旧电脑自制NAS存储变废为宝.docx

    amp tid 61 13992 amp page 61 1 amp extra 61 pid15059 amp tid 61 13992 amp page 61 1 amp extra 61 pid15059 旧电脑自制NAS存储变废为宝
  • Druid 连接池 JDBCUtils 工具类的使用

    Druid工具介绍 它不仅仅是一个数据库连接池 xff0c 它还包含一个ProxyDriver xff0c 一系列内置的JDBC组件库 xff0c 一个SQL Parser 支持所有JDBC兼容的数据库 xff0c 包括Oracle MyS
  • matlab练习程序(简单图像融合)

    通过本篇和上一篇的结合 xff0c 应该就能做出拉普拉斯图像融合了 这里用的方法很简单 xff0c 就是用模板和两个图像相乘 xff0c 然后对处理后的两个图像再相加就可以了 拉普拉斯融合就是对金字塔的每一层图像做这样的操作 xff0c 然
  • Ext.grid.Panel表格分页

    Ext grid Panel表格分页示例 代码 xff1a cshtml 64 Layout 61 null lt DOCTYPE html gt lt html gt lt head gt lt title gt Ext grid Pan
  • Build a Multiple Choices Cascader by ant-design-vue

    Preface I need to make a cascader which can support multiple choices However I didn 39 t find any ui which supports that