vue 下拉选择是tree结构

159 阅读2分钟

vue2安装插件@riophae/vue-treeselect

            <el-col :span="12">
                        <el-form-item label="归属部门" prop="deptId">
                          <treeselect
                            v-model="form.deptId"
                            :options="deptOptions"
                            :disable-branch-nodes="true"
                            :show-count="true"
                            placeholder="请选择归属部门"
                          />
                        </el-form-item>
                      </el-col>

              
             import Treeselect from "@riophae/vue-treeselect";
        import "@riophae/vue-treeselect/dist/vue-treeselect.css";
                          components: { Treeselect },
                            // 部门树选项
                       deptOptions: undefined,
              
       deptOptions 数组 接口数据 下图格式 
        this.deptOptions = response.data;
        
        
        // 节点单击事件
        handleNodeClick(data) {
          this.queryParams.deptId = data.id;
          this.getList();
        },

image.png

vue3 安装插件是npm i vue3-treeselect 结构也是这样的

                            <el-form-item label="用户所属部门" prop="deptId">
                              <!--    @click.native="getVideoplatList" -->
                              <!-- <el-input
                                v-model="form.deptName"
                                placeholder="请输入平台名称"
                              @click.native="getVideoplatList"
                              /> -->
                              <tree-select
                                v-model="form.deptName"
                                :multiple="true"
                                :options="state.cityTreeData"
                                :disable-branch-nodes="true"
                                :normalizer="state.normalizer"
                                :show-count="true"
                              />
                            </el-form-item>

                     // 部门树选项
                    // const deptOptions = ref(undefined);
                    const state = reactive({
                      cityTreeData: [],
                      normalizer(node) {
                        if (node.children && !node.children.length) {
                          //去掉childList=[]的情况
                          delete node.children;
                        }
                        return {
                          id: node.id, //字段名的替换
                          label: node.deptName,
                          children: node.children,
                        };
                      },
                    });





       arrData.value = res.data.map((r) => {
          console.log('r.children',r.children);
          console.log('r.children',r.children && !r.children.length);
          if (r.children && !r.children.length) {
            console.log(' delete r.children;', delete r.children);
            delete r.children;
          }
          return {
            id: r.id,
            label: r.deptName,
            children: r.children,
          };
        });
        
        虽然第一层转号了 但是里面的childern没转成功  最好的方法就是让后台改字段 我这个vue3这个项目label不方便转 转了这个在新增修改这个字段无法对应上的好像,
        之前是点击input然后触发弹框table选择tree数据 甲方觉得不够简单,所以还是需要上面的插件进行转换
        
        // 添加人员的用户部门 -下拉框里面的数据
                function getinit() {
                  getDeptRelation().then((res) => {
                    deviceList.value = res.data;
                    console.log("deviceList.value ", deviceList.value);
                    
                    下面这个代码只可以修改第一层的字段名 children里面的字段名没有修改成功
                    所以直接把tree结构字段直接赋值给接口返回值:state.cityTreeData=res.data
                    然后通过递归的方式把所以的字段名都进行更换,递归的方法是:transferKey()函数
                    
                   // state.cityTreeData = res.data.map((node) => {
                      if (node.children && !node.children.length) {
                        //去掉childList=[]的情况
                        delete node.children;
                      }
                      return {
                        id: node.id, //字段名的替换
                        label: node.deptName,
                        children: node.children,
                      };
                    });
                    transferKey(res.data);
                    console.log(state.cityTreeData, "state.cityTreeData");
                  });//
                }
                function transferKey(arr) {
                  arr.forEach((obj) => {
                    obj.label = obj.deptName;
                    delete obj["deptName"];
                    if (obj.children instanceof Array) {
                      transferKey(obj.children);
                    }
                  });
                  console.log('arr',arr);
                  return arr;
                }
                
                上面是可以的显示 但是form表单 提交的字段无法更改成后端定义的字段,因为这个插件的@seclect这个方法点击这个节点获取返回值,当这个节点数据没有children只有id和laber这个事件函数就没有触发,有子节点返回的值也没有laber等字段,所以又不使用上述方法了
                
                
                 <el-form-item label="用户所属部门" prop="deptId">
    
              <el-select
                ref="selectTree"
                v-model="form.deptName"
                placeholder="请输入用户所属部门"
              >
                <el-option
                  :key="form.deptName"
                  :value="form.id"
                  :label="form.label"
                  style="height: auto"
                  hidden
                />
                <el-tree
                  :data="state.cityTreeData"
                  :props="defaultProps"
                  @node-click="handleCurrentChange"
                />
                <!-- </el-option> -->
      </el-select>
      
      注意:el-option需要设置一个hidden隐藏的下拉选项,若不设置则tree组件无法使用,因为选择器是el-select和el-option组成的下拉选项,tree自带下拉选择,所以需要隐藏el-option的下拉选项。
      
      // 所属部门点击选中事件
        function handleCurrentChange(val) {
          console.log("Select");
          console.log("val", val);
          
          form.value.deptId = val.id;
          form.value.deptName = val.label;
      

          // 选择器执行完成后,使其失去焦点隐藏下拉框的效果

          proxy.$refs.selectTree.blur();
        }