这可能是最简略的一棵树了.

树菜单效果图预览

剖析交互

这棵树的交互像已有的哪个组件? 折叠菜单? 点击显示,点击暗藏. 只是折叠菜单只有一层, 树有有限层.

折叠菜单成果预览

BUI的组件都是只定义了交互, 其它给予了比拟大的设想空间. 比方: 折叠面板, 新闻详情的查看更多

折叠面板成果

新闻详情的查看更多成果

树的实现

如果折叠菜单进行多层嵌套, 实践上就能够实现树的成果, 再把图标进行批改, 就是咱们要的了.

折叠面板结构

<dl id="uiAccordion" class="bui-accoridon">    <dt>菜单1</dt>    <dd>内容1</dd>    <dt>菜单2</dt>    <dd>内容2</dd></dl>

构造进行嵌套.

<dl id="uiAccordion" class="bui-accoridon">    <dt>菜单1</dt>    <dd>        <dl class="bui-accoridon">            <dt>菜单1-1</dt>            <dd>内容1</dd>            <dt>菜单1-2</dt>            <dd>内容2</dd>        </dl>    </dd>    <dt>菜单2</dt>    <dd>内容2</dd></dl>
// 初始化代码无需批改var uiAccordion = bui.accordion({    id: "#uiAccordion"})

通过测试是可行的, 那这个再把它组件化, 组件化的目标是为了更简略不便的复用.

组件化

这里联合store进行数据绑定. 批改后的款式构造.

新建html文件 pages/components/tree/index.html

<style>    .bui-tree .bui-accordion{        border-top: 0;        border-bottom: 0;        padding-left: .2rem;    }    .bui-tree .bui-accordion dd{        padding-left: .3rem;    }    .bui-tree .bui-accordion dt:last-child{        border-bottom: 0;    }    .bui-tree .bui-accordion dd{        border-top: 0;    }    .bui-tree .bui-accordion dd:last-child{        border-bottom: 0;    }    .bui-tree .bui-btn .icon-nosubmenu ,    .bui-tree .bui-btn .icon-accordion {        margin-right: .2rem;    }    .bui-tree .bui-btn > .icon-accordion:before{        content:"\e61e"    }    .bui-tree .active > .icon-accordion:before{        content:"\e620"    }</style><dl class="bui-accordion bui-tree" b-template="tree.tplTrees(tree.trees)">    <!-- 保留原有的构造正文, 便于模板了解         <dt class="bui-btn bui-box">        <div class="span1">折叠菜单</div>        <i class="icon-accordion"></i>    </dt>    <dd>        折叠菜单内容    </dd> --></dl>

新建一个js文件 pages/components/tree/index.js

// 组件化必须加上 loader.defineloader.define(function(require, exports, module) {    // 假如树的数据层级构造是这样, 以下是模仿数据    var data = [        {id: 1, name: "办公治理", pid: 0 ,            children:[                { id: 2, name: "销假申请", pid: 1,                    children:[                        { id: 4, name: "销假记录", pid: 2 },                    ],                },                { id: 3, name: "出差申请", pid: 1},            ]        },        {id: 5, name: "零碎设置", pid: 0 ,            children:[                { id: 6, name: "权限治理", pid: 5,                    children:[                        { id: 7, name: "用户角色", pid: 6 },                        { id: 8, name: "菜单设置", pid: 6 },                    ]                },            ]        },    ]    // 初始化数据行为存储, 接管内部参数的 data数组, 如果没有则展现默认数据, mounted外面只是初始化了一次accordion, 但本来的id,换成了 `#${module.id} .bui-accordion` , module.id是内部component标签的id, 没有会主动生成.     // 留神: module.props 是1.6.3的用法,能够应用 var props = bui.history.getPageParams(module.id) 代替.    var bs = bui.store({        el: `#${module.id}`,        scope: "tree",        data: {           trees: module.props && module.props.data || data,        },        methods: {},        templates: {            tplTrees: function (data,pclass) {                var html="";                data.forEach((item, index) => {                    let hasChildren=item&&item.children&&item.children.length;                    // 是否有下一级图标                    let hasChildrenIcon=hasChildren? `<i class="icon-accordion"></i>`:`<i class="icon-nosubmenu">&#xe620;</i>`;                    // 没有下一级展现向右的箭头                    let hasChildrenNext=hasChildren? ``:`<i class="icon-listright"></i>`;                    // 不同层级加上父级款式                    let level= (pclass||"bui-tree-level") + `-${index}`;                    html+=`<dt class="bui-btn bui-box ${level}">                                ${hasChildrenIcon}                                <div class="span1">${item.name}</div>                            </dt>`                    // 如果有子集菜单持续递归生成                    if (hasChildren) {                        html+=`<dd class="${level}"><dl class="bui-accordion">`;                        html+=this.tplTrees(item.children,level);                        html+=`</dl></dd>`;                    }                });                                return html;            }        },        mounted: function () {            // 初始化折叠插件            var uiAccordion = bui.accordion({                id: `#${module.id} .bui-accordion`,                callback: function (e) {                    // 点击的时候触发了一次click事件, 如果内部有订阅这个事件,就会被触发.                     loader.trigger(`${module.id}:click`,e)                }            });        }    })    return bs;})

组件的预览

bui的组件是能够实时预览的, 间接关上 index.html#pages/components/tree/index 就能够预览以后组件成果, 加上?data=xxx能够传组件须要的参数进行模仿, 没有则应用默认数据;

组件的应用

<div class="bui-page bui-box-vertical">    <header>        <div class="bui-bar">            <div class="bui-bar-left">                <a class="bui-btn btn-back"><i class="icon-back"></i></a>            </div>            <div class="bui-bar-main">树菜单</div>            <div class="bui-bar-right">            </div>        </div>    </header>    <main>        /* 这类组件的数据个别是通过异步申请后而来, 所以不能间接写在属性上 */        <component id="tree" name="pages/components/tree/index" delay="true"></component>    </main></div>
// 模仿申请bui.ajax({    url:""}).then(function(result){    // 假如树的数据在 result.data    // 加载树组件    loader.delay({        id:"tree",        param: {            data:result.data        }    })})

监听树点击事件

loader.on("tree:click",function(e){    // e 为 loader.trigger 传过来的参数. 能够通过 e.target 晓得以后点击的是哪个dom    console.log(e.target);})

更多应用, 请查看组件章节.

最终成果: