横向结构的树组件(leader-line-vue)
近期做项目时需要做一个横向的树结构的图,如下所示:
本图的实现采用了leader-line-vue组件,
具体实现如下:
先npm install leader-line-vue --save,安装依赖
然后,子组件RightTree的封装,代码如下:
1 <template>2 <div class="TreeRight" id="treeRight" v-if="showTree">
3 <div class="childs">
4 <div
5 class="child"
6 v-for="(item, index) in list"
7 :key="item.id + \'-child-\' + index"
8 >
9 <div
10 class="child-item"
11 :style="{
12 marginRight:
13 item.children && item.children.length > 1 ? \'20px\' : \'\',
14 }"
15 >
16 <div class="childname" :id="item">
17 <div class="content-box" :ref="item.id" :id="item.id">
18 {{ item.id }}
19 <p
20 v-for="(itemshow, index3) in showfields"
21 :key="\'itemshow\' + index3"
22 >
23 {{ itemshow.name }}{{ item[itemshow.key] }}
24 </p>
25 </div>
26 <div style="width: 30px"></div>
27 <div
28 class="position-top"
29 v-if="isFirst(item.id) && domready"
30 :style="position_top(item.id, \'top\')"
31 ></div>
32 <div
33 class="position-top"
34 v-if="isLast(item.id)"
35 :style="position_top(item.id, \'bottom\')"
36 ></div>
37 </div>
38 <div style="width: 160px"></div>
39 </div>
40 <!-- 递归组件展示子节点 -->
41 <div
42 class="child-children"
43 v-if="item.children && item.children.length"
44 >
45 <RightTree :list="item.children" :showfields="showfields" />
46 </div>
47 </div>
48 </div>
49 </div>
50 </template>
51
52 <script>
53 import LeaderLine from "leader-line-vue";
54 export default {
55 name: "RightTree",
56 components: {},
57 data() {
58 return {
59 domready: false,
60 lines: [],
61 };
62 },
63 created() {},
64 props: {
65 list: {
66 type: Array,
67 default: () => [],
68 },
69 showfields: {
70 type: Array,
71 default: () => [],
72 },
73 },
74 mounted() {
75 this.$nextTick(() => {
76 this.domready = true;
77 this.drawArrowLine();
78 });
79 },
80 computed: {
81 /**
82 * 是否展示树计算属性
83 */
84 showTree() {
85 return this.list && this.list.length;
86 },
87 },
88 beforeDestroy() {
89 /**
90 * 离开页面时销毁所有line
91 */
92 if (this.lines && this.lines.length) {
93 this.lines.forEach((line) => {
94 line.remove();
95 });
96 }
97 },
98 methods: {
99 /**
100 * 递归绘制箭头
101 */
102 drawArrowLine() {
103 this.drawLeaderLine(this.list);
104 document.getElementById("treeRight").addEventListener("scroll", () => {
105 if (this.lines && this.lines.length) {
106 this.lines.forEach((line) => {
107 line.position();
108 });
109 }
110 });
111 },
112 /**
113 * 根据上下级关系绘制线条
114 */
115 drawLeaderLine(list) {
116 list.forEach((element) => {
117 let start = document.getElementById(element.id);
118 if (element.children && element.children.length) {
119 element.children.forEach((child) => {
120 let line = LeaderLine.setLine(
121 start,
122 document.getElementById(child.id)
123 );
124 line.color = "#7F7F7F";
125 line.path = "fluid";
126 line.size = 1;
127 line.setOptions({
128 solid: { animation: true },
129 });
130 this.lines.push(line);
131 });
132 this.drawLeaderLine(element.children);
133 }
134 });
135 },
136 position_top(id, position) {
137 let dom = document.getElementById(id);
138 let height;
139 if (dom) {
140 height = dom.clientHeight;
141 }
142 let rt;
143 if (position === "top") {
144 rt = {
145 height: height / 2 - 2 + "px",
146 top: 0,
147 };
148 }
149 if (position === "bottom") {
150 rt = {
151 height: height / 2 + 1 + "px",
152 bottom: 0,
153 };
154 }
155 return rt;
156 },
157 isFirst(id) {
158 return (
159 this.list.length > 1 && this.list.map((x) => x.id).indexOf(id) === 0
160 );
161 },
162 isLast(id) {
163 return (
164 this.list.length > 1 &&
165 this.list.map((x) => x.id).indexOf(id) === this.list.length - 1
166 );
167 },
168 },
169 };
170 </script>
171
172 <style lang="scss" scoped>
173 .TreeRight {
174 width: 100%;
175 height: 100%;
176 overflow: auto;
177 p {
178 margin: 0;
179 font-size: 13px;
180 }
181 display: flex;
182 .father {
183 width: 70px;
184 background-color: red;
185 padding: 100px 10px;
186 }
187 .childs {
188 .child {
189 display: flex;
190 background-color: #fff;
191 .child-item {
192 display: flex;
193 align-items: center;
194 margin: 10px 0;
195 .childname {
196 .content-box {
197 text-align: left;
198 border: 1px solid #e8e8e8;
199 padding: 10px;
200 height: 100px;
201 border-radius: 2px;
202 width: 100%;
203 box-shadow: 0 2px 4px 0 rgba(181, 181, 181, 0.7);
204 }
205 cursor: pointer;
206 height: 100%;
207 display: flex;
208 align-items: center;
209 width: 220px;
210 text-align: center;
211 justify-content: center;
212 position: relative;
213 padding: 10px 0;
214 .position-arrow {
215 position: absolute;
216 left: -22px;
217 }
218 .position-top {
219 position: absolute;
220 width: 3px;
221 background-color: #fff;
222 left: -23px;
223 height: 10px;
224 }
225 }
226 .childarrow {
227 height: 100%;
228 display: flex;
229 align-items: center;
230 }
231 }
232 }
233 .child-children {
234 display: flex;
235 flex-direction: column;
236 justify-content: center;
237 }
238 }
239 }
240 </style>
View Code
父亲组件引用方式如下:
1 <template>2 <div>
3 <right-tree
4 v-if="list && list.length"
5 :list="list"
6 :showfields="showFields"
7 ></right-tree>
8 </div>
9 </template>
10 <script>
11 import RightTree from \'../components/RightTree\'
12 export default {
13 components:{
14 RightTree,
15 },
16 data(){
17 return{
18 list: [//datasource
19 {
20 id: \'1\',
21 name: \'span1\',
22 serviceId: \'service1\',
23 children: [
24 {
25 id: \'1-1\',
26 name: \'user\',
27 serviceId: \'service-user\',
28 children: [
29 {
30 id: \'1-1-1\',
31 name: \'shop\',
32 serviceId: \'18\',
33 children: [
34 {
35 id: \'1-1-1-1\',
36 name: \'common\',
37 serviceId: \'common-service\',
38 },
39 ],
40 },
41 {
42 id: \'1-1-2\',
43 name: \'account1\',
44 serviceId: \'account-service\',
45 },
46 {
47 id: \'1-1-3\',
48 name: \'account2\',
49 serviceId: \'account-service\',
50
51 },
52 {
53 id: \'1-1-4\',
54 name: \'account3\',
55 serviceId: \'account-service\',
56 },
57 ],
58 },
59 {
60 id: \'1-2\',
61 name: \'truck\',
62 serviceId: \'truck-pay\',
63 work: \'web\',
64 },
65 ],
66 },
67 ],
68 showFields: [
69 {
70 name: \'服务名称:\',
71 key: \'name\',
72 },
73 {
74 name: \'服务编号:\',
75 key: \'serviceId\',
76 },
77 ],
78 }
79 },
80 methods:{
81
82 },
83
84 }
85 </script>
View Code
其实就是用leader-line-vue绘制了引导线,leader-line-vue的功能还是蛮强大的,想了解更深,可以参考官网:https://www.npmjs.com/package/leader-line-vue
以上是 横向结构的树组件(leader-line-vue) 的全部内容, 来源链接: utcz.com/z/376249.html