树形/树状组织结构
发表于:2024-09-13 14:00:28浏览:357次
引言
基于vue2-org-tree
组件结合html快速生成树状组织结构,只需复制以下代码加以微调即可,方便又快捷
效果图
模块
vue2-org-tree.zip
模块下载后放置:网站运行目录/assets/libs/
前端
<link href="/assets/libs/vue2-org-tree/vue2-org-tree@1.3.6.css" rel="stylesheet" />
<script src="/assets/libs/vue2-org-tree/vue@2.7.16.js"></script>
<script src="/assets/libs/vue2-org-tree/vue2-org-tree@1.3.6.js"></script>
<script src="/assets/libs/vue2-org-tree/axios@1.7.7.js"></script>
<!--【vue2文档】https://v2.cn.vuejs.org/v2/guide/installation.html-->
<!--【axios文档】http://www.axios-js.com/zh-cn/docs/-->
<style lang="scss">
.tree-node {
/*color: #FFFFFF;*/
/*background-color: orange;*/
padding: 0px!important;
}
#app {
width: 100%;
overflow:scroll;
}
</style>
<div class="" id="app">
<div class="org-tree">
<vue2-org-tree
:data="treeData"
:props="treeProps"
:label-class-name="treeLabelClassName"
:horizontal="horizontal"
:collapsable="collapsable"
:render-content="renderContent"
@on-node-mouseover="mouseoverTreeNode"
@on-node-mouseout="mouseoutTreeNode"
@on-node-click="onTreeNode"
@on-expand="onTreeExpand"
/>
</div>
</div>
<script>
new Vue({
name: 'OrgTree',
el: '#app',
data () {
return {
//horizontal:true=从左到右展示;false=从上到下展示
horizontal:false,
/**
* collapsable:true=显示展开或收缩;false=不显示展开或收缩
* 当collapsable=true时,数据中必须要有 expand 字段才会生效
* expand=true展开;expand=false收缩
*/
collapsable:true,
treeData:{},
treeProps:{
label:'label',
children:'children',
expand:'expand',
},
// style标签里不能加 scoped 不然自定义样式无效
treeLabelClassName:"tree-node",
}
},
created () {
const that = this
that.getTreeData(0).then((data)=>{
that.treeData = data
})
},
methods: {
// 获取数据
getTreeData(id){
// 执行API请求,这里数据写死
const that = this
return new Promise((resolve) => {
axios({
url:'tree_data',
method:'get',
params:{
id:id
},
headers:{
'content-type':'application/json'
}
})
.then(response => {
resolve(response.data);
})
.catch(error => {
console.error(error);
});
})
},
// 渲染方法,可以自己组装标签,类似vue的render方法
renderContent(h, node) {
let color_str = ""
if (node.is_vip) {
color_str = "color:#ff5722;"
}
return h('div', {}, [
h('p', {style:color_str+'margin:0px;border-bottom:1px solid #dddddd;padding:5px 10px;'}, node.label),
h('p', {style:'margin:0px;padding:5px 10px;font-size:14px;color:#c2c2c2;'}, '邀请:'+node.children_count+'人'),
]);
},
// 点击节点
onTreeNode(e, node) {
if (node.children_count > 0 && node.children.length == 0) {
const that = this
that.getTreeData(node.id).then((data)=>{
node.children = data
})
}
// console.log(node)
},
// 鼠标移入
mouseoverTreeNode(e, node) {
// console.log(node)
},
// 鼠标移出
mouseoutTreeNode(e, node) {
// console.log(node)
},
// 点击 展开 或 收缩
onTreeExpand(e, node) {
// console.log('点击 展开 或 收缩')
node.expand = node.expand == true ? false : true
}
}
})
</script>
后端
控制器
public function tree()
{
$this->layout = '';
return $this->view->fetch();
}
public function tree_data()
{
$id = $this->request->param('id',0);
$us = new \app\common\service\User();
$tree = $us->org($id,5);
if ($id == 0) {
$tree = [
'id' => 'top',
'value' => 'top',
'label' => '平台',
'expand'=>true,
'children'=>$tree,
'children_count'=>count($tree)
];
}
return json($tree);
}
逻辑
public function org($id,$level = 3)
{
if ($level == 0) {
return [];
}
$level--;
$model = new UserModel();
$list = $model->field('id,username as label,vip_id,vip_expire_time')->with('vip')->where('pid',$id)->select();
foreach ($list as &$user){
$user['expand'] = true;
$user['is_vip'] = $user['vip_id'] > 0;
$user['value'] = $user['id'];
$user['children'] = $this->org($user['id'],$level);
$user['children_count'] = $model->where('pid',$user['id'])->count();
}
return $list;
}