美文网首页
递归组合树状结构以及递归组件应用

递归组合树状结构以及递归组件应用

作者: writeanewworld | 来源:发表于2018-08-03 15:48 被阅读0次

1.需求:
数据库中有一张表,表名为itemType,记录的是商品类型,其中有一个字段是父级id,对应的也是本表中的id字段,所以这里类型数据应该是以一种树装结构json来显示的。

结构如图:

image.png image.png

2.json结构图:

image.png

转化后:

image.png

3.控制层代码:(递归)
递归这玩意不懂别去强行理解,多写多练,别指望一次就会用。用的多了自然就会明白了,要不然就直接看源码。

1).初始数据=>  List<ItemType>  itemTypes = ...
2).json格式拼装方法:
    private List<Map<String,Object>>  covertToTree(List<ItemType> itemTypes){
        Map<Integer,ItemType> typeMap = new HashMap<>();
        for(ItemType type:itemTypes){
              typeMap.put(type.getId(),type);
        }
        return recursionCovertToTree(null,typeMap); 
    }

    private recursionCovertToTree(Integer parentId,Map<Integer,ItemType> typeMap){
        List<Map<String,Object>> list = new ArrayList<>();
        for(Integer key : typeMap){
             //通过key拿到单个ItemType实例 
             ItemType type = typeMap.get(key);
             if((parentId==null && type.getParentId()==null) || ()){
                 Map<String,Object> entity = new HashMap<>();
                 entity.put("type",type);
                 List<Map<String,Object>>  children = recursionCovertToTree(type.getId(),typeMap);
                 entity.put("children",children);
                 list.add(entity) ;
             }
        }
          return list;
    }

4.vue递归组件应用场景:


image.png

选择一个类型,如果这个类型有父级就会接着选择。


image.png

无父级之后:

image.png

5.页面布局:

  <div class="form-group" style="width:500px !important;">
  
                <!-- todo -->
                <label>商品类型</label>
                <div id="item-type-container">
                    <item-type v-bind:options="tree" v-bind:id-path="path" v-bind:id-pos="0"></item-type>
                </div>
                
</div>

组件:

Vue.component('item-type', {
template: "" +
"<div style='display: inline-block;'>\n" +
"    <select @change='change($event.target.value)' :disabled='disabled' v-if='showSelector'>\n" +
"        <option value='-1'>请选择</option>\n" +
"        <option v-for='opt in options' :key='opt.type.id' :value='opt.type.id' :selected='idPath[idPos] == opt.type.id'>{{opt.type.typeName}}</option>\n" +
"    </select>\n" +
"    <item-type v-if='childOptions && childOptions.length !== 0' :options='childOptions' :id-path='idPath' :id-pos='idPos + 1' :disabled='disabled'></item-type>\n" +
"</div>",
props: ['options', 'idPath', 'idPos', 'disabled'],
data: function () {
    return {
        childOptions: []
    }
},
computed: {
    showSelector: function () {
        if (!this.disabled) {
            return true
        }
        var curId = this.idPath[this.idPos]
        for (var i = 0, len = this.options.length; i < len; ++i) {
            if (this.options[i].type.id == curId) {
                return true
            }
        }
        return false
    }
},
methods: {
    change: function (id) {
        for (var i = 0, len = this.options.length; i < len; ++i) {
            var opt = this.options[i]
            if (opt.type.id == id) {
                this.$set(this.idPath, this.idPos, id)
                this.childOptions = opt.children
                return
            }
        }
        this.childOptions = []
        this.idPath.splice(this.idPos)
    }
},
mounted: function () {
    this.change(this.idPath[this.idPos])
}
});

实例:

function createItemTypeSelector(id, itemTypeId, itemTypes, onItemTypeChanged) {
new Vue({
    el: id,
    data: function() {
        var path = [];
        this.getPath(path, itemTypeId, itemTypes);
        return {
            tree: itemTypes,
            itemTypeId: itemTypeId,
            path: path
        }
    },

    watch: {
        path: function (value) {
            typeof onItemTypeChanged === 'function' && onItemTypeChanged(value[value.length - 1])
        }
    },

    methods: {
        getPath: function (path, typeId, children) {
            for (var i = 0, len = children.length; i < len; ++i) {
                var child = children[i]
                if (this.getPath(path, typeId, child.children)) {0
                    path.unshift(child.type.id)
                    return true
                } else if (child.type.id == typeId) {
                    path.unshift(child.type.id)
                    return true
                }
            }
            return false
        }
    }
});
}

相关文章

  • 递归组合树状结构以及递归组件应用

    1.需求:数据库中有一张表,表名为itemType,记录的是商品类型,其中有一个字段是父级id,对应的也是本表中的...

  • 树状结构和扁平结构的相互转换(js, javascript,df

    1. 树状结构转换成扁平结构 有如下树状结构 实现效果 使用dfs遍历 递归 非递归 使用bfs遍历 层序遍历 2...

  • oracle树形结构层级查询之start with ....co

    浅谈oracle树状结构层级查询 原文地址:浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查...

  • vue 组件递归

    组件递归常用到的栗子就比如树形结构的创建,需要自调用进行递归渲染下面是递归组件渲染tree的效果图: 2.调用组件...

  • Composite模式(结构型)

    在开发中,我们经常可能要递归构建树状的组合结构,Composite模式则提供了很好的解决方案。 Composite...

  • python数据结构教程 Day6

    python数据结构教程 Day6 本节重点 递归定义 递归调用的实现 简单递归的应用 一、递归 在python基...

  • vue递归组件自定义事件

    关于递归组件只调用一次的问题,解决方案示例: 父组件:parent.vue 树状组件:components/tre...

  • VUE 树状选择 递归组件

    使用vue递归组件实现上一个多级的树状结构 先上图 demo链接 欢迎访问 获取到的数据 pid 表d示父节点的i...

  • Angular 工作原理

    Angular 应用,由组件构成,一颗由组件构成的树。由于组件是以树形结构组织起来的,当每个组件被渲染时,都会递归...

  • 14.递归组件与动态组件

    递归组件与动态组件 递归组件 递归组件就是指组件在模板中调用自己,开启递归组件的必要条件,就是在组件中设置一个 n...

网友评论

      本文标题:递归组合树状结构以及递归组件应用

      本文链接:https://www.haomeiwen.com/subject/xknyvftx.html