vue项目-封装树形控件公用组件
-
vue项目中,如h5端,第三方的树形选择器无法满足项目开发时,原生封装tree控件,通过判断是否存在子节点,循环递归组件完成树形封装,通过vue指令实现跨级传递数据或方法
封装树形组件如下:
1
2
3
4
39
40
41
42 :list="item.children"
43 v-bind="$props"
44 :selectIds.sync="selectedKeys"
45 v-if="item.children && expandedKeys.includes(item.key)"
46 style="padding-left: 16px"
47 v-on="$listeners"
48 >
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 export default {
66 name: 'TreeSelect',
67 props: {
68 // 传入的树形结构数据
69 list: {
70 type: Array,
71 default() {
72 return [];
73 }
74 },
75 // 选中的选项
76 selectedIds: {
77 type: Array,
78 default() {
79 return [];
80 }
81 }
82 },
83 data() {
84 return {
85 listMap: {}, // 数组对象
86 treeData: [], // 数据
87 selectedKeys: [], // 选中的keys
88 expandedKeys: [] // 展开的keys
89 };
90 },
91 watch: {
92 // 监听选中项改变
93 selectedIds(val) {
94 this.selectedKeys = val;
95 }
96 },
97 created() {
98 this.treeData = this.list;
99 this.selectedKeys = this.selectedIds;
100 },
101 methods: {
102 hanlderOpen(data) {
103 if (!data.children) return;
104 // 展开/收起 树形控件,请求数据
105 const targ = this.expandedKeys.includes(data.key);
106 if (!targ) {
107 // 展开项数组中无对应数据,则为展开操作
108 this.expandedKeys = [...this.expandedKeys, data.key];
109 } else {
110 //反之,收起操作
111 this.expandedKeys = this.expandedKeys.filter((item) => item !== data.key);
112 }
113 // 展开/收起抛出方法,用于父级操作数据
114 this.$emit('expand', targ, this.expandedKeys, data);
115 },
116 selectItem(data) {
117 // 选择操作,与展开/收起逻辑相同
118 const targ = this.selectedKeys.includes(data.key);
119 if (!targ) {
120 this.selectedKeys.push(data.key);
121 } else {
122 this.selectedKeys = this.selectedKeys.filter((item) => item !== data.key);
123 }
124 // 抛出选择方法
125 this.$emit('selectKeys', this.selectedKeys);
126 }
127 }
128 };
129
130
131
132 .tree-select-page {
133 background: #fff;
134 .tree-item-line {
135 height: 1px;
136 width: calc(100% - 8px);
137 margin-left: 8px;
138 background: #eaeaea;
139 position: absolute;
140 bottom: 0;
141 left: 0;
142 right: 0;
143 }
144 .tree-item-options {
145 padding: 8px 15px 8px 8px;
146 display: flex;
147 align-items: center;
148 justify-content: space-between;
149 position: relative;
150
151 .tree-item-left {
152 display: flex;
153 align-items: center;
154 width: calc(100% - 24px);
155 .tree-item-icon {
156 margin-right: 8px;
157 width: 24px;
158 img {
159 width: 24px;
160 height: 24px;
161 }
162 }
163 .tree-item-img {
164 height: 40px;
165 width: 40px;
166 margin-right: 16px;
167 }
168 .ml-8 {
169 margin-left: 8px;
170 }
171 .ml-16 {
172 margin-left: 16px;
173 }
174 .tree-item-content {
175 text-align: left;
176 flex-grow: 1;
177 overflow: hidden;
178 .tree-item-title {
179 font-size: 18px;
180 color: #2f2f2e;
181 line-height: 24px;
182 font-weight: 500;
183 overflow: hidden;
184 width: 100%;
185 text-overflow: ellipsis;
186 white-space: nowrap;
187 }
188 .tree-item-desc {
189 margin-top: 4px;
190 font-size: 14px;
191 color: #999999;
192 line-height: 16px;
193 font-weight: 400;
194 overflow: hidden;
195 text-overflow: ellipsis;
196 display: -webkit-box;
197 -webkit-line-clamp: 3;
198 -webkit-box-orient: vertical;
199 }
200 }
201 }
202 }
203 }
204 :deep(.ok-checkbox.ok-checkbox-checked .ok-checkbox-inner) {
205 // border-color: #07c160;
206 // background: #07c160;
207 border-color: var(--feature-color-primary);
208 background: var(--feature-color-primary);
209 }
210
父级组件:(部分代码)
1
2 :list="treeData"
3 :selectedIds="selectedKeys"
4 @selectKeys="treeSelectKeys"
5 @expand="expandTree"
6 >
7
自定义说明书8
11
12
提交树形控件选中父组件传给子组件的数据
1 // 树形控件选择器
2 selectedIds: [],
3 selectedKeys: [],
4 treeData: [
5 {
6 title: '一一级',
7 key: 'one-one-key',
8 desc: '说明书',
9 children: [
10 {
11 title: '一二级',
12 key: 'one-two-key',
13 children: [
14 {
15 title: '一三级',
16 key: 'one-three-key'
17 }
18 ]
19 }
20 ]
21 },
22 {
23 title: '二一级',
24 key: 'two-one-key',
25 desc: '说明书',
26 children: [
27 {
28 title: '二二级',
29 key: 'two-two-key',
30 children: [
31 {
32 title: '二三级',
33 key: 'two-three-key'
34 }
35 ]
36 }
37 ]
38 }
39 ],
方法的调用,数据回传显示
1 treeSelectKeys(ids) {
2 this.selectedKeys = ids;
3 console.log('this.selectedKeys--', this.selectedKeys);
4 console.log('tree调用---keys---回传', this.selectedKeys);
5 },
6 expandTree(targ, keys, data) {
7 console.log('expandTree---', targ, keys, data);
8 if (targ) {
9 // 收起
10 } else {
11 // 展开
12 }
13 },
14 submitTreeSelect() {
15 // 树形控件提交
16 console.log('submitTreeSelect---', this.selectedKeys);
17 },
实现的效果如下: