【封装Tree的思路】

封装Tree遇到的问题和知识点

1.怎么封装?
用数据自己去渲染组件


  {
    type:"rulename"
    children:[
        {
            type:"condition",
            children:[]
        },
        {
            type:"action",
            children:[]
        }
    ]
}
//组件遇到type就知道自己用哪个组件!

2.思路
TreeData--------> Tree------------>TreeNode

3.TreeNode的设计
最原始的TreeNode

  
{renderRoot} //渲染 第一个节点
{renderTreeNode} // 渲染留白区域
.treenode{
  width:100%;
  height:100%;
  i{
    margin-right: 5px !important;
    line-height: inherit;
  }
  span{
    width:200px;
    line-height: 23px;
  }
}

4.TreeNode的递归
思路:每一层只管自己的数据,如自己当前一层的type,key,value

TreeData: {
    type: 'rulename',
    key: '0',
    value: '',
    children: [
        {
            type:'ruleConditions',
            key: '0-0',
            value: '条件'
        },
        {
            type: 'action',
            key: '0-1',
            value: '实例'
        }
    ]
},

数据一进来,只有rulename,需要一个专门根据type来渲染组件的渲染变量

let renderComponent;
switch(type){
        case "rulename":
          renderComponent = (
123
) break; default: renderComponent=null break; }

遇到的问题 一开始写的递归

if(!!dataSource.children){
    dataSource.children.map(item=>{
         let {children,{...rest}}=item
          return 
        })
}

这样写会有一个问题 结合起来看

let { dataSource } =this.props
let {type,key,value}={...dataSource}; //children递归回来,已经没有type,key,value了
let renderRoot;
let renderTreeNode = [];
if(!!dataSource.children){
    renderTreeNode=dataSource.children.map(item=>{
         let {children,{...rest}}=item
            //{...rest} 里面包含的是我这一层需要的type,key,value
          return  
            //问题所在,children递归回去,没有我要的东西了
        })
}

switch(type){
        case "rulename":
          renderRoot = (
123
) break; default: renderRoot=null break; }
急需解决的问题:
1.children递归回来,没有type,key,value了,全部留在递归前的{...rest}了,怎么根据取出来去渲染呢?
2.renderRoot和renderTreeNode不能同时被渲染出来,rulename和ruleConditions,action没法共同渲染
3.而且children里面还有其他字段需要传递给组件,无法传出去给组件,继续完成递归

解决思路:
 1.我把type和children单独拿出来,其他参数我不管,传进传出,自己去传,自己去解构
 2.渲染需要两个变量来自动完成,一个变量渲染父节点,一个变量渲染子节点
 3.其余的数据结构里面的字段,全部传过去,自己去解构
我需要

1.一个专门负责递归的函数,并能渲染子组件的变量
(递归children的函数和渲染children的变量)

let { dataSource } =this.props
let {type,children,...rest}={...dataSource}; //把type和children单独拿出来
if(children){
          renderTreeNode=this.reduceChild(children,renderTreeNode)
}
  /**
    * @func reduceChild
    * @desc 如果有children,进行TreeNode递归,
    * @param ChildData    传过来的children数据
    * @param renderTreeNode 专门用来渲染子节点的数组,reduceChild要返回回去一个新的渲染数组
    */
    reduceChild(ChildData,renderTreeNode){
        return renderTreeNode=ChildData.map((item,index)=>{
          return 
        })

    }

遍历的时候需要个唯一的key,通过加index解决


遍历时报的错

2.一个专门负责根据type渲染组件的函数

let renderRoot;
renderRoot=this.JudgeType(type,{...rest}) //TreeData里的rulename
  /**
    * @func JudgeType
    * @desc          根据数据结构里的type字段渲染不同的组件
    * @param type    数据结构里面的type字段
    * @param rest    数据结构里面除了type外的其他字段内容,需要哪个字段,就解构出来
    */
    JudgeType(type,rest){
      let renderComponent;
      let {value,key}={...rest}
      switch(type){
        case "rulename":
          renderComponent = ()
          break;

        case "ruleConditions":
          renderComponent =()
          break;

        case "editCondition":
          renderComponent =()
          break;

        case "action":
          renderComponent =()
          break;

        case "actionInstance":
          renderComponent =()
          break;

        case "config":
          renderComponent =()
          break;

        case "Type":
          renderComponent =()
        break;

        default:
          renderComponent=null
        break;
      }
      return renderComponent;
    }

完整代码段

import React from 'react';
import './TreeNode.scss'
import '../EditComponent/index.scss'
import { Icon} from "@alife/next";
import InputInTree from "../EditComponent/InputInTree/InputInTree"
import Add from '../EditComponent/Add/Add'
import TwoInputAndSelectInTree from '../EditComponent/TwoInputAndSelectInTree/TwoInputAndSelectInTree'
import SelectInTree from "../EditComponent/SelectInTree/SelectInTree"
const deepClone=obj=>{
  return JSON.parse(JSON.stringify(obj))
}

class TreeNode extends React.Component {
    addCondition(addConditionkey){
      console.log(addConditionkey)
    }
    deleteItemCondition(deleteConditionKey){
      console.log(deleteConditionKey)
    }
    onInputChange(key,value){
      console.log(key,value)
    }
    /**
    * @func JudgeType
    * @desc          根据数据结构里的type字段渲染不同的组件
    * @param type    数据结构里面的type字段
    * @param rest    数据结构里面除了type外的其他字段内容,需要哪个字段,就解构出来
    */
    JudgeType(type,rest){
      let renderComponent;
      let {value,key}={...rest}
      switch(type){
        case "rulename":
          renderComponent = ()
          break;

        case "ruleConditions":
          renderComponent =()
          break;

        case "editCondition":
          renderComponent =()
          break;

        case "action":
          renderComponent =()
          break;

        case "actionInstance":
          renderComponent =()
          break;

        case "config":
          renderComponent =()
          break;

        case "Type":
          renderComponent =()
        break;

        default:
          renderComponent=null
        break;
      }
      return renderComponent;
    }
    /**
    * @func reduceChild
    * @desc 如果有children,进行TreeNode递归,
    * @param ChildData    传过来的children数据
    * @param renderTreeNode 专门用来渲染子节点的数组,reduceChild要返回回去一个新的渲染数组
    */
    reduceChild(ChildData,renderTreeNode){
        return renderTreeNode=ChildData.map((item,index)=>{
          return 
        })

    }
    /**
    * @func reduceChild
    * @desc TreeData一进来是一个对象,
            type要用来判断显示怎么样的组件,
            children要用来递归
            {...rest}里面包含了除了type和children的其他字段传给组件,
            比如:需要的value和key,传给自定义组件去使用
    * @param renderRoot     //专门负责渲染最上层的rulename
    * @param renderTreeNode //专门负责渲染子节点的数组
    */
    render() {
        let { dataSource } =this.props
        let {type,children,...rest}={...dataSource}; //把type和children单独拿出来
        let renderRoot;
        let renderTreeNode = [];
        if(children){
          renderTreeNode=this.reduceChild(children,renderTreeNode)
        }
        renderRoot=this.JudgeType(type,{...rest})//TreeData里的rulename

        return (
          
{renderRoot}
{renderTreeNode}
) } } export default TreeNode;

你可能感兴趣的:(【封装Tree的思路】)