当前位置: 首页 > news >正文

el-tree点击变disabled

<template>
  <div class="flow-layer-tag-wrapper">
    <div class="left">
      <p class="title">可选标签</p >
      <!-- 搜索区 -->
      <div class="search">
        <el-input placeholder="请输入关键字" v-model="filterTagName" clearable>
        </el-input>
      </div>
      <!-- 左边内容区 -->
      <div class="content">
        <!-- 树形组件 -->
        <div class="tag-top">
          <el-tree
            ref="tree"
            :data="treeData"
            :props="treeProps"
            node-key="label"
            :check-on-click-node="true"
            highlight-current
            show-checkbox
            :filter-node-method="filterNode"
            default-expand-all
            @check="handleCheckChange">
          </el-tree>
        </div>
      </div>
    </div>
    <!-- 右边内容区 -->
    <div class="right">
      <p class="title">已选标签</p >
      <div class="search">
        <el-input placeholder="请输入关键字" v-model="selectedName" clearable>
          <el-button slot="append" @click="handleReset">清空</el-button>
        </el-input>
      </div>
      <div class="content" v-if="selectedTags.length">
        <div class="block" v-for="(tagItem, index) in searchSelectedTags" :key="index">
          <div class="wrapper" @click="handleChecked(index)" :class="[currentIndex === index ? 'active' : '']">
            <div class="main">
              <div :span="20" class="tag" v-for="(child, childIndex) in tagItem" :key="child.label">
                <div>{{ child.value }}</div>
                <el-button icon="el-icon-minus" type="danger" class="tag-btn" circle  @click="handleDelete(child, childIndex, index)"></el-button>
              </div>
            </div>
            <el-button size="mini" type="text" style="width: 40px; color: #999;">并集</el-button>
          </div>
          <el-button size="mini" type="text" v-if="index === selectedTags.length - 1" @click="handleAddWrapper">新建交集</el-button>
          <el-button size="mini" v-else>交集</el-button>
        </div>
      </div>
      <div v-else class="content-empty">
        请从左侧添加标签
      </div>
    </div>
  </div>
</template>

<script>
// import debounce from '@/utils/debounce'
export default {
  name: 'Tag',
  props: {
    oTreeData: {
      type: Array,
      default: () => {
        return []
      }
    },
    parentTags: Array, // 数据回显
  },
  data() {
    return {
      treeProps: {
        label: 'value',
        children: 'child'
      },
      currNodeId: '',
      count: 1,
      tagName: '',
      filterTagName: '',
      selectedName: '',
      // 左边可选标签列表
      tags: [],
      // 存放已选标签数组列表
      selectedTags: [],
      currentIndex: null, // 当前选中
      flag: true,
      checkedKeys: [],
      treeData: [],
      dataSource: [],
      tempKeys: [],
      allParentIds: [],
    }
  },
  computed: {
    // 右侧已选标签列表,使用计算属性因为涉及到搜索,需要动态过滤列表
    searchSelectedTags() {
      if (this.selectedName) { // 有关键字时
        let arr1 = []
        this.selectedTags.forEach(tag => {
          let arr2 = []
          tag.forEach(item => {
            if (item.value.search(this.selectedName) > -1) {
              arr2.push(item)
            }
          })
          arr2.length && arr1.push(arr2)
        })
        return arr1
      } else { // 无关键字时
        return this.selectedTags
      }
    },
    // 左侧可选标签长度
    choosableLen() {
      return this.tags.filter(item => !item.disabled).length
    },
    // 右侧已选标签长度
    selectedLen() {
      return this.tags.filter(item => item.disabled).length
    },
  },
  watch: {
    parentTags(val) {
      if (val) {
        this.selectedTags = JSON.parse(JSON.stringify(this.parentTags))
        let arr = [].concat.apply([], JSON.parse(JSON.stringify(this.parentTags)))
        //  已选标签,默认设置为第一项聚焦
        this.currentIndex = 0
        console.log(arr, 'arr.....')
        arr.forEach(item => {
          this.setDisabledById(this.treeData, item.label)
        })
        this.$emit('handleCheckedTags', this.selectedTags)
      }
    },
    // 监听若为空数组,disabled则全部变成false
    checkedKeys(val) {
      if (val.length === 0) {
        this.setTreeDataDisabledFalse(this.treeData)
      }
    },
    // 查询过滤
    filterTagName(val) {
      this.$refs.tree.filter(val)
    }
  },
  mounted() {
    this.treeData = JSON.parse(JSON.stringify(this.oTreeData))
    this.getAllParentIds(this.treeData)
  },
  methods: {
    // 设置disabled为false
    setTreeDataDisabledFalse(treeData) {
      if (treeData === undefined) treeData = []
      treeData.length && treeData.forEach(item => {
        this.$set(item, 'disabled', false)
        let arrChildren = item.child
        if (arrChildren !== undefined) this.setTreeDataDisabledFalse(arrChildren)
      })
    },
    // 收集所有的父级id
    getAllParentIds(treeData) {
      // allParentIds
      if (treeData === undefined) treeData = []
      treeData.length && treeData.forEach(item => {
        if (item.child !== undefined) {
          this.allParentIds.push(item.label)
          this.getAllParentIds(item.child)
        }
      })
    },
    // 选中某个并集容器
    handleChecked(index) {
      if (!this.selectedTags[index]) {
        this.currentIndex = null // 删除当前全部集合后,当前置灰选中状态不存在了,特此处理
      } else {
        this.currentIndex = index
      }
    },
    // 新建交集容器
    handleAddWrapper() {
      this.selectedTags.push([])
      this.currentIndex = this.selectedTags.length - 1
    },
    // 清空
    handleReset() {
      this.selectedTags = []
      this.checkedKeys = []
      this.$refs.tree.setCheckedKeys(this.checkedKeys, false)
      this.$emit('handleCheckedTags', this.selectedTags)
    },
    // 通过id,设置disabled,用于编辑回显数据
    setDisabledById(treeData, tagId) {
      let id = tagId
      if (treeData === undefined) {
        treeData = []
        return
      }
      treeData.length &&
        treeData.forEach(item => {
          if (item.label === tagId) {
            this.checkedKeys.push(tagId)
            this.$set(item, 'disabled', true)
            this.$refs.tree.setCheckedKeys(this.checkedKeys)
          }
          let arrChildren = item.child
          if (arrChildren !== undefined) this.setDisabledById(arrChildren, id)
        })
    },
    // 通过删除的某个子id时,去查找设置其所有的父节点可以点击
    setParentEnbledById(treeData, targetId) {
      if (treeData === undefined) {
        treeData = []
        return
      }
      treeData.length &&
        treeData.forEach(item1 => {
          // checkedKeys为当前选中的节点id
          if (item1.label === targetId) {
            console.log(parent, 'parentObj...')
            console.log(targetId, 'tagId...123')
            this.$set(item1, 'disabled', false)
            this.$refs.tree.setCheckedKeys(this.checkedKeys)
            this.setParentEnbledById(this.treeData, item1.pid)
            return
          }
          if (item1.child !== undefined) this.setParentEnbledById(item1.child, targetId)
        })
    },
    // 通过id,设置enabled,用于删除场景
    setEnbledById(treeData, targetId, parent = {}) {
      // const targetIds = targetId
      console.log(targetId, 'targetId....')
      if (treeData === undefined) {
        treeData = []
        return
      }
      treeData.length &&
        treeData.forEach(item1 => {
          // checkedKeys为当前选中的节点id
          if (item1.label === targetId) {
            console.log(parent, 'parentObj...')
            console.log(targetId, 'tagId...123')
            // parent.disabled = false
            // let index = this.checkedKeys.indexOf(pid)
            // if (index !== -1) this.checkedKeys.splice(index, 1)
            let index1 = this.checkedKeys.indexOf(targetId)
            if (index1 !== -1) this.checkedKeys.splice(index1, 1)
            this.$refs.tree.setCheckedKeys(this.checkedKeys)
            this.$set(item1, 'disabled', false)
            return
          }
          if (item1.child !== undefined) this.setEnbledById(item1.child, targetId, item1)
        })
    },
    // 删除标签
    handleDelete(tag, i, index) {
      let tagId = tag.label
      // 递归设置 该id的  disable  为false
      this.setEnbledById(this.treeData, tagId)
      // 递归设置 该id所有的父级节点的 disable 为false
      this.setParentEnbledById(this.treeData, tagId)
      this.$refs.tree.setCheckedKeys(this.checkedKeys)
      this.selectedTags[index].splice(i, 1)
      if (!this.selectedTags[index].length) {
        this.selectedTags.splice(index, 1)
      }
      if (!this.selectedTags[index]) {
        this.currentIndex = null // 删除当前全部集合后,当前置灰选中状态不存在了,特此处理
      } else {
        this.currentIndex = index
      }
      // checkedKeys需要删除所有的父级id,否则视图层删除无效果
      this.checkedKeys.map((item, index) => {
        if (this.allParentIds.includes(item)) {
          this.checkedKeys.splice(index, 1)
        }
      })
      this.$refs.tree.setCheckedKeys(this.checkedKeys)
      this.$emit('handleCheckedTags', this.selectedTags)
    },
    // 树形组件-查询过滤函数(防抖)
    filterNode (value, data) {
      if (!value) return true
      return data.value.indexOf(value) !== -1
    },
    // 树形组件-添加标签
    handleCheckChange(currentItem, data) {
      console.log(currentItem, 'param1...1111111')
      console.log(data, 'param2....1111111111')
      if (!this.selectedTags.length) {
        this.selectedTags = [[]]
        this.currentIndex = 0
      }
      if (this.currentIndex === null) {
        return this.$message.warning('请选择右侧要添加到的并集容器')
      }
      this.currNodeId = currentItem.label
      this.checkedKeys = JSON.parse(JSON.stringify(data.checkedKeys))
      // 防止重复push
      // if (currentItem.child !== undefined) {
      //   this.selectedTags[this.currentIndex].length = 0
      // }
      // this.selectedTags[this.currentIndex].length = 0
      this.setDisabled(this.treeData)
      // 设置所有选中的节点,均为disabled
      this.setAllCheckedDisabled(this.treeData)
      // '---------------------------------处理tree结构-----------------------------------------'
      this.$emit('handleCheckedTags', this.selectedTags)
    },
    // 确定某个父级id的条件下,child
    dealChild(treeData) {
      if (treeData === undefined) treeData = []
      treeData.length &&
        treeData.forEach(item => {
          // 处理右边已选标签
          if (item.child === undefined) {
            if (!item.disabled) {
              item.disabled = true
              this.selectedTags[this.currentIndex].push(item)
            }
          } else {
            this.$refs.tree.setCheckedKeys(this.checkedKeys)
            this.dealChild(item.child)
          }
        })
    },
    // 当所有子级变disabled,父级自己不自动变disabled,故递归将当前选中的key,把父级变成disabled
    setDisabled(treeData) {
      if (treeData === undefined) treeData = []
      treeData.length &&
        treeData.forEach(item => {
          if (this.currNodeId === item.label) {
            // 设置所有当前选中的为disabled状态
            // item.disabled = true
            if (item.child === undefined) {
              // 点击的是子节点
              this.selectedTags[this.currentIndex].push(item)
            } else {
              // 点击的是父节点
              this.dealChild(item.child)
            }
            this.$refs.tree.setCheckedKeys(this.checkedKeys)
          }
          if (item.child !== undefined) this.setDisabled(item.child)
        })
    },
    // 当所有子级变disabled,父级自己不自动变disabled,故递归将当前选中的key,把父级变成disabled
    setAllCheckedDisabled(treeData) {
      if (treeData === undefined) treeData = []
      treeData.length &&
        treeData.forEach(item => {
          if (this.checkedKeys.includes(item.label)) {
            // 设置所有当前选中的为disabled状态
            item.disabled = true
            this.$refs.tree.setCheckedKeys(this.checkedKeys)
          }
          if (item.child !== undefined) this.setAllCheckedDisabled(item.child)
        })
    },
  }
}
</script>

<style lang="scss" scoped>
.flow-layer-tag-wrapper {
  height: 356px;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  .left {
    margin-right: 40px;
  }
  .left,.right {
    width: 366px;
    overflow: auto;
    border: 1px solid #e1e3e5;
    border-radius: 4px;
    background: #fff;
    display: flex;
    height: 100%;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column;
    .title {
      height: 42px;
      line-height: 42px;
      border-bottom: 1px solid #e1e3e5;
      background: #f6f6f6;
      padding: 0 20px;
    }
    .search {
      padding: 20px 20px 0 20px;
    }
    .content {
      -ms-flex: 1;
      flex: 1;
      overflow: auto;
      padding-left: 20px;
      padding-right: 20px;
      .tag {
        display: flex;
        padding: 0 6px;
        justify-content: space-between;
        &:hover {
          background-color: #dfdfdf;
        }
        .tag-btn{
          margin:4px 0 0;
          padding:0;
          width: 24px;
          height: 24px;
          line-height: 4px;
          text-align: center;
        }
      }
      .wrapper {
        display: flex;
        justify-content: space-between;
        // align-items: center;
        border-top: 1px solid #efefef;
        border-bottom: 1px solid #efefef;
        &:hover {
          background-color: #efefef;
        }
        .main {
          flex: 1;
        }
      }
      .active {
        background-color: #efefef;
      }
    }
    .content-empty {
      text-align: center;
      margin-top: 80px;
      color: #aaa;
    }
  }
}
</style>

 

相关文章:

  • css /deep/
  • json可视化在vue应用中的实现
  • Please use the --no-verify flag to skip running lint-staged.
  • 32个手写JS,巩固你的JS基础(面试高频)
  • 如何搭建npm私有仓库及发布npm包
  • vscode批量替换
  • js去除字符串空格
  • for循环里面的break;和continue;语句
  • JS递归树结构,修改树结构的属性值key和value
  • Antd Select组件结合使用出现must set key for <rc-animate> children问题
  • react数组变了,但是视图没有更新
  • antd下拉框选择了值,却仍然触发了rules里面的必选项
  • 冷门的骚操作
  • 黑科技:编辑任何网页只需要一句代码
  • antd 组件Input 输入按字节限制长度(汉字占2个字节,字母1个字节)
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • Android 控件背景颜色处理
  • centos安装java运行环境jdk+tomcat
  • echarts花样作死的坑
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • Magento 1.x 中文订单打印乱码
  • Python进阶细节
  • session共享问题解决方案
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 驱动程序原理
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 实现菜单下拉伸展折叠效果demo
  • 使用API自动生成工具优化前端工作流
  • 无服务器化是企业 IT 架构的未来吗?
  • 怎么把视频里的音乐提取出来
  • ionic入门之数据绑定显示-1
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​Linux·i2c驱动架构​
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • $ git push -u origin master 推送到远程库出错
  • (2)Java 简介
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)详解PHP处理密码的几种方式
  • (转载)CentOS查看系统信息|CentOS查看命令
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • ***监测系统的构建(chkrootkit )
  • .NET MVC第三章、三种传值方式
  • .Net Remoting常用部署结构
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .sdf和.msp文件读取
  • :not(:first-child)和:not(:last-child)的用法
  • @angular/cli项目构建--Dynamic.Form
  • [ vulhub漏洞复现篇 ] AppWeb认证绕过漏洞(CVE-2018-8715)