精华内容
下载资源
问答
  • a-tree 异步树真是太多坑了,不显示文字,点击根节点没反应,点击子节点没反应,点击子节点出现的是上一个子节点内容,切换是否展示监管部门时点击过的子节点没反应,好在问题都一一解决了,记录一下。 <a-...

    a-tree 异步树真是太多坑了,不显示文字,点击根节点没反应,点击子节点没反应,点击子节点出现的是上一个子节点内容,切换是否展示监管部门时点击过的子节点没反应,好在问题都一一解决了,记录一下。
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    <a-checkbox @change="onCheckboxDeptChange"> 是否展现非监管部门 </a-checkbox>
     <a-tree
                :replaceFields="replaceFields"
                :loadedKeys="loadedKeys"
                @expand="onExpand"
                @load="loadDept"
                :expandedKeys="expandedKeys"
                :load-data="onLoadDeptData"
                :tree-data="treeDeptData"
              />
    
    data() {
        return {
          loadedKeys: [],
          expandedKeys: [],
          isShowAll: false, //非监管部门是否展示
          treeDeptData: [],
          replaceFields: {
            children: 'children',
            title: 'text',
            key: 'id',
          }, // 树数据结构匹配替换映射
          }
     }
    
    //loadedKeys	(受控)已经加载的节点,需要配合 loadData 使用
        //	节点加载完毕时触发
        loadDept(loadedKeys) {
          this.loadedKeys = loadedKeys
        },
    
        //展开/收起节点时触发
        onExpand(keys) {
           // expandedKeys(.sync)	(受控)展开指定的树节点
          this.expandedKeys = keys
        },
        // 异步加载数据
        onLoadDeptData(treeNode) {
          return new Promise((resolve) => {
            setTimeout(() => {
              this.requestGet(
                `/Dept/RegionDeptTreeByParent?isShowAll=${this.isShowAll}&&nodeTypeValue=${treeNode.dataRef.typeEnum}&&parent=${treeNode.dataRef.id}`
              ).then((res) => {
                treeNode.dataRef.children = res.data.map((item) => {
                  return item
                })
                this.treeDeptData = [...this.treeDeptData]
                resolve()
              }, 1000)
            })
          })
        },
    
        //获取树结构
        RegionDeptTreeByParent() {
          this.loadedKeys=[]
          this.expandedKeys=[]
          this.requestGet('/Dept/RegionDeptTreeByParent').then((res) => {
            this.treeDeptData = res.data.map((item) => {
              item.isLeaf = false
              return item
            })
          })
        },
        //是否展现非监管部门
        onCheckboxDeptChange(e) {
          console.log(`checked = ${e.target.checked}`)
          if (e.target.checked == true) {
            this.isShowAll = true
          } else {
            this.isShowAll = false
          }
          this.treeDeptData=[]
          this.RegionDeptTreeByParent()
        },
    
    展开全文
  • vue 项目ztree 异步加载

    千次阅读 2019-11-11 16:43:32
    // 异步加载时需要自动提交父节点属性的参数 } , callback : { onClick : this . onClick , // 节点被点击时调用 } } , `` 2、点击树异步请求后台数据 onClick ( ...

    1、在data()添加setting设置

    
    setting: {
    					data: {
    						simpleData: {
    							enable: true,
    							idKey: "",
    							pIdKey: "",
    							rootPId: 0
    						}
    					},
    					check: {
    						//不显示复选框
    						enable: false
    					},
    					view: {
    						nameIsHTML: true,
    						selectedMulti: false
    					},
    					edit: {
    						enable: false,
    						editNameSelectAll: false
    					},
    					async: {
    						enable: true, // 开启异步加载
    						url: "", //对应的后台请求路径
    						dataType: "json",
    						autoParam: [] // 异步加载时需要自动提交父节点属性的参数
    					},
    					callback: {
    						onClick: this.onClick, // 节点被点击时调用
    					}
    				},
    

    `` 2、点击树异步请求后台数据

    onClick(event, treeId, treeNode, clickFlag) {
    			//console.log(event, treeId, treeNode, clickFlag)
    				let get_url ="xxxxxx"
    				this.$http.get(get_url, {}).then(items=> {
    				//	console.log('treeSelect res-------->::', items)
    	
    						//异步点击查询子节点,无该子节点则插入到该父节点中
    						if(!treeNode.hasOwnProperty("children") || treeNode.children.length == 0) {
    							for(let i = 0; i < items.length; i++) {
    								var treeObj = $.fn.zTree.getZTreeObj(treeId);//treeId为自定义的树的id
    								var parentZNode = treeObj.getNodeByParam("code", treeNode.code, null); //获取指定父节点,code为本级节点, treeNode.code为当前点击节点的code值
    								let newNode = treeObj.addNodes(parentZNode, items[i], false);//将获取到的子节点插入到父节点中
    							}
    						}
    
    					}
    				}).catch(error => {
    					console.log(error)
    					throw new Error(error)
    				})
    
    			},
    
    展开全文
  • 情景 需要生成一棵树,树的...实现一个有异步批量加载功能的树 class treeLoader { constructor(props) { const { treeData, treeProps, treeLoaderFn, //加载树结点的fn treeMultiLoaderFn, //批量加载树结

    目录

    情景

    抽象实现一个有异步批量加载功能的树

    问题:第三级树结构无法渲染出来,直接$set也失效了

    分析

    解决


    情景

    1. 需要生成一棵树,树的节点叶子可能很多,一次性数据返回会导致性能问题;
    2. 需要根据parent的nodeType不同,设置不同的请求的接口;有的接口直接返回tree格式,有的只返回下一级等;
    3. 需要保持树的复选框【全选等】功能。

    抽象实现一个有异步批量加载功能的树

    class treeLoader {
      constructor(props) {
        const {
          treeData,
          treeProps,
          treeLoaderFn, //加载树结点的fn
          treeMultiLoaderFn, //批量加载树结点的fn
          checkHasChildFn, //判断是否有children【是否是叶子节点】
          loaderSuccessCallback,//全部加载完的回调
          loaderFailCallback,//加载失败的回调【暂无用】
        } = props;
        this.options = {
          maxMultiCount: 20,//单次最大id合并请求数
          treeData,
          treeProps,
          treeLoaderFn,
          treeMultiLoaderFn, //批量加载树结点的fn
          checkHasChildFn,
          loaderSuccessCallback,
          loaderFailCallback,
        };
        this.initDep();
        this.running = [];
        this.treeDataMap = {};
      }
      
      initDep() {
        //成功回调
        Object.defineProperty(this.options, 'tip', {
          get:() => this.__tip,
          set(val) {
            val && this.loaderSuccessCallback(this.treeData);
            this.__tip = val;
          }
        })
    
        this.options.tip = false;
    
        let self = this;
        //需要加载排队请求idList的代理
        this.toLoaderData = new Proxy([], {
          set(target, key, value, receiver) {
            if (key === 'length') {
              if (value > 0) {
                setTimeout(()=>{
                  self._loadMulti();
                }, 100);
              }
            }
            return Reflect.set(target, key, value, receiver);
          },
          deleteProperty(target, key) {
            return Reflect.deleteProperty(target, key);
          }
        })
      }
    
      run() {
        this.load(this.options.treeData);
      }
      //一个节点请求
      load(data) {
        if (data.__all) {
          return true;
        }
        data.__all = true;
        data.isClick = true;
        //console.log('--treeLoader--', data[this.options.treeProps.id]);
    
        this.running.push(1);
        this.options.treeLoaderFn(data).then(()=>{
          this.searchGrandChild(data);
        }).finally(()=>{
          this.running.pop();
          (this.running.length === 0) && (this.options.tip = true);
        })
      }
      //根据treeId获取扁平化parentIdList
      findParentTreeIdLinkFromTreeData(treeId) {
        let parentId = this.treeDataMap[treeId];
        let arr = [parentId];
        if (this.treeDataMap[parentId]) {
          arr = arr.concat(this.findParentTreeIdLinkFromTreeData(parentId));
        }
    
        return arr;
      }
      //根据treeId获取实际的treeData
      findLeafFromTreeData(treeId) {
        let treeParentLinks = this.findParentTreeIdLinkFromTreeData(treeId);
        let treeParentLinksLength = treeParentLinks.length;
    
        const getParent = (GrandParent, index) => {
          let parent = GrandParent[this.options.treeProps.children].filter((item)=>item[this.options.treeProps.id] == treeParentLinks[index])[0];
          index--;
          if (index > -1) {
            parent = getParent(parent, index);
          }
    
          return parent;
        }
        let parent = null;
        if (this.options.treeData[this.options.treeProps.id] != treeParentLinks[treeParentLinksLength-1]) {
          console.error('treeLoader-findLeafFromTreeData treeParent Not Found')
          return {};
        }
        if (treeParentLinksLength === 1) {
          parent = this.options.treeData;
        }else {
          parent = getParent(this.options.treeData, treeParentLinksLength-2);
        }
    
        return parent[this.options.treeProps.children].filter((item)=>item[this.options.treeProps.id] == treeId)[0];
      }
      //获取孙子节点
      searchGrandChild(data) {
        data[this.options.treeProps.children] = data[this.options.treeProps.children] ?? [];
        data[this.options.treeProps.children].map((child) => {
          if (this.options.checkHasChildFn(child)) {
            this.treeDataMap[child[this.options.treeProps.id]] = data[this.options.treeProps.id];
            this.toLoaderData.push(child[this.options.treeProps.id]);
            // this.load(child);太多节点会导致请求过多
          }
        })
      }
      //批量请求
      _loadMulti() {
        //超过最大值,就先截取最大值
        let length = this.toLoaderData.length >= this.options.maxMultiCount ? this.options.maxMultiCount : this.toLoaderData.length;
        if (length == 1 && this.options.treeMultiLoaderFn) {
          let qId = this.toLoaderData.splice(0, 1)[0];
          this.load(this.findLeafFromTreeData(qId));
        }else {
          this.loadMulti(this.toLoaderData.splice(0, length));
        }
      }
    
      loadMulti(ids) {
        let datas = [];
        ids.forEach((id)=>{
          let data = this.findLeafFromTreeData(id);
          data.__all = true;
          data.isClick = true;
          datas.push(data);
          this.running.push(1);
        })
        this.options.treeMultiLoaderFn(datas, this).then((resDatas)=>{
          resDatas.forEach((data)=>{
            let _data = this.findLeafFromTreeData(data[this.options.treeProps.id]);
            _data.children = data.children;
    
            this.running.pop();
            this.searchGrandChild(_data);
          })
    
        }).finally(()=>{
          (this.running.length === 0) && (this.options.tip = true);
        })
      }
    }
    
    export default treeLoader;
    

    问题

    在做异步批量加载树结构的时候,发现到第三级节点的时候,children无法有效显示出来,而且手动$set也失效了。

    分析

    页面的更新主要是依赖于 Vue 的响应式原理,而Vue2的响应式初始化,一个是created的时候,一个是$set手动设置。

    但是$set手动设置时,如果是数组或者对象的话,一些情况是触发不到变动的。

    如:

    this.$set(data, 'children', children);

    当data.children已经存在的话,那么 children === data.children 为 true,无法触发到响应式变动。

    其次,elementUI内部判断是否更新,也是用的 === 比较。

    数组和数组的比较,对象和对象的比较,比较的是引用地址

    解决

    • 方案一:继续使用$set特性,在每次展开操作的时候,重新设置。
        handleNodeExpand(data, node) {        
            if(!data.is_expand) {
              let children = data.children;
              data.children = null;//粗暴的先删除
              this.$nextTick(()=>{
                this.$set(data, 'children', children);//再设置
                this.$set(data, 'is_expand', true);
                ...其他操作
              })
            }
        }
    • 方案二:使用elementUI里面node的updateChildren方法,改造一下。
    import Vue from 'vue'
    class treeLoader {
      constructor(props) {
        const {
          root,
          ...
        } = props;
        this.$nextTick = root.$nextTick.bind(root);
        this.options = {
          getTreeNode,
          ...
        };
        ...
      }
    
      initDep() {}
    
      run() {}
    
      load(data) {
        ...
        this.options.treeLoaderFn(data).then(()=>{
          this.$nextTick(()=>{
            this.options.getTreeNode(data).updateChildren();
            this.running.pop();
            this.searchGrandChild(data);
          })
        }).finally(()=>{...})
      }
    
      findParentTreeIdLinkFromTreeData(treeId) {}
    
      findLeafFromTreeData(treeId) {}
    
      searchGrandChild(data) {}
    
      _loadMulti() {}
    
      loadMulti(ids) {
        ...
        this.options.treeMultiLoaderFn(datas, this).then((resDatas)=>{
          resDatas.forEach((data)=>{
            let _data = this.findLeafFromTreeData(data[this.options.treeProps.id]);
            
            this.$nextTick(()=>{
              this.options.getTreeNode(data).updateChildren();
              this.running.pop();
              this.searchGrandChild(_data);
            })
          })
    
        }).finally(()=>{...})
      }
    }
    
    export default treeLoader;
    

    展开全文
  • VUE 使用 IView 实现Tree进行异步数据加载,在页面初始化时默认加载二级数据,二级之后的数据再进行异步数据加载 布局 <Tree v-show="familyList[0].children.length > 0" ref="mytree" :data=...

    VUE 使用 IView 实现Tree进行异步数据加载,在页面初始化时默认加载二级数据,二级之后的数据再进行异步数据加载

    布局

    <Tree v-show="familyList[0].children.length > 0"  
    ref="mytree" 
    :data="familyList" 
    :load-data="handleLoadData"  
    @on-select-change="selChange" 
    @on-check-change="ClickCheck" 
    show-checkbox 
    expand-node>
    </Tree> 

    数据加载及方法

    export default {
      data(){
        return{
          familyList: [
            {
              ID: "0",
              Name: "结构",
              title: "结构",
              loading: false,
              expand: true,
              selected: true,
              children: [],
              disableCheckbox: true
            },
          ],
        }
      },
      mounted(){
        this.loadData(this.familyList[0]);
      },
      methods:{
        loadData(item, callback) {
          var _this = this;
          var _item = item;
          var pid = "";
          if (_item) {
            pid = _item.ID;
          }
          post("/api/GetTree", {
            PID: pid
          }).then((res) => {
            if (res.Code == 0) {
              var list = res.Datas;
              list.forEach(function(obj, indxs) {
                if (obj.ChildCont > 0) {
                  obj.loading = false;
                }
              });
              if (callback !== undefined) {
                callback(list);
              }
              if(_this.familyList[0].children.length == 0){
                _this.familyList[0].children =list;
              }
            }
          });
        },
        handleLoadData(item, callback) {
          this.loadData(item, function(data) {
            callback(data);
          });
          this.$forceUpdate();
        },
        selChange(selarray, item) {//当前已选中的节点数组、当前项
         
        },
        ClickCheck(selarray, item) {//当前已选中的节点数组、当前项
         
        }
      }
    }
    </script>

     

    展开全文
  • a-tree-select style="width: 90%" allowClear :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :treeData="personData" showSearch :load-data="onLoadData" /> onLoadData(treeNode){ var...
  • 用el-tree的lazy属性 存在问题: 如果绑定用 :load=“loadNode” 看着是懒加载但也会触发多次,第一次就把所有数据拿出来了。 如果绑定 :data=“data” 就不会显示前面的三角形。 解决方案 lazy 和 data 属性和 ...
  • VUE 使用 IView 实现Table Tree进行异步数据加载 页面布局 <Table ref="thisTab" row-key="ID" :load-data="handleLoadData" :columns="columnsList" :data="familyList" :highlight-row="true" :...
  • vue中使用z-tree插件,执行异步加载时候,API文档提示必须写上。 async: { enable: true, url: &quot;nodes.php&quot;, autoParam: [&quot;id&quot;, &quot;name&quot;] } ...
  • element-ui异步加载行政区划树 功能:进入页面,左侧显示行政区划树的顶级目录,单击目录左侧的箭头,则向后端发送请求,获得该级目录的子目录;以此类推;点击目录本身,则向后端发请求和右边的列表进行联动; ...
  • vue异步加载

    2020-08-24 15:06:42
    methods: { getStart() { // 岗位查询 const p1 = new Promise((resolve, reject) => { findAll().then((res) => { this.postObj = res.data;... }, } // 异步加载 created() { this.getStart(); }
  • html <el-form-item label="门店:" :label-width="formLabelWidth"> <el-tree :props="props" :load="loadNode" node-key="id" ref="tree" highlight-current lazy show-che
  • 7-26日再更新组件懒加载有三种方式:1.... vue异步 = resolve => require(['../../xx'], resolve)3. webpackrequire.ensurer => require.ensure([], () => r(require('../components/Hel...
  • Vue动态加载异步组件

    2018-12-15 19:37:00
    这个异步加载组件已经结束了。这边门户需要封装一封实现异步组件。父级只需要传入url即可。这边还有个可以优化的是,可以把mode优先缓存,那么不需要每次都去加载请求。如下: 我们可以看到在门户的一个数据概览...
  • 1.引入 <el-tree :props="props" :load="loadNode" node-key="id" ref="tree" highlight-current lazy show-checkbox @node-click="handleNodeClick" >...
  • vue ant-design Tree树结构 同步加载

    千次阅读 2020-04-30 15:36:20
    公司业务需要,让我一个后台,...官网的是异步加载,但是也不可用,这里是没有**return resolve()**这个方法的,和Element UI的写法不同,大家千万不要忘了! 树结构 <a-tree :treeData="treeData" :loadData...
  • jsTree异步动态加载子节点

    千次阅读 2017-10-13 10:02:27
    想要将显示区域作为查询的条件,而区域是树形结构并且可以多选,并且数据量很大,是从中国到乡镇的地区数据,如果我们一次将所有的区域数据查出直接塞到树形结构,那么页面将会卡死,因此我们需要每次加载部分数据,...
  • 场景:最近做tree异步加载的功能,但是发现只有我第一次点击的时候,会调用方法加载,后面再点击都不会再加载。 需求:每次点击都会加载 解决方法: 用onExpand,onLoad,loadedKeys,expandedKeys <Tree ...
  • ant design提供的可搜索树的案例(此案例不要被里面的x,y,z所迷惑,仔细看看,他们只是造假数据的),以及异步数据加载树的案例,下面对这两个案例合二为一留作参考 import React from 'react'; import {Tree, Input} ...
  • 如何使用elementui中的树形组件在懒加载模式中会默认展开N层;...剩下的使用异步加载. <template> <div id="app"> <el-tree :props="props" :load="loadNode" lazy show-checkbox> </el-
  • ant design vue中treeselect异步获取数据

    千次阅读 热门讨论 2019-07-29 16:28:56
    结构: <a-tree-select :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" :getPopupContainer="(triggerNode) => triggerNode.parentNode" :loadD...
  • Vue加载异步组件时的resolve函数

    千次阅读 2020-07-21 16:32:37
    见识到了一些没见过的写法, 网上找不到满意的答案, 只好自己找咯,希望能够帮到其他人, 学习ing+++ 我是目录 原代码 问题 答案 探寻步骤 结论 原代码 const router = new VueRouter({ routes: [{ path: '/foo', ...
  • vue-iview异步加载渲染树

    千次阅读 2018-12-14 11:27:41
    Tree v-show=“curType==‘archive’” :data=“archiveTree” :load-data=“loadData” @on-select-change=“selectChange” :show-check=“false”&amp;amp;gt; data () { return { archiveTree:[],树的...
  • treeTable页面 ... ... $attrs" style="width: 100%;... <el-table-column v-if="selection" type="selection"></el-table-column> ... ... 实现table表格树结构,异步加载,不断追加子级。
  • ElementUI实现异步加载

    千次阅读 2019-08-20 14:21:44
    路由文件修改 import List from '@/components/list.vue' import Add from '@/components/add...import Tree from '@/components/tree.vue' import AsynTree from '@/components/asyntree.vue' export default{ ro...
  • 前言:最近使用element开发项目,在使用异步树时(即添加了lazy),翻阅了官方提供的文档,并未找到可直接提供给开发者使用的刷新某个树节点的方法(即增加某个树节点或修改某个树节点后无法实现实时刷新整棵树或刷新...
  • 官方文档比较全面,这里我就自己的实际开发提供一个案例,刚刚接触前端,不足... lazy //开启懒加载 show-checkbox //是否开启复选框 > </el-tree> <script> export default { data() { return {
  • ant table 中树形数据 异步加载

    千次阅读 2020-11-17 15:44:09
    ps:ant design tree有封装好的异步加载方式,table没有,因此自己写了 问题描述: ant design table 树形数据加载,数据量过大,采用异步加载方式 原因分析: 数据量过大,导致渲染速度慢,且很容易崩溃 解决...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,324
精华内容 1,729
关键字:

treevue异步加载

vue 订阅