部门或者人员等层级Tree

前端工作中经常遇到需要多层级选择的场景,有时候单选有时候多选,有的需要联动有的又不需要,有的需要置灰不可选,等等场景太多,看着头疼///

业务场景:

1)部门多选且父子部门不联动场景,效果如下:

2)人员选择--只能单选 部门显示book图标 人员显示user图标,效果如下:

解决方案:使用treeselect,话不多说上代码

使用方法:

1、安装:

npm install --save @riophae/vue-treeselect

2、使用

import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
  name: "Treepage",
  components: { 
    Treeselect
  },
    data() {
        return {
            // 表单参数
          form: {
            deptIds: [],//所在部门
             // 多选部门树选项
            deptOptions: [],
            superior:null,//单选 直属上级id
            superiorName:'',//直属上级名字
          }
        }
    },
    mounted() {
        this.getTreeselect();// 获取部门列表
    },
    methods: {
        /** 查询部门下拉树结构 */
        async getTreeselect(){
          let data = await treeselect(this.queryParams);
          if (data.code === SUCCESSCODE) {
            this.deptOptions = data.data;//接口获取部门tree
          }
        },
        /** 转换部门数据结构 */
        normalizer(node) {
          return {
            id: node.id,
            label: node.label,
          }
        },
        /** 查询部门下拉树结构 */
    async getdeptUserTreeselect(){
      let data = await deptUserTreeselect();
      if (data.code === SUCCESSCODE) {
        this.superiorOptions = data.data;//接口获取 直属上级tree列表
      }
    },
    // 直属上级列表处理
    superior_normalizer(node) {
      if ((node.children && !node.children.length) || node.children === null) {
        delete node.children;
      }
      //isDisabled 类型node.type是部门且部门下没有员工则置灰不可选
      return {
        id: node.id,
        label: node.label,
        isDisabled: node.type === 1 && (!node.children || node.children === null) ? true : false,
        children: node.children,
      }
    },
    //选中人员的时候拿到上级ID和名字
    superiorTreeSelectChange(raw){
      this.form.superior = raw.id;
      this.form.superiorName = raw.label;
    },
    }
    
}
<el-form ref="form" :model="form" :rules="rules" label-width="130px">
    <!-- 部门多选 -->
    <el-row class="dept-con">
        <el-col :span="12">
          <el-form-item label="部门" prop="deptIds">
            <treeselect 
              :multiple="true"
              :append-to-body="true"
              v-model="form.deptIds" 
              :options="deptOptions" 
              :normalizer="normalizer"
              :show-count="true"  
              noOptionsText="暂无数据" 
              noResultsText="未找到数据" 
              placeholder="请选择部门"
              :flat="true"
              :auto-deselect-descendants="false"
              :auto-select-descendants="false"
              search-nested
            >
              <label
                slot="option-label"
                slot-scope="{ node, shouldShowCount, labelClassName, countClassName }"
                :class="labelClassName"
              >
                <slot name="diy-option" v-bind="{ node, shouldShowCount, countClassName }">
                  <img src="@/assets/images/book.png" style="width:15px; height:15px;"/>
                  {{ node.label }}
                  <span v-if="shouldShowCount" :class="countClassName">({{ node.children.length }})</span>
                </slot>
              </label>
            </treeselect>
            <!-- 组件说明 设置父子不联动选择
            :flat="true" //设置平面模式(选中的标签不联动子节点和父节点)
            :auto-deselect-descendants="false" //取消节点时,取消其接点的子节点(仅可在平面模式下使用)
            :auto-select-descendants="true" //选择节点时,取消其接点的子节点(仅可在平面模式下使用)
            :disable-branch-nodes="true" //设置只能选择子节点
          -->
          </el-form-item>
        </el-col>
      </el-row>
      <!-- 人员单选 -->
       <el-row>
        <el-col :span="12">
          <el-form-item label="直属上级" prop="superior">
            <treeselect v-model="form.superior"
              :append-to-body="true"
              :options="superiorOptions" 
              noOptionsText="暂无数据" 
              noResultsText="未找到数据" 
              :show-count="true" 
              placeholder="请选择直属上级" 
              search-nested
              :flat="true"
              :disable-branch-nodes="true"
              :normalizer="superior_normalizer"
              @select="superiorTreeSelectChange"
            >
            <label
                slot="option-label"
                slot-scope="{ node, shouldShowCount, labelClassName, countClassName }"
                :class="labelClassName"
              >
                <slot name="diy-option" v-bind="{ node, shouldShowCount, countClassName }">
                  <img v-if="node.raw.type == 1" src="@/assets/images/book.png" style="width:15px; height:15px;"/>
                  <img v-else src="@/assets/images/people.png" style="width:15px; height:15px;"/>
                  {{ node.label }}
                  <span v-if="shouldShowCount" :class="countClassName">({{ node.children.length }})</span>
                </slot>
              </label>
            </treeselect>
          </el-form-item>
        </el-col>
      </el-row>
</el-form>

 结语:

以上就是所有代码啦,感谢看到了这里,希望对你有所帮助,拜拜~

QAbstractItemModel是Qt框架中用于实现数据模型的抽象类,它提供了一种通用的方式来表示和操作数据。多层级Tree的实现可以通过继承QAbstractItemModel类来完成。 首先,你需要定义一个自定义的数据模型类,继承自QAbstractItemModel。在这个类中,你需要实现一些必要的函数来处理数据的组织和访问。 1. rowCount和columnCount函数:用于返回形结构中每个节点的子节点数量和列数。 2. index函数:根据给定的行、列和父节点索引,返回对应节点的索引。 3. parent函数:根据给定的节点索引,返回其父节点的索引。 4. data函数:根据给定的节点索引和角色,返回对应节点的数据。 在实现这些函数时,你需要考虑到多层级Tree的特点。通常情况下,每个节点都会有一个父节点和若干个子节点。你可以使用一个数据结构(如列表或字典)来存储节点的信息,并在相应的函数中进行处理。 下面是一个简单的示例代码,演示了如何使用QAbstractItemModel实现多层级Tree: ```python from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt class TreeModel(QAbstractItemModel): def __init__(self, data, parent=None): super().__init__(parent) self.rootItem = data def rowCount(self, parent=QModelIndex()): if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() return len(parentItem.children) def columnCount(self, parent=QModelIndex()): return 1 def index(self, row, column, parent=QModelIndex()): if not self.hasIndex(row, column, parent): return QModelIndex() if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() childItem = parentItem.children[row] if childItem: return self.createIndex(row, column, childItem) else: return QModelIndex() def parent(self, index): if not index.isValid(): return QModelIndex() childItem = index.internalPointer() parentItem = childItem.parent if parentItem == self.rootItem: return QModelIndex() return self.createIndex(parentItem.row(), 0, parentItem) def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None item = index.internalPointer() if role == Qt.DisplayRole: return item.data return None ``` 在这个示例中,我们定义了一个TreeModel类,其中的data属性表示节点的数据,children属性表示子节点列表。你可以根据实际需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值