Showing
1 changed file
with
99 additions
and
137 deletions
| 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 00:19:33 | 4 | + * @LastEditTime: 2024-05-31 11:32:37 |
| 5 | * @FilePath: /data-table/src/components/TreeField/index.vue | 5 | * @FilePath: /data-table/src/components/TreeField/index.vue |
| 6 | * @Description: 树形组件 | 6 | * @Description: 树形组件 |
| 7 | --> | 7 | --> |
| ... | @@ -13,14 +13,22 @@ | ... | @@ -13,14 +13,22 @@ |
| 13 | </div> | 13 | </div> |
| 14 | 14 | ||
| 15 | <van-popup | 15 | <van-popup |
| 16 | - v-model:show="showBottom" | 16 | + v-model:show="showPopover" |
| 17 | position="bottom" | 17 | position="bottom" |
| 18 | :style="{ height: '90vh' }" | 18 | :style="{ height: '90vh' }" |
| 19 | > | 19 | > |
| 20 | <div v-if="!is_search" class="search-box" @click="onSearchFocus"> | 20 | <div v-if="!is_search" class="search-box" @click="onSearchFocus"> |
| 21 | <van-icon name="search" size="1.1rem" /> 点击搜索 | 21 | <van-icon name="search" size="1.1rem" /> 点击搜索 |
| 22 | </div> | 22 | </div> |
| 23 | - <van-field ref="searchInputRef" v-else v-model="search_value" label="" placeholder="可通过名称,手机号或邮箱查询" :border="false" @blur="onSearchBlur" @focus="onSearchFocus"> | 23 | + <van-field |
| 24 | + v-else | ||
| 25 | + ref="searchInputRef" | ||
| 26 | + v-model="searchValue" | ||
| 27 | + placeholder="可通过名称,手机号或邮箱查询" | ||
| 28 | + :border="false" | ||
| 29 | + @blur="onSearchBlur" | ||
| 30 | + @focus="onSearchFocus" | ||
| 31 | + > | ||
| 24 | <template #button> | 32 | <template #button> |
| 25 | <van-button size="small" type="primary" @click="onCloseSearch">关闭</van-button> | 33 | <van-button size="small" type="primary" @click="onCloseSearch">关闭</van-button> |
| 26 | </template> | 34 | </template> |
| ... | @@ -86,8 +94,8 @@ | ... | @@ -86,8 +94,8 @@ |
| 86 | <van-row gutter=""> | 94 | <van-row gutter=""> |
| 87 | <van-col span="10" style="border-right: 1px solid #eee; height: 60vh; overflow: scroll;"> | 95 | <van-col span="10" style="border-right: 1px solid #eee; height: 60vh; overflow: scroll;"> |
| 88 | <Vtree | 96 | <Vtree |
| 89 | - ref="memberTreeRef" | 97 | + ref="userTreeRef" |
| 90 | - v-model="select_member_value" | 98 | + v-model="select_user_value" |
| 91 | selectable | 99 | selectable |
| 92 | titleField="name" | 100 | titleField="name" |
| 93 | keyField="id" | 101 | keyField="id" |
| ... | @@ -101,22 +109,22 @@ | ... | @@ -101,22 +109,22 @@ |
| 101 | </van-col> | 109 | </van-col> |
| 102 | <van-col span="14"> | 110 | <van-col span="14"> |
| 103 | <van-checkbox-group | 111 | <van-checkbox-group |
| 104 | - v-model="member_checked" | 112 | + v-model="user_checked" |
| 105 | style="padding: 0 0 1rem 1rem;" | 113 | style="padding: 0 0 1rem 1rem;" |
| 106 | - @change="onMemberChange" | 114 | + @change="onUserChange" |
| 107 | > | 115 | > |
| 108 | <van-checkbox | 116 | <van-checkbox |
| 109 | 117 | ||
| 110 | - @click="onCheckMemberChange(member, $event)" | 118 | + @click="onCheckUserChange(user, $event)" |
| 111 | - v-for="(member, index) in memberList" | 119 | + v-for="(user, index) in userList" |
| 112 | - :id="member.id" | 120 | + :id="user.id" |
| 113 | - :type="member.type" | 121 | + :type="user.type" |
| 114 | - :text="member.name" | 122 | + :text="user.name" |
| 115 | :key="index" | 123 | :key="index" |
| 116 | - :name="member.id" | 124 | + :name="user.id" |
| 117 | shape="square" | 125 | shape="square" |
| 118 | icon-size="13px" | 126 | icon-size="13px" |
| 119 | - :checked-color="styleColor.baseColor" style="margin-bottom: 0.5rem;">{{ member.name }}</van-checkbox> | 127 | + :checked-color="styleColor.baseColor" style="margin-bottom: 0.5rem;">{{ user.name }}</van-checkbox> |
| 120 | </van-checkbox-group> | 128 | </van-checkbox-group> |
| 121 | </van-col> | 129 | </van-col> |
| 122 | </van-row> | 130 | </van-row> |
| ... | @@ -212,93 +220,79 @@ const isGroup = computed(() => { | ... | @@ -212,93 +220,79 @@ const isGroup = computed(() => { |
| 212 | return props.item.component_props.is_field_group | 220 | return props.item.component_props.is_field_group |
| 213 | }); | 221 | }); |
| 214 | 222 | ||
| 215 | -const showBottom = ref(true); | 223 | +/******* 搜索输入项 *******/ |
| 224 | +const showPopover = ref(true); // 显示/隐藏弹框 | ||
| 216 | 225 | ||
| 217 | -const search_value = ref(''); | 226 | +const searchInputRef = ref(null); |
| 218 | -const onSearch = (val) => { | 227 | +const searchValue = ref(''); |
| 219 | - console.log(val); | 228 | +const is_search = ref(false); // 默认不显示搜索框 |
| 220 | -}; | 229 | +/** |
| 221 | -const onCancel = () => { | 230 | + * 搜索选中结果集 |
| 222 | - search_value.value = ''; | 231 | + * @param {Number} id |
| 223 | -}; | 232 | + */ |
| 233 | +const search_result_checked = ref([]); | ||
| 234 | + | ||
| 235 | +const onSearchBlur = () => { // 搜索框失去焦点 | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +const onSearchFocus = () => { // 搜索框获取焦点回调 | ||
| 239 | + is_search.value = true; // 打开搜索状态 | ||
| 240 | + | ||
| 241 | + // 自动选中搜索框 | ||
| 242 | + nextTick(() => { | ||
| 243 | + searchInputRef.value.focus(); | ||
| 244 | + }); | ||
| 245 | + | ||
| 246 | + // 如果选中框有值,点击搜索框后把结果选中到搜索结果集里面 | ||
| 247 | + // TODO:待实现 真实情况应该是请求搜索结果后做 | ||
| 248 | + handleSelectToSearch(); | ||
| 249 | +} | ||
| 224 | 250 | ||
| 251 | +const handleSelectToSearch = () => { // 把选中结果集同步,到搜索结果集上勾中显示 | ||
| 252 | + let dept = checkedGroup.value.dept.map(item => item.id); | ||
| 253 | + let role = checkedGroup.value.role.map(item => item.id); | ||
| 254 | + let user = checkedGroup.value.user.map(item => item.id); | ||
| 255 | + search_result_checked.value = [...dept, ...role, ...user]; // 搜索选中结果集 | ||
| 256 | +} | ||
| 257 | + | ||
| 258 | +const onCloseSearch = () => { // 点击搜索关闭按钮回调 | ||
| 259 | + tabActive.value = 0; // 默认选中组织结构 | ||
| 260 | + is_search.value = false; // 关闭搜索状态 | ||
| 261 | + // 组织结构,勾选状态还原 | ||
| 262 | + deptTreeRef.value?.setCheckedKeys(checkedGroup.value.dept.map(item => item.id), true); | ||
| 263 | + // 角色选中,勾选状态还原 | ||
| 264 | + role_checked.value = checkedGroup.value.role.map(item => item.id); | ||
| 265 | + // 成员选中,勾选状态还原 | ||
| 266 | + user_checked.value = checkedGroup.value.user.map(item => item.id) | ||
| 267 | +} | ||
| 268 | +/****************************** END ********************************/ | ||
| 269 | + | ||
| 270 | +/*************** Tab 功能模块 ****************/ | ||
| 225 | const tabRef = ref(null); | 271 | const tabRef = ref(null); |
| 226 | const tabActive = ref(0); | 272 | const tabActive = ref(0); |
| 227 | -const select_dept_value = ref(); | 273 | +const select_dept_value = ref(); // 组织结构树形选中值 |
| 228 | const deptTreeRef = ref(); | 274 | const deptTreeRef = ref(); |
| 229 | -const role_checked = ref([]); | 275 | +const role_checked = ref([]); // 角色多选选中值 |
| 230 | const roleList = ref([]); | 276 | const roleList = ref([]); |
| 231 | -const select_member_value = ref(); | 277 | +const select_user_value = ref(); // 成员树形选中值 |
| 232 | -const memberTreeRef = ref(); | 278 | +const userTreeRef = ref(); |
| 233 | -const member_checked = ref([]); | 279 | +const user_checked = ref([]); // 成员多选选中值 |
| 234 | -const memberList = ref([]); | 280 | +const userList = ref([]); |
| 235 | 281 | ||
| 236 | const onClickTab = ({ title }) => { // tab点击事件 | 282 | const onClickTab = ({ title }) => { // tab点击事件 |
| 237 | - if (title === '组织结构') { | 283 | + nextTick(() => { |
| 238 | - nextTick(() => { | 284 | + if (title === '组织结构') { |
| 239 | deptListReset(); | 285 | deptListReset(); |
| 240 | - }); | 286 | + } |
| 241 | - } | 287 | + if (title === '角色') { |
| 242 | - if (title === '角色') { | ||
| 243 | - nextTick(() => { | ||
| 244 | roleListReset(); | 288 | roleListReset(); |
| 245 | - }); | 289 | + } |
| 246 | - } | 290 | + if (title === '成员') { |
| 247 | - if (title === '成员') { | 291 | + userListReset(); |
| 248 | - nextTick(() => { | 292 | + } |
| 249 | - memberListReset(); | 293 | + }); |
| 250 | - }); | ||
| 251 | - } | ||
| 252 | }; | 294 | }; |
| 253 | 295 | ||
| 254 | -const testData = [{ | ||
| 255 | - id: 1, | ||
| 256 | - name: '西园寺', | ||
| 257 | - children: [{ | ||
| 258 | - name: '保安', | ||
| 259 | - id: 2, | ||
| 260 | - children: [{ | ||
| 261 | - name: '1号', | ||
| 262 | - id: 3 | ||
| 263 | - }] | ||
| 264 | - }, { | ||
| 265 | - name: '餐饮', | ||
| 266 | - id: 4, | ||
| 267 | - children: [{ | ||
| 268 | - name: '5号', | ||
| 269 | - id: 5 | ||
| 270 | - }] | ||
| 271 | - }, { | ||
| 272 | - name: '保安', | ||
| 273 | - id: 21, | ||
| 274 | - children: [{ | ||
| 275 | - name: '1号', | ||
| 276 | - id: 31 | ||
| 277 | - }] | ||
| 278 | - }, { | ||
| 279 | - name: '餐饮', | ||
| 280 | - id: 41, | ||
| 281 | - children: [{ | ||
| 282 | - name: '5号', | ||
| 283 | - id: 51 | ||
| 284 | - }] | ||
| 285 | - }, { | ||
| 286 | - name: '保安', | ||
| 287 | - id: 22, | ||
| 288 | - children: [{ | ||
| 289 | - name: '1号', | ||
| 290 | - id: 32 | ||
| 291 | - }] | ||
| 292 | - }, { | ||
| 293 | - name: '餐饮', | ||
| 294 | - id: 42, | ||
| 295 | - children: [{ | ||
| 296 | - name: '5号', | ||
| 297 | - id: 52 | ||
| 298 | - }] | ||
| 299 | - }] | ||
| 300 | -}]; | ||
| 301 | - | ||
| 302 | const checkedGroup = ref({ | 296 | const checkedGroup = ref({ |
| 303 | dept: [], | 297 | dept: [], |
| 304 | role: [], | 298 | role: [], |
| ... | @@ -329,9 +323,8 @@ onMounted(() => { | ... | @@ -329,9 +323,8 @@ onMounted(() => { |
| 329 | deptTreeRef.value.setData(role_list); | 323 | deptTreeRef.value.setData(role_list); |
| 330 | // 默认展开第一个 | 324 | // 默认展开第一个 |
| 331 | deptTreeRef.value.setExpand(35697, true) | 325 | deptTreeRef.value.setExpand(35697, true) |
| 332 | - // memberTreeRef.value.setData(testData); | ||
| 333 | // // 默认展开第一个 | 326 | // // 默认展开第一个 |
| 334 | - // memberTreeRef.value.setExpand(1, true) | 327 | + // userTreeRef.value.setExpand(1, true) |
| 335 | }); | 328 | }); |
| 336 | 329 | ||
| 337 | const searchMethod = (value) => { | 330 | const searchMethod = (value) => { |
| ... | @@ -351,37 +344,6 @@ const checkedChangeMethod = (arr) => { | ... | @@ -351,37 +344,6 @@ const checkedChangeMethod = (arr) => { |
| 351 | checkedGroup.value.dept = list; | 344 | checkedGroup.value.dept = list; |
| 352 | } | 345 | } |
| 353 | 346 | ||
| 354 | -const is_search = ref(false); // 默认不显示搜索框 | ||
| 355 | - | ||
| 356 | -const onSearchBlur = () => { // 搜索框失去焦点 | ||
| 357 | - // search_result_checked.value = [] | ||
| 358 | -} | ||
| 359 | - | ||
| 360 | -const onSearchFocus = () => { // 搜索框获取焦点 | ||
| 361 | - is_search.value = true; | ||
| 362 | - nextTick(() => { | ||
| 363 | - searchInputRef.value.focus() | ||
| 364 | - }) | ||
| 365 | - // 角色选中 | ||
| 366 | - let dept = checkedGroup.value.dept.map(item => item.id); | ||
| 367 | - let role = checkedGroup.value.role.map(item => item.id); | ||
| 368 | - let user = checkedGroup.value.user.map(item => item.id); | ||
| 369 | - search_result_checked.value = [...dept, ...role, ...user]; | ||
| 370 | -} | ||
| 371 | - | ||
| 372 | -const onCloseSearch = () => { // 搜索关闭按钮 | ||
| 373 | - tabActive.value = 0 | ||
| 374 | - is_search.value = false; | ||
| 375 | - // 组织结构勾选状态还原 | ||
| 376 | - deptTreeRef.value?.setCheckedKeys(checkedGroup.value.dept.map(item => item.id), true); | ||
| 377 | - // console.warn(checkedGroup.value.role); | ||
| 378 | - // 角色选中 | ||
| 379 | - role_checked.value = checkedGroup.value.role.map(item => item.id); | ||
| 380 | - // | ||
| 381 | - member_checked.value = checkedGroup.value.user.map(item => item.id) | ||
| 382 | -} | ||
| 383 | - | ||
| 384 | -const searchInputRef = ref(null); | ||
| 385 | 347 | ||
| 386 | const deptListReset = () => { // 组织重置列表 | 348 | const deptListReset = () => { // 组织重置列表 |
| 387 | deptTreeRef.value.setData(role_list); | 349 | deptTreeRef.value.setData(role_list); |
| ... | @@ -391,18 +353,18 @@ const deptListReset = () => { // 组织重置列表 | ... | @@ -391,18 +353,18 @@ const deptListReset = () => { // 组织重置列表 |
| 391 | const roleListReset = () => { | 353 | const roleListReset = () => { |
| 392 | roleList.value = dept_list; | 354 | roleList.value = dept_list; |
| 393 | } | 355 | } |
| 394 | -const memberListReset = () => { | 356 | +const userListReset = () => { |
| 395 | - memberTreeRef.value.setData(role_list); | 357 | + userTreeRef.value.setData(role_list); |
| 396 | 358 | ||
| 397 | - memberTreeRef.value.setExpand(35697, true) | 359 | + userTreeRef.value.setExpand(35697, true) |
| 398 | } | 360 | } |
| 399 | 361 | ||
| 400 | const onNodeClick = (node) => { | 362 | const onNodeClick = (node) => { |
| 401 | // console.warn(node); | 363 | // console.warn(node); |
| 402 | console.warn(checkedGroup.value.user); | 364 | console.warn(checkedGroup.value.user); |
| 403 | // console.warn(node.user); | 365 | // console.warn(node.user); |
| 404 | - memberList.value = node.user; | 366 | + userList.value = node.user; |
| 405 | - member_checked.value = checkedGroup.value.user.map(item => item.id) | 367 | + user_checked.value = checkedGroup.value.user.map(item => item.id) |
| 406 | } | 368 | } |
| 407 | 369 | ||
| 408 | const roleChangeMethod = (val) => { // 角色多选组点击回调 | 370 | const roleChangeMethod = (val) => { // 角色多选组点击回调 |
| ... | @@ -423,13 +385,13 @@ const roleChangeMethod = (val) => { // 角色多选组点击回调 | ... | @@ -423,13 +385,13 @@ const roleChangeMethod = (val) => { // 角色多选组点击回调 |
| 423 | } | 385 | } |
| 424 | 386 | ||
| 425 | const onChange = (val) => { | 387 | const onChange = (val) => { |
| 426 | - console.warn(memberList.value); | 388 | + console.warn(userList.value); |
| 427 | } | 389 | } |
| 428 | 390 | ||
| 429 | const roleTreeList = ref(role_list); | 391 | const roleTreeList = ref(role_list); |
| 430 | 392 | ||
| 431 | -const onMemberChange = (val) => { // 成员多选组点击回调 | 393 | +const onUserChange = (val) => { // 成员多选组点击回调 |
| 432 | - // memberList.value.forEach(item => { | 394 | + // userList.value.forEach(item => { |
| 433 | // if (val.includes(item.id)) { | 395 | // if (val.includes(item.id)) { |
| 434 | // item.checked = true; | 396 | // item.checked = true; |
| 435 | // } else { | 397 | // } else { |
| ... | @@ -437,7 +399,7 @@ const onMemberChange = (val) => { // 成员多选组点击回调 | ... | @@ -437,7 +399,7 @@ const onMemberChange = (val) => { // 成员多选组点击回调 |
| 437 | // } | 399 | // } |
| 438 | // }); | 400 | // }); |
| 439 | 401 | ||
| 440 | - // checkedGroup.value.user = member_checked.value; | 402 | + // checkedGroup.value.user = user_checked.value; |
| 441 | } | 403 | } |
| 442 | 404 | ||
| 443 | const onRemoveDeptTag = (dept) => { // 移除部门标签 | 405 | const onRemoveDeptTag = (dept) => { // 移除部门标签 |
| ... | @@ -467,8 +429,8 @@ const onRemoveUserTag = (user) => { // 移除成员标签 | ... | @@ -467,8 +429,8 @@ const onRemoveUserTag = (user) => { // 移除成员标签 |
| 467 | const index = checkedGroup.value.user.indexOf(user); | 429 | const index = checkedGroup.value.user.indexOf(user); |
| 468 | checkedGroup.value.user.splice(index, 1); | 430 | checkedGroup.value.user.splice(index, 1); |
| 469 | // | 431 | // |
| 470 | - const idx = member_checked.value.indexOf(user); | 432 | + const idx = user_checked.value.indexOf(user); |
| 471 | - member_checked.value.splice(index, 1); | 433 | + user_checked.value.splice(index, 1); |
| 472 | // 移除搜索结果选中显示 | 434 | // 移除搜索结果选中显示 |
| 473 | const i = search_result_checked.value.indexOf(user); | 435 | const i = search_result_checked.value.indexOf(user); |
| 474 | search_result_checked.value.splice(i, 1); | 436 | search_result_checked.value.splice(i, 1); |
| ... | @@ -512,7 +474,7 @@ const user_dept_role = ref({ | ... | @@ -512,7 +474,7 @@ const user_dept_role = ref({ |
| 512 | ] | 474 | ] |
| 513 | }); | 475 | }); |
| 514 | 476 | ||
| 515 | -const search_result_checked = ref([]); | 477 | + |
| 516 | 478 | ||
| 517 | // watch( | 479 | // watch( |
| 518 | // search_result_checked | 480 | // search_result_checked |
| ... | @@ -648,8 +610,8 @@ const onSearchUserChange = (val, evt) => { | ... | @@ -648,8 +610,8 @@ const onSearchUserChange = (val, evt) => { |
| 648 | const index = checkedGroup.value.user.findIndex(user => user.id === obj.id); | 610 | const index = checkedGroup.value.user.findIndex(user => user.id === obj.id); |
| 649 | checkedGroup.value.user.splice(index, 1); | 611 | checkedGroup.value.user.splice(index, 1); |
| 650 | // // | 612 | // // |
| 651 | - // const idx = member_checked.value.indexOf(obj); | 613 | + // const idx = user_checked.value.indexOf(obj); |
| 652 | - // member_checked.value.splice(index, 1); | 614 | + // user_checked.value.splice(index, 1); |
| 653 | // // 移除搜索结果选中显示 | 615 | // // 移除搜索结果选中显示 |
| 654 | // const i = search_result_checked.value.indexOf(obj); | 616 | // const i = search_result_checked.value.indexOf(obj); |
| 655 | // search_result_checked.value.splice(i, 1); | 617 | // search_result_checked.value.splice(i, 1); |
| ... | @@ -658,7 +620,7 @@ const onSearchUserChange = (val, evt) => { | ... | @@ -658,7 +620,7 @@ const onSearchUserChange = (val, evt) => { |
| 658 | }) | 620 | }) |
| 659 | } | 621 | } |
| 660 | 622 | ||
| 661 | -const onCheckMemberChange = (val, evt) => { | 623 | +const onCheckUserChange = (val, evt) => { |
| 662 | nextTick(() => { | 624 | nextTick(() => { |
| 663 | let checked = false; | 625 | let checked = false; |
| 664 | let id = ''; | 626 | let id = ''; | ... | ... |
-
Please register or login to post a comment