横向结构的树组件(leader-line-vue)

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

回到顶部