antd中在vue项目中自定义穿梭框

news2024/9/29 23:30:46

antd中在vue项目中自定义穿梭框

1、完成代码

<template>
  <a-modal
    title="高危因素选择"
    :width="1000"
    :visible="riskVisible"
    :confirm-loading="confirmLoading"
    @ok="handleOk"
    @cancel="handleCancel"
    okText="确认"
  >
    <a-transfer
      class="tree-transfer"
      :data-source="dataSource"
      :target-keys="targetKeys"
      :render="item => item.title"
      :show-select-all="false"
      @change="onChange"
      :titles="['可选择高危因素', '已选中高危因素']"
    >
      <template
        slot="children"
        slot-scope="{ props: { direction, selectedKeys }, on: { itemSelect } }"
      >
        <div v-if="direction === 'left'">
          <div class="nav-list">
            <div  v-for="(item, index) in navList"
                  :key="index"
                  @click="handleNavChange(index)"
                  :class="['nav-item', currentNav === index ? 'current-color' : '']">
              {{item.title}}
            </div>
          </div>
          <div class="left-ipt">
            <a-input placeholder="搜索可选择内容">
              <a-icon slot="prefix" type="search"></a-icon>
            </a-input>
            <a-button type="primary" class="search-btn">
              搜索
            </a-button>
          </div>
          <a-tree
            v-if='treeData.length'
            :showLine="showLine"
            blockNode
            checkable
            checkStrictly
            :tree-data="renderTreeData"
            :defaultExpandedKeys="['1', '2']"
            :checkedKeys="[...selectedKeys, ...targetKeys]"
            @check="
            (_, props) => {
              onLeftChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect);
            }
          "
          >
          <template slot='custom' slot-scope='item'>
            <div v-if="item.flag === '1'"> {{ item.title+'('+item.level+')' }}</div>
            <div v-if="item.flag === '2'">
              <span :style="{width:'20px',height:'10px',background:item.color,padding:'5px 10px',marginRight:'5px'}">{{ item.levelText}}</span>{{ item.title}}
            </div>
          </template>
          </a-tree>
        </div>
        <div v-if="direction === 'right'">
          <div class="left-ipt">
            <a-input placeholder="搜索可选择内容">
              <a-icon slot="prefix" type="search"></a-icon>
            </a-input>
            <a-button type="primary" class="search-btn">
              搜索
            </a-button>
          </div>
          <div>
            <div v-for="item in rightData" :key="item.key">
              <a-checkbox @change="(e) => handleRightChange(e, [...selectedKeys], itemSelect, item.key)">
                <span :style="{width:'20px',height:'10px',background:item.color,padding:'5px 10px',marginRight:'5px'}">{{ item.levelText}}</span>{{ item.title}}
              </a-checkbox>
            </div>
          </div>
        </div>
      </template>
    </a-transfer>
  </a-modal>
</template>
<script>
import { getAction} from '@api/manage'
export default {
  props: {
    riskVisible: {
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      dataSource: [], 
      // selectedKeys: [],
      confirmLoading: false,
      targetKeys: [],
      treeData: [],
      navList:[
        {
          title: '颜色分类',
        },
        {
          title: '常用分类'
        },
        {
          title: '疾病分类'
        }
      ],
      currentNav: 0,
      showLine: true,
      rightData: [],
      rightSelectKeys: [],
    };
  },
  computed: {
    renderTreeData() {
      return this.handleTreeData(this.treeData, this.targetKeys);
    },
  },
  created() {
    this.initData ();
  },
  methods: {
    initData () {
      getAction("/biz/bizFiveColorConfig/getTreeData",null).then(res => {
        if (res.success) {
          this.treeData = res.result;
          let resultTranferData = [];
          res.result.forEach(item => {
            resultTranferData.push({title: item.title, key: item.key});
            if(item.children && item.children !== null) {
              item.children.forEach(it => {
                resultTranferData.push({
                  title: it.title,
                  key: it.key,
                });
              })
            }
          })
          this.dataSource = resultTranferData;
        } else {
          this.treeData = [];
          this.dataSource = [];
        }
      })
    },
    handleTreeData(data, targetKeys = []) {
      data.forEach(item => {
        item['disabled'] = true;
        if (item.children && item.children != null) {
          item.children.forEach(it => {
            if(targetKeys.includes(it.key)) {
              it.disabled = true;
            } else {
              it.disabled = false
            }
          })
        }
      });
      return data;
    },
    handleRightChange(event, checkedKeys, itemSelect, key) {
      itemSelect(key, !this.isChecked(checkedKeys, key));
      const { target } = event;
      if(target.checked) {
        this.rightSelectKeys.push(key);
        this.rightSelectKeys = [...new Set(this.rightSelectKeys)];
      }
    },
    isChecked(selectedKeys, eventKey) {
      return selectedKeys.indexOf(eventKey) !== -1;
    },
    onChange(targetKeys, direction) {
      if(direction == 'right') {
        this.targetKeys = targetKeys;
        let resultData = [];
        this.treeData.forEach(item => {
          if(item.children && item.children != null) {}
          item.children.forEach(it => {
            if(this.targetKeys.includes(it.key)) {
              resultData.push(it);
            }
          })
        })
        this.rightData = resultData;
      } else {
        const resKeys = [];
        const resRightData = [];
        this.rightData.forEach(item => {
          if(!this.rightSelectKeys.includes(item.key)) {
            resKeys.push(item.key);
            resRightData.push(item);
          }
        })
        this.targetKeys = resKeys;
        this.rightData = resRightData;
      }
    },
    // 左侧复选框选中
    onLeftChecked(_, e, checkedKeys, itemSelect) {
      const { eventKey } = e.node;
      itemSelect(eventKey, !this.isChecked(checkedKeys, eventKey));
    },
    // 确认
    handleOk() {
      const chooseFactorArr = [];
      this.treeData.forEach(item => {
        let children = [];
        if(item.children && item.children != null) {
          children = item.children.filter(it => it.disabled);
          if(children.length) {
            chooseFactorArr.push({
              ...item,
              children
            })
          }
        }
      })
      this.confirmLoading = true;
      setTimeout(() => {
        this.$emit('handleRiskVisible', { bool: false, chooseFactorArr})
        this.confirmLoading = false;
      }, 1000);
    },
    // 取消
    handleCancel() {
      this.$emit('handleRiskVisible', { bool: false})
    },
    // nav切换
    handleNavChange(index) {
      this.currentNav = index;
    }
  },
};
</script>
<style scoped lang="less">

.left-ipt {
  display: flex;
  margin: 15px 0 13px;
}

.search-btn {
  margin-left: 8px;
}

.nav-list {
  display: flex;
  cursor: pointer;
}

.nav-item {
  padding: 0 8px;
  height: 24px;
  line-height: 24px;
  background: #EEEEEE;
  border-radius: 4px;
  margin-right: 16px;
  font-size: 12px;
  font-weight: 400;
  color: #333333;
}

.current-color {
  background: #2AB967;
  color: white;
}

.right-ipt {
  display: flex;
}

/deep/.ant-modal-footer {
  border-top: none;
  padding: 4px 24px 30px;
}

.tips {
  margin-top: 10px;
  font-size: 14px;
  color: #666666;
  line-height: 20px;
}

/deep/.ant-transfer-list-content-item {
  padding: 0 12px;
}

/deep/.ant-transfer-list {
  border: none;
}

/deep/.ant-transfer-list-header {
  border-bottom: none;
  border-radius: 0;
}

/deep/.ant-transfer-list-body {
  border-radius: 4px;
  border: 1px solid #DDDDDD;
}

/deep/.ant-transfer-list-header-selected span:first-child {
  position: relative;
  left: 100px;

  font-size: 12px;
  color: #999999;
}
.folder-icon {
  width: 14px;
  height: 11px;
  margin: 4px 0 6px 0;
}
/deep/.ant-transfer-list-header-title {
  left: 0;
  font-size: 14px;
  font-weight: 500;
  color: #333333;
}

/deep/.ant-input-affix-wrapper {
  color: #999999;
}

/deep/.ant-transfer-list {
  width: 100%;
  overflow: auto;
}

/deep/.ant-tree.ant-tree-block-node li span.ant-tree-checkbox + .ant-tree-node-content-wrapper {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
</style>

2、以上需要注意的点:

dataSource做为穿梭框的数据源需要是一维数组,并且里面的属性title和key都要为string类型,不然就会报错(dataSource类型不正确)

在这里插入图片描述

3、最终实现的效果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/984251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

攻克海外市场!企业客户培育,销售额倍增

随着全球市场的不断融合和国际贸易的加速&#xff0c;越来越多的企业纷纷进军海外市场&#xff0c;寻求新的增长机会。然而&#xff0c;在这一过程中&#xff0c;客户培育成为了取得成功的关键因素之一。运营坛今天将带领大家深入剖析为什么客户培育在国际市场尤为关键&#xf…

手写Spring:第2章-创建简单的Bean容器

文章目录 一、目标&#xff1a;创建简单的Bean容器二、设计&#xff1a;创建简单的Bean容器三、实现&#xff1a;创建简单的Bean容器3.0 引入依赖3.1 工程结构3.2 创建简单Bean容器类图3.3 Bean定义3.4 Bean工厂 四、测试&#xff1a;创建简单的Bean容器4.1 用户Bean对象4.2 单…

cmake编译(qtcreator)mingw下使用的osg3.6.5

官网下载osg3.6.5源码&#xff0c;先不使用依赖库&#xff0c;直接进行编译 如果generate后报错&#xff0c;显示找不到boost必须库&#xff0c;则手动增加路径。然后先在命令行中使用mingw32-make&#xff0c;如果显示不存在&#xff0c;则需要去环境变量里配置一下这个工具的…

h5开发网站-使用jquery来实现二层嵌套的左侧列表,点击后显示右侧内容的效果

一、需求&#xff1a; 使用jquery来实现二层嵌套的左侧列表&#xff0c;点击后显示右侧内容的效果。 二、思路&#xff1a; 为一级列表项和二级子列表项分别添加了点击事件处理程序。当一级列表项被点击时&#xff0c;使用.slideToggle()方法展开或收起对应的二级子列表项。…

Linux--进程--vfork与fork区别

vfork&#xff1a; 所需头文件&#xff1a;#include <sys/types.h> #include <unistd.h> pid_t vfork(void); 功能&#xff1a; vfork() 函数和 fork() 函数一样都是在已有的进程中创建一个新的进程&#xff0c;但它们创建的子进程是有区别的。 参数&#xff…

【自执行闭包JS逆向】某网站登录MD5加密分析

文章目录 一、写在前面二、抓包分析三、加密函数分析 一、写在前面 最近工作比较忙&#xff0c;不过还是在督促自己利用有限的时间学习更新一些技术文章。互联网这个行业大家目前也都知道是非常内卷的&#xff0c;所有大家在工作之余养成良好的自主学习习惯是非常好的&#xff…

egg单元测试Mocha报错Error: Cannot find module ‘mocha‘解决办法

最近在玩egg&#xff0c;使用mocha作为单元测试工具时发现一个很奇怪的报错&#xff0c;差了大多数文档都没说明&#xff0c;只好去官网搜了下&#xff0c;发现官网有解决方案。 1. 问题 如果你的报错和我的差不多&#xff0c;恭喜您&#xff0c;以下就是解决方案。 2. 解决方…

基于Delft3D模型水体流动、污染物对流扩散、质点运移、溢油漂移及地表水环境报告编制丨掌握模型建立、参数校准、模拟运行和结果分析等实际操作

目录 专题一 Delft3D软件介绍及建模原理和步骤 专题二 掌握Delft3D各模块的基本原理&#xff0c;以及在模型中的操作流程、实例练习模型 专题三 Delft3D数值模拟溶质运移模型建立 专题四 工程实施前后水文情势、流场、冲淤的变化 专题五 地表水环境风险预测 专题六 地表水…

HarmonyOS/OpenHarmony(Stage模型)应用开发组合手势(一)连续识别

组合手势由多种单一手势组合而成&#xff0c;通过在GestureGroup中使用不同的GestureMode来声明该组合手势的类型&#xff0c;支持连续识别、并行识别和互斥识别三种类型。 .GestureGroup(mode:GestureMode, …gesture:GestureType[]) mode&#xff1a;必选参数&#xff0c;为G…

老听说企业要做私域运营,那具体如何做呢?

以前企业获得新客户的方式是从各大流量平台进行引流&#xff0c;但现在这些公域平台人力投入和产出的比例不合理&#xff0c;或者费用太高而无法承担。因此&#xff0c;企业需要建立自己的私域流量池&#xff0c;无需付费、随时可接触的私域流量池。 那么&#xff0c;怎么做私域…

【数据结构】 七大排序详解(壹)——直接插入排序、希尔排序、选择排序、堆排序

文章目录 &#x1f340;排序的概念及引用&#x1f431;‍&#x1f464;排序的概念&#x1f431;‍&#x1f453;排序运用&#x1f431;‍&#x1f409;常见的排序算法 &#x1f334;插入排序&#x1f38b;基本思想&#xff1a;&#x1f6eb;直接插入排序&#x1f4cc;算法步骤&…

彩色图像处理彩色模型

彩色图像处理 彩色基础 人类感知一个物体的颜色是由物体反射光的性质决定的描述彩色光源的基本量&#xff1a; 辐射&#xff1a;是从光源流出能量的总量&#xff0c;用瓦特来度量光强&#xff1a;给出观察者从光源感知的能量总和的度量&#xff0c;用流明来度量亮度&#xff…

小龟带你写Java经典题(合并有序数组)

合并有序数组 1.题目2.图解分析3.代码演示 1.题目 2.图解分析 3.代码演示

汽车行业“墨守成规”?VR全景助力车企打开新局面

近年来&#xff0c;随着互联网时代的快速发展&#xff0c;各个行业都在不断挖掘创新点&#xff0c;汽车行业也是如此。以往汽车销售在线下门店的限制较多&#xff0c;由于营销方式、场地限制等原因&#xff0c;用户的体验过于单一&#xff0c;并且现场展示样车不多&#xff0c;…

控制算法::速度前馈

伺服三环设计---位置环前馈环路设计 - 百度文库 (baidu.com) 伺服电机-松下伺服前馈功能的使用示例_上海会通自动化科技发展有限公司 (shhuitong.net) 运动控制中速度前馈的作用_省身求是的博客-CSDN博客 速度前馈功能_技成培训网论坛 (jcpeixun.com)

lvm + raid(逻辑磁盘+阵列)创建删除恢复 for linux

本教程适用于linux lvm为逻辑磁盘&#xff0c;raid为阵列&#xff0c;两种技术可以单独使用也可以搭配使用 2023.9.3更新 前三节是操作命令和基础知识&#xff0c;后面是实操。 一、存储硬件查看相关命令 硬盘分区相关操作在后面用的到&#xff0c;可以先略过&#xff0c;有需…

微信小程序实现连续签到七天

断签之后会从第一天重新开始 <template><view class"content" style"height: 100vh;background: white;"><view class"back"><view style"position: absolute;bottom: 200rpx;left: 40rpx;width: 90%;"><i…

星际争霸之小霸王之小蜜蜂(十一)--杀杀杀

系列文章目录 星际争霸之小霸王之小蜜蜂&#xff08;十&#xff09;--鼠道 星际争霸之小霸王之小蜜蜂&#xff08;九&#xff09;--狂鼠之灾 星际争霸之小霸王之小蜜蜂&#xff08;八&#xff09;--蓝皮鼠和大脸猫 星际争霸之小霸王之小蜜蜂&#xff08;七&#xff09;--消失…

箭头函数(arrow function)与普通函数之间的区别是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 语法简洁性&#xff1a;⭐ this 的绑定&#xff1a;⭐ 不能用作构造函数&#xff1a;⭐ 没有 arguments 对象&#xff1a;⭐ 不适用于方法&#xff1a;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上…

svn log 高级命令解释

参考目录 基本命令完整命令效果鸣谢 实现目标&#xff1a;svn查询指定版本或时间范围指定人最近的变更文件路径到输出文件 基本命令 svn log --search youname -r {param1}:{param2} -v > custom.out完整命令 svn log --search yuanyubo -r {2020-07-01}:{2020-09-01} -v …