这可能是最简单的一棵树了.
树菜单效果图预览
分析交互
这棵树的交互像已有的哪个组件? 折叠菜单? 点击显示,点击隐藏. 只是折叠菜单只有一层, 树有无限层.
折叠菜单效果预览
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.define
loader.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"></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);
})
更多使用, 请查看组件章节.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。