hookehuyr

fix 树形选中组件代码整理

1 <!-- 1 <!--
2 * @Date: 2022-08-29 14:31:20 2 * @Date: 2022-08-29 14:31:20
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-05-31 11:32:37 4 + * @LastEditTime: 2024-05-31 17:09:02
5 * @FilePath: /data-table/src/components/TreeField/index.vue 5 * @FilePath: /data-table/src/components/TreeField/index.vue
6 * @Description: 树形组件 6 * @Description: 树形组件
7 --> 7 -->
...@@ -65,8 +65,7 @@ ...@@ -65,8 +65,7 @@
65 :showFooter="false" 65 :showFooter="false"
66 :cascade="false" 66 :cascade="false"
67 :defaultExpandAll="false" 67 :defaultExpandAll="false"
68 - @search="searchMethod" 68 + @checked-change="deptTreeCheckedChange"
69 - @checked-change="checkedChangeMethod"
70 style=" height: 60vh; overflow: scroll;" 69 style=" height: 60vh; overflow: scroll;"
71 > 70 >
72 <span slot="empty">暂无数据</span> 71 <span slot="empty">暂无数据</span>
...@@ -102,7 +101,7 @@ ...@@ -102,7 +101,7 @@
102 :expandOnFilter="false" 101 :expandOnFilter="false"
103 :showCheckedButton="false" 102 :showCheckedButton="false"
104 @update:modelValue="() => {}" 103 @update:modelValue="() => {}"
105 - @click="onNodeClick" 104 + @click="onUserTreeClick"
106 > 105 >
107 <span slot="empty">暂无数据</span> 106 <span slot="empty">暂无数据</span>
108 </Vtree> 107 </Vtree>
...@@ -141,7 +140,7 @@ ...@@ -141,7 +140,7 @@
141 <p>部门</p> 140 <p>部门</p>
142 <div> 141 <div>
143 <van-checkbox 142 <van-checkbox
144 - @click="onSearchDeptChange(dept, $event)" 143 + @click="onSearchResultClick(dept, $event)"
145 v-for="(dept) in user_dept_role.dept" 144 v-for="(dept) in user_dept_role.dept"
146 :id="dept.id" 145 :id="dept.id"
147 :type="dept.type" 146 :type="dept.type"
...@@ -157,7 +156,7 @@ ...@@ -157,7 +156,7 @@
157 <p>角色</p> 156 <p>角色</p>
158 <div> 157 <div>
159 <van-checkbox 158 <van-checkbox
160 - @click="onSearchRoleChange(role, $event)" 159 + @click="onSearchResultClick(role, $event)"
161 v-for="(role) in user_dept_role.role" 160 v-for="(role) in user_dept_role.role"
162 :id="role.id" 161 :id="role.id"
163 :type="role.type" 162 :type="role.type"
...@@ -173,7 +172,7 @@ ...@@ -173,7 +172,7 @@
173 <p>成员</p> 172 <p>成员</p>
174 <div> 173 <div>
175 <van-checkbox 174 <van-checkbox
176 - @click="onSearchUserChange(user, $event)" 175 + @click="onSearchResultClick(user, $event)"
177 v-for="(user) in user_dept_role.user" 176 v-for="(user) in user_dept_role.user"
178 :id="user.id" 177 :id="user.id"
179 :type="user.type" 178 :type="user.type"
...@@ -202,7 +201,6 @@ import Vtree, { VTreeNode, VTreeSearch, VTreeDrop } from '@wsfe/vue-tree' ...@@ -202,7 +201,6 @@ import Vtree, { VTreeNode, VTreeSearch, VTreeDrop } from '@wsfe/vue-tree'
202 import '@wsfe/vue-tree/style.css'; 201 import '@wsfe/vue-tree/style.css';
203 import role_list from './flow_role_list.json' 202 import role_list from './flow_role_list.json'
204 import dept_list from './flow_dept_list.json' 203 import dept_list from './flow_dept_list.json'
205 -// import user_dept_role from './user_dept_role.json'
206 import $ from 'jquery'; 204 import $ from 'jquery';
207 import _ from 'lodash'; 205 import _ from 'lodash';
208 206
...@@ -267,16 +265,55 @@ const onCloseSearch = () => { // 点击搜索关闭按钮回调 ...@@ -267,16 +265,55 @@ const onCloseSearch = () => { // 点击搜索关闭按钮回调
267 } 265 }
268 /****************************** END ********************************/ 266 /****************************** END ********************************/
269 267
268 +/**
269 + * 中间通用显示勾选结果集
270 + */
271 +
272 +const checkedGroup = ref({
273 + dept: [], // 组织结构
274 + role: [], // 角色
275 + user: [] // 成员
276 +});
277 +
278 +const onRemoveDeptTag = (dept) => { // 移除部门标签
279 + // 移除选中框显示
280 + const index = checkedGroup.value.dept.indexOf(dept);
281 + checkedGroup.value.dept.splice(index, 1);
282 + // 组织结构移除对应ID
283 + deptTreeRef.value?.setChecked(dept.id, false);
284 + // 移除搜索结果选中显示
285 + const idx = search_result_checked.value.indexOf(dept);
286 + search_result_checked.value.splice(idx, 1);
287 +}
288 +
289 +const onRemoveRoleTag = (role) => { // 移除角色标签
290 + const index = checkedGroup.value.role.indexOf(role);
291 + checkedGroup.value.role.splice(index, 1);
292 + //
293 + const idx = role_checked.value.indexOf(role);
294 + role_checked.value.splice(index, 1);
295 + // 移除搜索结果选中显示
296 + const i = search_result_checked.value.indexOf(role);
297 + search_result_checked.value.splice(i, 1);
298 +}
299 +
300 +const onRemoveUserTag = (user) => { // 移除成员标签
301 + const index = checkedGroup.value.user.indexOf(user);
302 + checkedGroup.value.user.splice(index, 1);
303 + //
304 + const idx = user_checked.value.indexOf(user);
305 + user_checked.value.splice(index, 1);
306 + // 移除搜索结果选中显示
307 + const i = search_result_checked.value.indexOf(user);
308 + search_result_checked.value.splice(i, 1);
309 +}
310 +
270 /*************** Tab 功能模块 ****************/ 311 /*************** Tab 功能模块 ****************/
271 const tabRef = ref(null); 312 const tabRef = ref(null);
272 const tabActive = ref(0); 313 const tabActive = ref(0);
273 -const select_dept_value = ref(); // 组织结构树形选中值
274 const deptTreeRef = ref(); 314 const deptTreeRef = ref();
275 -const role_checked = ref([]); // 角色多选选中值 315 +
276 -const roleList = ref([]); 316 +
277 -const select_user_value = ref(); // 成员树形选中值
278 -const userTreeRef = ref();
279 -const user_checked = ref([]); // 成员多选选中值
280 const userList = ref([]); 317 const userList = ref([]);
281 318
282 const onClickTab = ({ title }) => { // tab点击事件 319 const onClickTab = ({ title }) => { // tab点击事件
...@@ -293,149 +330,109 @@ const onClickTab = ({ title }) => { // tab点击事件 ...@@ -293,149 +330,109 @@ const onClickTab = ({ title }) => { // tab点击事件
293 }); 330 });
294 }; 331 };
295 332
296 -const checkedGroup = ref({ 333 +const deptListReset = () => { // 组织重置列表
297 - dept: [], 334 + deptTreeRef.value.setData(role_list);
298 - role: [], 335 + deptTreeRef.value.setExpand(35697, true)
299 - user: [] 336 +}
300 -});
301 337
302 -// 使用watch进行深度监听 338 +const roleListReset = () => { // 角色重置列表
303 -watch( 339 + roleList.value = dept_list;
304 - checkedGroup, 340 +}
305 - (newCheckedGroup, oldCheckedGroup, onInvalidate) => { 341 +
306 - // console.log('checkedGroup changed:', newCheckedGroup); 342 +const userListReset = () => { // 成员重置列表
307 - // role_checked.value = newCheckedGroup.role.map(item => item.id); 343 + userTreeRef.value.setData(role_list);
308 - // 如果需要在下次更新前清理副作用,可以使用onInvalidate 344 + userTreeRef.value.setExpand(35697, true)
309 - // onInvalidate(() => { 345 +}
310 - // console.log('Watch invalidated'); 346 +/**************** END *****************/
311 - // });
312 - },
313 - {
314 - deep: true, // 深度监听
315 - immediate: true, // 立即触发回调
316 - }
317 -);
318 347
319 onMounted(() => { 348 onMounted(() => {
320 props.item.value = props.item.component_props.default; 349 props.item.value = props.item.component_props.default;
321 -
322 // TODO:获取数据 350 // TODO:获取数据
323 - deptTreeRef.value.setData(role_list); 351 + getDeptTreeData();
324 - // 默认展开第一个
325 - deptTreeRef.value.setExpand(35697, true)
326 - // // 默认展开第一个
327 - // userTreeRef.value.setExpand(1, true)
328 }); 352 });
329 353
330 -const searchMethod = (value) => { 354 +/************* 组织结构模块 ***************/
331 - console.log(value) 355 +const select_dept_value = ref(); // 组织结构树形选中值
356 +
357 +const getDeptTreeData = () => { // 获取组织结构数据
358 + deptTreeRef.value.setData(role_list);
359 + // 默认展开第一个
360 + deptTreeRef.value.setExpand(35697, true);
332 } 361 }
333 362
334 -const checkedChangeMethod = (arr) => { 363 +const deptTreeCheckedChange = (arr) => { // 组织结构勾选回调
335 - let list = []; 364 + checkedGroup.value.dept = arr.map((item) => {
336 - arr.forEach((item) => { 365 + return {
337 - list.push({
338 id: item.id, 366 id: item.id,
339 - name: item.name 367 + name: item.name,
340 - }) 368 + type: 'dept'
341 - }) 369 + }
342 - // console.log(deptTreeRef.value.getCheckedNodes()) 370 + });
343 - // checkedGroup.value.dept = [];
344 - checkedGroup.value.dept = list;
345 } 371 }
372 +/**************** END *****************/
346 373
374 +/************* 角色模块 ***************/
375 +const role_checked = ref([]); // 角色多选选中值
376 +const roleList = ref([]);
347 377
348 -const deptListReset = () => { // 组织重置列表 378 +const roleChangeMethod = (val) => { // 角色多选组点击回调
349 - deptTreeRef.value.setData(role_list); 379 + let result = val.map(id => roleList.value.find(obj => obj.id === id));
350 - 380 + // 过滤掉未找到的项(即返回undefined的项)
351 - deptTreeRef.value.setExpand(35697, true) 381 + checkedGroup.value.role = result.filter(item => item !== undefined);
352 -}
353 -const roleListReset = () => {
354 - roleList.value = dept_list;
355 } 382 }
356 -const userListReset = () => { 383 +/**************** END *****************/
357 - userTreeRef.value.setData(role_list);
358 384
359 - userTreeRef.value.setExpand(35697, true) 385 +/************* 成员模块 ***************/
360 -} 386 +const userTreeRef = ref();
387 +const select_user_value = ref(); // 成员树形选中值
388 +const user_checked = ref([]); // 成员多选选中值
361 389
362 -const onNodeClick = (node) => { 390 +const onUserTreeClick = (node) => { // 点击成员树形回调
363 - // console.warn(node);
364 - console.warn(checkedGroup.value.user);
365 - // console.warn(node.user);
366 userList.value = node.user; 391 userList.value = node.user;
367 user_checked.value = checkedGroup.value.user.map(item => item.id) 392 user_checked.value = checkedGroup.value.user.map(item => item.id)
368 } 393 }
369 394
370 -const roleChangeMethod = (val) => { // 角色多选组点击回调
371 - let list = [];
372 - roleList.value.forEach((item) => {
373 - val.forEach((v) => {
374 - if (item.id === v) {
375 - list.push({
376 - id: v,
377 - name: item.name
378 - })
379 - }
380 - })
381 - });
382 - //
383 - // checkedGroup.value.role = [];
384 - checkedGroup.value.role = list;
385 -}
386 -
387 -const onChange = (val) => {
388 - console.warn(userList.value);
389 -}
390 -
391 -const roleTreeList = ref(role_list);
392 -
393 const onUserChange = (val) => { // 成员多选组点击回调 395 const onUserChange = (val) => { // 成员多选组点击回调
394 - // userList.value.forEach(item => {
395 - // if (val.includes(item.id)) {
396 - // item.checked = true;
397 - // } else {
398 - // item.checked = false;
399 - // }
400 - // });
401 -
402 - // checkedGroup.value.user = user_checked.value;
403 -}
404 -
405 -const onRemoveDeptTag = (dept) => { // 移除部门标签
406 - // 移除选中框显示
407 - const index = checkedGroup.value.dept.indexOf(dept);
408 - checkedGroup.value.dept.splice(index, 1);
409 - // 组织结构移除对应ID
410 - deptTreeRef.value?.setChecked(dept.id, false);
411 - // 移除搜索结果选中显示
412 - const idx = search_result_checked.value.indexOf(dept);
413 - search_result_checked.value.splice(idx, 1);
414 } 396 }
415 397
416 -const onRemoveRoleTag = (role) => { // 移除角色标签 398 +const onCheckUserChange = (val, evt) => {
417 - const index = checkedGroup.value.role.indexOf(role); 399 + nextTick(() => {
418 - checkedGroup.value.role.splice(index, 1); 400 + let checked = false;
419 - // 401 + let id = '';
420 - const idx = role_checked.value.indexOf(role); 402 + let name = '';
421 - role_checked.value.splice(index, 1); 403 + let type = '';
422 - // 移除搜索结果选中显示 404 + if ($(evt.target).attr('aria-checked') === undefined) {
423 - const i = search_result_checked.value.indexOf(role); 405 + checked = $(evt.target).parents('.van-checkbox').attr('aria-checked');
424 - search_result_checked.value.splice(i, 1); 406 + id = $(evt.target).parents('.van-checkbox').attr('id');
407 + name = $(evt.target).parents('.van-checkbox').attr('text');
408 + type = $(evt.target).parents('.van-checkbox').attr('type');
409 + } else {
410 + checked = $(evt.target).attr('aria-checked');
411 + id = $(evt.target).attr('id');
412 + name = $(evt.target).attr('text');
413 + type = $(evt.target).attr('type');
414 + }
415 + let obj = {
416 + id: +id,
417 + name,
418 + type
419 + }
420 + checkedGroup.value.user.push(obj);
421 + checkedGroup.value.user = _.uniqBy(checkedGroup.value.user, 'id');
422 + //
423 + if (checked === 'false') {
424 + if (val.type === 'user') {
425 + const index = checkedGroup.value.user.indexOf(val);
426 + checkedGroup.value.user.splice(index, 1);
427 + }
428 + }
429 + })
425 } 430 }
431 +/**************** END *****************/
426 432
427 -const onRemoveUserTag = (user) => { // 移除成员标签 433 +/***************** 搜索结果集模块 ********************/
428 - console.warn(user);
429 - const index = checkedGroup.value.user.indexOf(user);
430 - checkedGroup.value.user.splice(index, 1);
431 - //
432 - const idx = user_checked.value.indexOf(user);
433 - user_checked.value.splice(index, 1);
434 - // 移除搜索结果选中显示
435 - const i = search_result_checked.value.indexOf(user);
436 - search_result_checked.value.splice(i, 1);
437 -}
438 434
435 +// 模拟数据
439 const user_dept_role = ref({ 436 const user_dept_role = ref({
440 "dept": [ 437 "dept": [
441 { 438 {
...@@ -474,184 +471,50 @@ const user_dept_role = ref({ ...@@ -474,184 +471,50 @@ const user_dept_role = ref({
474 ] 471 ]
475 }); 472 });
476 473
477 -
478 -
479 -// watch(
480 -// search_result_checked
481 -// ,(newVal, oldVal) => {
482 -// console.warn(newVal);
483 -// console.warn(oldVal);
484 -// }, {
485 -// deep: true,
486 -// })
487 -
488 const onSearchResultChange = (val) => { // 监听搜索结果集点击回调,结果集为选中项 474 const onSearchResultChange = (val) => { // 监听搜索结果集点击回调,结果集为选中项
489 - // console.warn(val);
490 - // val.forEach((item) => { // 把选中项合并到显示框中
491 - // if (item.type === 'dept') { // 部门
492 - // checkedGroup.value.dept.push(item);
493 - // checkedGroup.value.dept = _.uniqBy(checkedGroup.value.dept, 'id');
494 - // }
495 - // if (item.type === 'role') { // 角色
496 - // checkedGroup.value.role.push(item);
497 - // checkedGroup.value.role = _.uniqBy(checkedGroup.value.role, 'id');
498 - // }
499 - // if (item.type === 'user') { // 成员
500 - // checkedGroup.value.user.push(item);
501 - // checkedGroup.value.user = _.uniqBy(checkedGroup.value.user, 'id');
502 - // }
503 - // });
504 } 475 }
505 476
506 -const onSearchDeptChange = (val, evt) => { 477 +const onSearchResultClick = (val, evt) => { // 搜索结果集项点击回调
507 - nextTick(() => {
508 - let checked = false;
509 - let id = '';
510 - let name = '';
511 - let type = '';
512 - if ($(evt.target).attr('aria-checked') === undefined) {
513 - checked = $(evt.target).parents('.van-checkbox').attr('aria-checked');
514 - id = $(evt.target).parents('.van-checkbox').attr('id');
515 - name = $(evt.target).parents('.van-checkbox').attr('text');
516 - type = $(evt.target).parents('.van-checkbox').attr('type');
517 - } else {
518 - checked = $(evt.target).attr('aria-checked');
519 - id = $(evt.target).attr('id');
520 - name = $(evt.target).attr('text');
521 - type = $(evt.target).attr('type');
522 - }
523 - let obj = {
524 - id: +id,
525 - name,
526 - type
527 - }
528 - checkedGroup.value.dept.push(obj);
529 - checkedGroup.value.dept = _.uniqBy(checkedGroup.value.dept, 'id');
530 - //
531 - if (checked === 'false') {
532 - if (val.type === 'dept') {
533 - console.warn(obj);
534 - const index = checkedGroup.value.dept.findIndex(dept => dept.id === obj.id);
535 - checkedGroup.value.dept.splice(index, 1);
536 - // 移除搜索结果选中显示
537 - // const idx = search_result_checked.value.indexOf(obj);
538 - // search_result_checked.value.splice(idx, 1);
539 - // 组织结构移除对应ID
540 - deptTreeRef.value?.setChecked(obj.id, false);
541 - }
542 - }
543 - })
544 -}
545 -const onSearchRoleChange = (val, evt) => {
546 nextTick(() => { 478 nextTick(() => {
547 let checked = false; 479 let checked = false;
548 let id = ''; 480 let id = '';
549 let name = ''; 481 let name = '';
550 let type = ''; 482 let type = '';
551 - if ($(evt.target).attr('aria-checked') === undefined) {
552 - checked = $(evt.target).parents('.van-checkbox').attr('aria-checked');
553 - id = $(evt.target).parents('.van-checkbox').attr('id');
554 - name = $(evt.target).parents('.van-checkbox').attr('text');
555 - type = $(evt.target).parents('.van-checkbox').attr('type');
556 - } else {
557 - checked = $(evt.target).attr('aria-checked');
558 - id = $(evt.target).attr('id');
559 - name = $(evt.target).attr('text');
560 - type = $(evt.target).attr('type');
561 - }
562 - let obj = {
563 - id: +id,
564 - name,
565 - type
566 - }
567 - checkedGroup.value.role.push(obj);
568 - checkedGroup.value.role = _.uniqBy(checkedGroup.value.role, 'id');
569 - //
570 - if (checked === 'false') {
571 - if (val.type === 'role') {
572 - const index = checkedGroup.value.role.findIndex(role => role.id === obj.id);
573 - checkedGroup.value.role.splice(index, 1);
574 - // const idx = role_checked.value.indexOf(obj);
575 - // role_checked.value.splice(index, 1);
576 - // 移除搜索结果选中显示
577 - // const i = search_result_checked.value.indexOf(obj);
578 - // search_result_checked.value.splice(i, 1);
579 - }
580 - }
581 - })
582 -}
583 -const onSearchUserChange = (val, evt) => {
584 - nextTick(() => {
585 - let checked = false;
586 - let id = '';
587 - let name = '';
588 - let type = '';
589 - if ($(evt.target).attr('aria-checked') === undefined) {
590 - checked = $(evt.target).parents('.van-checkbox').attr('aria-checked');
591 - id = $(evt.target).parents('.van-checkbox').attr('id');
592 - name = $(evt.target).parents('.van-checkbox').attr('text');
593 - type = $(evt.target).parents('.van-checkbox').attr('type');
594 - } else {
595 - checked = $(evt.target).attr('aria-checked');
596 - id = $(evt.target).attr('id');
597 - name = $(evt.target).attr('text');
598 - type = $(evt.target).attr('type');
599 - }
600 - let obj = {
601 - id: +id,
602 - name,
603 - type
604 - }
605 - checkedGroup.value.user.push(obj);
606 - checkedGroup.value.user = _.uniqBy(checkedGroup.value.user, 'id');
607 - //
608 - if (checked === 'false') {
609 - if (val.type === 'user') {
610 - const index = checkedGroup.value.user.findIndex(user => user.id === obj.id);
611 - checkedGroup.value.user.splice(index, 1);
612 - // //
613 - // const idx = user_checked.value.indexOf(obj);
614 - // user_checked.value.splice(index, 1);
615 - // // 移除搜索结果选中显示
616 - // const i = search_result_checked.value.indexOf(obj);
617 - // search_result_checked.value.splice(i, 1);
618 - }
619 - }
620 - })
621 -}
622 483
623 -const onCheckUserChange = (val, evt) => { 484 + if ($(evt.target).attr('aria-checked') === undefined) { // 点击子元素
624 - nextTick(() => {
625 - let checked = false;
626 - let id = '';
627 - let name = '';
628 - let type = '';
629 - if ($(evt.target).attr('aria-checked') === undefined) {
630 checked = $(evt.target).parents('.van-checkbox').attr('aria-checked'); 485 checked = $(evt.target).parents('.van-checkbox').attr('aria-checked');
631 id = $(evt.target).parents('.van-checkbox').attr('id'); 486 id = $(evt.target).parents('.van-checkbox').attr('id');
632 name = $(evt.target).parents('.van-checkbox').attr('text'); 487 name = $(evt.target).parents('.van-checkbox').attr('text');
633 type = $(evt.target).parents('.van-checkbox').attr('type'); 488 type = $(evt.target).parents('.van-checkbox').attr('type');
634 - } else { 489 + } else { // 点击父元素
635 checked = $(evt.target).attr('aria-checked'); 490 checked = $(evt.target).attr('aria-checked');
636 id = $(evt.target).attr('id'); 491 id = $(evt.target).attr('id');
637 name = $(evt.target).attr('text'); 492 name = $(evt.target).attr('text');
638 type = $(evt.target).attr('type'); 493 type = $(evt.target).attr('type');
639 } 494 }
640 - let obj = { 495 +
496 + let obj = { // 点击元素属性
641 id: +id, 497 id: +id,
642 name, 498 name,
643 type 499 type
644 } 500 }
645 - checkedGroup.value.user.push(obj); 501 +
646 - checkedGroup.value.user = _.uniqBy(checkedGroup.value.user, 'id'); 502 + // 对应类型添加到选中组
647 - // 503 + checkedGroup.value[type].push(obj);
504 + checkedGroup.value[type] = _.uniqBy(checkedGroup.value[type], 'id');
505 +
506 + // 取消选中处理
648 if (checked === 'false') { 507 if (checked === 'false') {
649 - if (val.type === 'user') { 508 + // 移除对应的数据集
650 - const index = checkedGroup.value.user.indexOf(val); 509 + const index = checkedGroup.value[type].findIndex(item => item.id === obj.id);
651 - checkedGroup.value.user.splice(index, 1); 510 + checkedGroup.value[type].splice(index, 1);
511 +
512 + if (type === 'dept') {
513 + // 树形 组织结构移除对应ID
514 + deptTreeRef.value?.setChecked(obj.id, false);
652 } 515 }
653 } 516 }
654 - }) 517 + });
655 } 518 }
656 </script> 519 </script>
657 520
......