• vue的自定义树形列表组件(及数据格式转换)


     
    • 组件定义

    子组件:

    <template>
    <div>
    <!-- <h5>{{temp.tital}}</h5> -->
    <el-button class="filter-item" style="margin-left: 1px;" size="small" type="primary" >{{temp.tital}}</el-button>
    <el-input
    size="small"
    placeholder="输入关键字过滤分类"
    v-model="filterText">
    </el-input>
     
    <el-tree
    class="filter-tree"
    :data="treeData"
    :props="defaultProps"
    :node-key="id"
    default-expand-all
    :filter-node-method="filterNode"
    ref="tree2"
    @node-click="sendData"
    >
    </el-tree>
    </div>
    </template>
    <script>
    export default {
    watch: {
    filterText(val) {
    this.$refs.tree2.filter(val);
    }
    },
    methods: {
    filterNode(value, data) {
    if (!value) return true;
    return data.name.indexOf(value) !== -1;
    },
    setTreeData(datass){//接收父组件的参数
    this.temp.tital = datass.tital
    this.treeData = datass;
    },
    sendData(obj, node, data){//向父组件发送参数
    this.$emit("sendTreeData", obj)//"sendTreeData"这是父组件引用时定义的
     
    }
    },
    data() {
    return {
    temp:{
    tital:"哈哈哈"
    },
    filterText: '',
    data2: [{//这是tree型数据格式
    id: 1,
    label: '一级 1',
    children: [{
    id: 4,
    label: '二级 1-1',
    children: [{
    id: 9,
    label: '三级 1-1-1'
    }, {
    id: 10,
    label: '三级 1-1-2'
    }]
    }]
    }, {
    id: 2,
    label: '一级 2',
    children: [{
    id: 5,
    label: '二级 2-1'
    }, {
    id: 6,
    label: '二级 2-2'
    }]
    }, {
    id: 3,
    label: '一级 3',
    children: [{
    id: 7,
    label: '二级 3-1'
    }, {
    id: 8,
    label: '二级 3-2'
    }]
    }],
    treeData:[],
    defaultProps: {
    children: 'children',
    label: 'name'
    }
    };
    }
    };
    </script>
     
    父组件调用子组件
    <Mytreetable ref="mytreedata" v-model="temp.icon" @sendTreeData="sendTreeObj" />
     
    import Mytreetable from '@/components/MyTreeTable/index'
     
    export default {
    name: 'ComplexTable',
    components: { Mytreetable },
     
    //向子组件传递数据
    this.$refs.mytreedata.setTreeData(treesss);
     
    • 以下内容为普通扁平化格式转换成树形对象的方法
    • 其中list的格式为
    • [
      {
      "id": 100,
      "pId": 0,
      "name": "科技",
      "title": "科技",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 101,
      "pId": 100,
      "name": "深圳总公司",
      "title": "深圳总公司",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 102,
      "pId": 100,
      "name": "长沙分公司",
      "title": "长沙分公司",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 103,
      "pId": 101,
      "name": "研发部门",
      "title": "研发部门",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 104,
      "pId": 101,
      "name": "市场部门",
      "title": "市场部门",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 105,
      "pId": 101,
      "name": "测试部门",
      "title": "测试部门",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 106,
      "pId": 101,
      "name": "财务部门",
      "title": "财务部门",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 107,
      "pId": 101,
      "name": "运维部门",
      "title": "运维部门",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 108,
      "pId": 102,
      "name": "市场部门",
      "title": "市场部门",
      "checked": false,
      "open": false,
      "nocheck": false
      },
      {
      "id": 109,
      "pId": 102,
      "name": "财务部门",
      "title": "财务部门",
      "checked": false,
      "open": false,
      "nocheck": false
      }
      ]

    • buildTree(list){
      let pidStr = 'pId';
      let idStr = 'id';
      let childrenStr = 'children';

      let listOjb = {}; // 用来储存{key: obj}格式的对象
      let treeList = []; // 用来储存最终树形结构数据的数组

      // 将数据变换成{key: obj}格式,方便下面处理数据
      for (let i = 0; i < list.length; i++) {
      listOjb[list[i][idStr]] = list[i]
      }

      for (let j = 0; j < list.length; j++) {
      // 判断父级是否存在
      let haveParent = listOjb[list[j][pidStr]]
      if (haveParent) {
      // 如果有没有父级children字段,就创建一个children字段
      !haveParent[childrenStr] && (haveParent[childrenStr] = [])
      // 在父级里插入子项
      haveParent[childrenStr].push(list[j])
      } else {
      // 如果没有父级直接插入到最外层
      treeList.push(list[j])
      }
      }
      return treeList
      },
     
     
    另一种扁平化转树形格式的转换方式(据说效率极高,有兴趣的可以试试)
     

    实现算法buildTree

    算法思想:

    先将数组中的每一个节点放到temp对象中(创建map)
    即数组中有{id: '2-3', parent_id: '2',...}这样一个节点,需要将他放到temp中变成 '2-3': {id: '2-3', parent_id: '2',...}这种JSON结构
    直接遍历整个temp对象,通过这句代码   temp[temp[i].parent_id].children[temp[i].id] = temp[i];   将当前子节点与父节点建立连接。是因为我们保证了父节点一定在子节点前,那么当子节点出现的时候就直接可以用temp[temp[i].parent_id]来查找到父节点这个时候先父节点的children对象中添加一个引用即可。
    /**
    * 将一维的扁平数组转换为多层级对象
    * @param {[type]} list 一维数组,数组中每一个元素需包含id和parent_id两个属性
    * @return {[type]} tree 多层级树状结构
    */
    function buildTree(list){
    let temp = {};
    let tree = {};
    for(let i in list){
    temp[list[i].id] = list[i];
    }
    for(let i in temp){
    if(temp[i].parent_id) {
    if(!temp[temp[i].parent_id].children) {
    temp[temp[i].parent_id].children = new Object();
    }
    temp[temp[i].parent_id].children[temp[i].id] = temp[i];
    } else {
    tree[temp[i].id] = temp[i];
    }
    }
    return tree;
    }
    测试结果:

    可以看到函数成功地构建了多级的树状结构

    这个算法的效率是极高的,比多重for循环来的好得多。

    以下是测试数据,用时只需5毫秒左右:


    var menu_list = [{
    id: '1',
    menu_name: '设置',
    menu_url: 'setting',
    parent_id: 0
    }, {
    id: '1-1',
    menu_name: '权限设置',
    menu_url: 'setting.permission',
    parent_id: '1'
    }, {
    id: '1-1-1',
    menu_name: '用户管理列表',
    menu_url: 'setting.permission.user_list',
    parent_id: '1-1'
    }, {
    id: '1-1-2',
    menu_name: '用户管理新增',
    menu_url: 'setting.permission.user_add',
    parent_id: '1-1'
    }, {
    id: '1-1-3',
    menu_name: '角色管理列表',
    menu_url: 'setting.permission.role_list',
    parent_id: '1-1'
    }, {
    id: '1-1-4',
    menu_name: '角色管理新增',
    menu_url: 'setting.permission.role_add',
    parent_id: '1-1'
    }, {
    id: '1-2',
    menu_name: '菜单设置',
    menu_url: 'setting.menu',
    parent_id: '1'
    }, {
    id: '1-2-1',
    menu_name: '菜单列表',
    menu_url: 'setting.menu.menu_list',
    parent_id: '1-2'
    }, {
    id: '1-2-2',
    menu_name: '菜单添加',
    menu_url: 'setting.menu.menu_add',
    parent_id: '1-2'
    }, {
    id: '2',
    menu_name: '订单',
    menu_url: 'order',
    parent_id: 0
    }, {
    id: '2-1',
    menu_name: '报单审核',
    menu_url: 'order.orderreview',
    parent_id: '2'
    }, {
    id: '2-2',
    menu_name: '退款管理',
    menu_url: 'order.refundmanagement',
    parent_id: '2'
    }, {
    id: '2-3',
    menu_name: '实物订单',
    menu_url: 'order.realorder',
    parent_id: '2'
    }, {
    id: '2-1-1',
    menu_name: '全部报单',
    menu_url: 'order.orderreview.all',
    parent_id: '2-1'
    }, {
    id: '2-2-1',
    menu_name: '所有记录',
    menu_url: 'order.refundmanagement.all',
    parent_id: '2-2'
    }, {
    id: '2-2-2',
    menu_name: '待处理',
    menu_url: 'order.refundmanagement.wait',
    parent_id: '2-2'
    }, {
    id: '2-2-3',
    menu_name: '退款原因',
    menu_url: 'order.refundmanagement.result',
    parent_id: '2-2'
    }, {
    id: '2-3-1',
    menu_name: '实物订单管理',
    menu_url: 'order.realorder.list',
    parent_id: '2-3'
    }, {
    id: '3',
    menu_name: '商品',
    menu_url: 'commodity',
    parent_id: 0
    }, {
    id: '3-1',
    menu_name: '分类管理',
    menu_url: 'commodity.classifieldmanagement',
    parent_id: '3'
    }, {
    id: '3-1-1',
    menu_name: '管理',
    menu_url: 'commodity.classifieldmanagement.management',
    parent_id: '3-1'
    }, {
    id: '3-1-2',
    menu_name: '编辑或新增',
    menu_url: 'commodity.classifieldmanagement.edit',
    parent_id: '3-1'
    }, {
    id: '3-2',
    menu_name: '品牌管理',
    menu_url: 'commodity.brandmanagement',
    parent_id: '3'
    }, {
    id: '3-2-1',
    menu_name: '管理',
    menu_url: 'commodity.brandmanagement.management',
    parent_id: '3-2'
    }, {
    id: '3-2-2',
    menu_name: '编辑或新增',
    menu_url: 'commodity.brandmanagement.edit',
    parent_id: '3-2'
    }, {
    id: '3-3',
    menu_name: '商品管理',
    menu_url: 'commodity.commoditymanagement',
    parent_id: '3'
    }, {
    id: '3-3-1',
    menu_name: '管理',
    menu_url: 'commodity.commoditymanagement.management',
    parent_id: '3-3'
    }, {
    id: '3-3-2',
    menu_name: '编辑或新增',
    menu_url: 'commodity.commoditymanagement.edit',
    parent_id: '3-3'
    }, {
    id: '3-4',
    menu_name: '类型管理',
    menu_url: 'commodity.typeManagement',
    parent_id: '3'
    }, {
    id: '3-4-1',
    menu_name: '管理',
    menu_url: 'commodity.typeManagement.management',
    parent_id: '3-4'
    }, {
    id: '3-4-2',
    menu_name: '编辑或新增',
    menu_url: 'commodity.typeManagement.edit',
    parent_id: '3-4'
    }]

     
     
     
     
     
     
  • 相关阅读:
    Spring 学习——Spring IOC概念
    Oracle使用——Oracle表空间处理
    Spring 学习——Spring框架结构、概念
    Java错误——The hierarchy of the type is inconsistent错误
    Git教程
    git 常用操作
    "use strict"; 的正确使用
    react学习笔记(二)React表单详解
    chrome 添加有用扩展程序
    react学习笔记(一)
  • 原文地址:https://www.cnblogs.com/braveLN/p/11196603.html
Copyright © 2020-2023  润新知