Vue3+ElementUI 多選框中復(fù)選框和名字點擊方法效果分離方法
Vue3+ElementUI 多選框中復(fù)選框和名字點擊方法效果分離
現(xiàn)在的需求為
比如我點擊了Option A ,觸發(fā)點擊Option A的方法,并且復(fù)選框不會取消勾選,分離的方法。
<el-checkbox-group v-model="mapWork.model_checkArray.value"> <div class="naipTypeDom" v-for="item in mapWork.modelList.value" :key="item.id"> <el-checkbox :label="item.id" :disabled="!mapWork.mould_layer_isShow.value"> <span @click.prevent="flyToMould(item.id)">{{ item.modelName }}</span> </el-checkbox> </div> </el-checkbox-group>
通過Vue事件處理的方法.prevent來阻止。<!-- 提交事件將不再重新加載頁面 -->
VUE-Element組件 CheckBox多選框
一、用法說明:
1、el-checkbox標(biāo)簽內(nèi)的內(nèi)容,綁定點擊事件,點擊的時候會觸發(fā)選中/不選中,如果不希望事件冒泡,可以使用
event.preventDefault();
如我:
<el-checkbox-group v-model="codes"> <template v-for="(item, index) in allCodes"> <el-checkbox :label="item.value" :key="item.value" @click.native="handleCheckRegion($event, item.value)" >{{ item.value }} <a class="detail-btn" :key="index" @click="clickToDetail($event, item.value)" >詳情</a > </el-checkbox> </template> </el-checkbox-group> clickToDetail(e, code) { if (e.target.tagName !== 'A') return; //阻止選中 e.preventDefault(); //你的邏輯 }
2、在checkBox中加上按鈕:
<el-checkbox-group v-model="checkedRoleCodes" @change="handleCheckedRoleChange"> <template v-for="(role, index) in allRoles"> <el-checkbox :label="role.value" :key="role.value" @click.native="handleCheckRole($event, role)" :indeterminate="role.indeterminate" >{{ role.text }} <a class="detail-btn" @click="clickRoleToRegionDetail($event, role)" :key="index">詳情</a> </el-checkbox> </template> </el-checkbox-group>
現(xiàn)在希望按鈕統(tǒng)一排列在最有側(cè):給按鈕加上右浮動,并修改.el-checkbox__label的display屬性使按鈕的浮動生效即可:
/deep/ .el-checkbox__label { display: inline; padding-left: 10px; line-height: 19px; font-size: 14px; } .detail-btn { float: right; }
二、舉例
1、例1,現(xiàn)有通訊錄,點擊出現(xiàn)通訊錄選擇彈框。彈框右側(cè)為選擇的用戶列表,可以點擊刪除,左側(cè)默認為角色列表,可以勾選角色,也可以點擊角色進入角色詳情頁勾選具體的用戶。還可以在左側(cè)上方搜索用戶名或者賬號出來用戶列表來勾選。其中,角色列表復(fù)選框、搜索用戶列表復(fù)選框、選中的用戶列表復(fù)選框,三者的選中狀態(tài)需要關(guān)聯(lián)(不勾選、半選、全選)。
代碼實現(xiàn):
父組件:
<div class="user-div" @click="openSelectUserDialog"> <template v-for="(item, index) in formValidate.sendUers"> <span class="user-item" :title="item" :key="index">{{ item.userName + '(' + item.userAccount + ')' }}</span></template > </div> <!--彈框--> <div> <SelectUser :selectUserDialogVisible="selectUserDialogVisible" :initUers="formValidate.sendUers" v-if="selectUserDialogVisible" @cancelSelectUser="cancelSelectUser" @changeSelectUser="changeSelectUser" ></SelectUser> </div> //選擇用戶彈框 openSelectUserDialog() { this.selectUserDialogVisible = true; }, //關(guān)閉用戶選擇彈框 cancelSelectUser() { this.selectUserDialogVisible = false; }, //選擇用戶 changeSelectUser(users) { this.formValidate.sendUers = users; this.cancelSelectUser(); },
子組件:
<!-- @format --> <template> <div> <el-dialog title="通訊錄" :visible.sync="dialogVisible" width="60%" @close="cancel"> <el-row class="user-row"> <el-col :span="12" class="department-user-col scoll-col"> <div class="header-query"> <el-input v-model="userNameOrAccount" ><i class="el-icon-search" slot="suffix" @click="queryUser"></i ></el-input> </div> <div class="department-user"> <!--用戶列表復(fù)選框--> <template v-if="queryUsers && queryUsers.length > 0"> <el-checkbox :indeterminate="userIsIndeterminate" @change="handleCheckAllUserChange" v-model="userCheckAll" >全選</el-checkbox > <el-checkbox-group v-model="checkedUserAccounts"> <el-checkbox v-for="user in queryUsers" :label="user.userAccount" :key="user.userAccount" @click.native="clickUser($event, user)" >{{ user.userName + '(' + user.userAccount + ')' }}</el-checkbox > </el-checkbox-group> </template> <!--角色復(fù)選框--> <template v-else> <el-checkbox :indeterminate="roleIsIndeterminate" @change="handleCheckAllRole" v-model="roleCheckAll" >全選</el-checkbox > <el-checkbox-group v-model="checkedRoleCodes" @change="handleCheckedRoleChange"> <template v-for="(role, index) in allRoles"> <el-checkbox :label="role.value" :key="role.value" @click.native="clickRole($event, role)" :indeterminate="role.indeterminate" >{{ role.text }} <a class="detail-btn" @click="clickToRoleDetail($event, role)" :key="index">詳情</a> </el-checkbox> </template> </el-checkbox-group> </template> </div> </el-col> <!--右側(cè)--> <el-col :span="12" class="user-col scoll-col"> <!--選中的用戶列表--> <div class="user-item" v-for="(user, index) in addUsers" :key="index"> {{ user.userName + '(' + user.userAccount + ')' }} <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="deleteAddUser(index)" class="delete-icon">X</a> </div> </el-col> </el-row> <span slot="footer" class="dialog-footer"> <el-button @click="cancel()">取 消</el-button> <el-button type="primary" @click="ok()">確 定</el-button> </span> </el-dialog> </div> </template> <script> export default { props: { selectUserDialogVisible: {}, //初始化的用戶列表 initUers: {} }, data() { return { dialogVisible: false, userNameOrAccount: '', //本界面的用戶列表 addUsers: [], //勾選的用戶賬號列表 checkedUserAccounts: [], //用戶列表 queryUsers: [], //所有可以選擇的用戶 //用戶多選框 userIsIndeterminate: true, userCheckAll: false, //角色列表 allRoles: [], //所有可以選擇的角色 //勾選的角色code checkedRoleCodes: [], //角色選擇復(fù)選框 roleIsIndeterminate: true, roleCheckAll: false //從角色列表中選擇的用戶 }; }, created() { this.init(); }, methods: { init() { this.findRoles(); this.addUsers = this.addUsers.concat(this.initUers); this.handleCheckedValue(); this.dialogVisible = this.selectUserDialogVisible; }, //從全量用戶中獲取勾選的賬號和角色編碼信息,去重 handleCheckedValue() { //勾選的用戶 this.handleCheckUser(); //勾選的角色 this.handleCheckRoleCode(); }, handleCheckUser() { let checkedUserAccounts = this.addUsers.map(function(item) { return item.userAccount; }); this.checkedUserAccounts = Array.from(new Set(checkedUserAccounts)); }, handleCheckRoleCode() { let checkedRoleCodes = this.addUsers.map(function(item) { return item.roleCode; }); this.checkedRoleCodes = Array.from(new Set(checkedRoleCodes)); }, findRoles() { this.$api['role/getAllRoles']({ }).then(data => { data.forEach(item => { item.indeterminate = false; }); this.allRoles = data; }); }, cancel() { this.dialogVisible = false; this.$emit('cancelSelectUser'); }, ok() { this.dialogVisible = false; //發(fā)送對象 = 初始化的用戶+用戶列表中選擇的用戶+角色列表選擇的用戶 this.$emit('changeSelectUser', this.addUsers); }, //角色全選/全部取消,全量 handleCheckAllRole(val) { if (val) { //全選 this.checkedRoleCodes = this.allRoles.map(function(item) { return item.value; }); this.getUsersByRoles(this.checkedRoleCodes).then(users => { this.addUsers = users; }); this.handleCheckUser(); } else { //取消全選 this.addUsers = []; this.checkedUserAccounts = []; this.checkedRoleCodes = []; } this.roleIsIndeterminate = false; }, //角色復(fù)選框點擊事件 clickRole(e, role) { // 因為原生click事件會執(zhí)行兩次,第一次在label標(biāo)簽上,第二次在input標(biāo)簽上,故此處理 if (e.target.tagName === 'INPUT' || e.target.tagName === 'A') return; let roleCode = role.value; if (this.checkedRoleCodes.indexOf(roleCode) === -1) { //選中 this.getUsersByRoles(new Array(roleCode)).then(users => { let addUsers = this.addUsers.concat(users); this.addUsers = this.unique(addUsers); }); } else { //取消 role.indeterminate = false; this.addUsers = this.addUsers.filter(function(item) { return item.roleCode !== roleCode; }); } this.handleCheckUser(); }, //角色詳情單擊事件詳情,取A標(biāo)簽的事件 clickToRoleDetail(e, role) { if (e.target.tagName !== 'A') return; let roleCode = role.value; //阻止選中 // this.checkedRoleCodes = this.checkedRoleCodes.filter(item => { // return item !== roleCode; // }); this.getUsersByRoles(new Array(roleCode)).then(users => { this.queryUsers = users; let addUsers = this.addUsers.concat(users); this.addUsers = this.unique(addUsers); this.handleCheckUser(); }); }, //角色選擇改變 handleCheckedRoleChange(roleCodes) { let checkedCount = roleCodes.length; let totalCount = this.allRoles.length; this.roleCheckAll = checkedCount === totalCount; this.roleIsIndeterminate = checkedCount > 0 && checkedCount < totalCount; }, async getUsersByRoles(roleCodes) { let roleCodeStr = roleCodes.join(','); let queryUsers = []; await this.$api['personDetail/listPersonnelDetailByPositionTypeCodes']({ positionTypeCodeList: roleCodeStr }).then(data => { queryUsers = data; }); return queryUsers; }, //搜索用戶 queryUser() { if (this.userNameOrAccount) { this.$api['personDetail/listPersonnelDetailByNameOrAccount']({ nameOrAccount: this.userNameOrAccount }).then(data => { this.queryUsers = data; }); } else { this.queryUsers = []; } }, //用戶全選,用戶是角色的子集,故用戶新增/刪除需要做比對 handleCheckAllUserChange(val) { if (val) { //全選,addUsers加上queryUsers,去重 this.addUsers = this.addUsers.concat(this.queryUsers); } else { //全部取消,addUsers去掉所有queryUsers let queryUserAccounts = this.queryUsers.map(function(item) { return item.userAccount; }); this.addUsers = this.addUsers.filter(function(item) { return queryUserAccounts.every(function(item1) { return item.userAccount !== item1; }); }); } this.addUsers = this.unique(this.addUsers); //復(fù)選框勾選綁定值改變 this.handleCheckedValue(); this.userIsIndeterminate = false; }, //用戶復(fù)選框點擊事件 clickUser(e, user) { // 因為原生click事件會執(zhí)行兩次,第一次在label標(biāo)簽上,第二次在input標(biāo)簽上,故此處理 if (e.target.tagName === 'INPUT' || e.target.tagName === 'A') return; let userAccount = user.userAccount; let roleCode = user.roleCode; if (this.checkedUserAccounts.indexOf(userAccount) === -1) { //選中 let addUser = this.queryUsers.find(item => { return item.userAccount === userAccount; }); this.addUsers.push(addUser); this.addUsers = this.unique(this.addUsers); } else { //取消 this.addUsers = this.addUsers.filter(function(item) { return item.userAccount !== userAccount; }); } //全選狀態(tài)改變 this.userAndRoleAllCheckStatusChange(); //角色選中值變化 this.handleCheckedValue(); //角色復(fù)選框選中狀態(tài)改變 this.roleUserCheckStatusChange(roleCode); }, //用戶、角色全選框選中狀態(tài)改變 userAndRoleAllCheckStatusChange() { //右側(cè)用戶列表包含左側(cè)復(fù)選框用戶列表,userCheckAll為true,userIsIndeterminate為false let userCheckAll = true; this.queryUsers.forEach(item => { if (this.checkedUserAccounts.indexOf(item.userAccount) < 0) { userCheckAll = false; return; } }); this.userCheckAll = userCheckAll; this.userIsIndeterminate = !this.userCheckAll; //角色 this.handleCheckedRoleChange(this.checkedRoleCodes); }, //角色復(fù)選框選中狀態(tài)改變 roleUserCheckStatusChange(roleCode) { this.allRoles.forEach(item => { if (item.value === roleCode) { if (this.checkedRoleCodes.indexOf(roleCode) !== -1) { item.indeterminate = true; } else { item.indeterminate = false; } } }); }, //去重 unique(arr) { var obj = {}; arr = arr.reduce(function(item, next) { obj[next.userAccount] ? '' : (obj[next.userAccount] = true && item.push(next)); return item; }, []); return arr; }, //刪除本次新增的用戶 deleteAddUser(index) { let deleteUser = this.addUsers[index]; let deleteUserAccount = deleteUser.userAccount; let roleCode = deleteUser.roleCode; //1、用戶復(fù)選框綁定值同步刪除 this.checkedUserAccounts = this.checkedUserAccounts.filter(function(value) { return value !== deleteUserAccount; }); //2、最后本次新增的用戶刪除 this.addUsers.splice(index, 1); //3、角色復(fù)選框綁定值同步變化 this.handleCheckRoleCode(); //4、用戶全選狀態(tài)改變 this.userAndRoleAllCheckStatusChange(); //5、角色選中狀態(tài)改變,設(shè)置已選且有刪除用戶操作的角色indeterminate為true this.roleUserCheckStatusChange(roleCode); } }, watch: { queryUsers: { handler: function(val) { this.userAndRoleAllCheckStatusChange(); } } } }; </script> <style scoped lang="less"> .user-row { .department-user-col { /deep/ .el-checkbox { color: #606266; font-weight: 500; font-size: 14px; cursor: pointer; user-select: none; margin-right: 30px; display: block; } .detail-btn { float: right; margin-left: 20px; } } .user-col { .user-item { margin-left: 10px; } .delete-icon { float: right; margin-right: 20px; } } //滾動條 .scoll-col { max-height: 300px; overflow-y: auto; } } </style>
已知問題:某角色先選中,然后刪除用戶,該角色變?yōu)榘脒x,如果該用戶通過搜索用戶列表的方式來單獨勾選或者全選重新加上,該角色的狀態(tài)仍為半選。因為需要全量判斷,性能較差。
2、舉例2:例1是從角色跳轉(zhuǎn)到用戶,現(xiàn)在再加一層關(guān)系,角色跳轉(zhuǎn)到區(qū)域(固定的省份),區(qū)域再調(diào)轉(zhuǎn)到用戶:
父組件:這里對角色、區(qū)域、區(qū)域復(fù)選框狀態(tài)做了一個緩存
<!-- @format --> <template> <div> <div class="container"> <el-form ref="formValidate" :model="formValidate" :rules="ruleValidate" label-position="left" label-width="100px"> <el-form-item :required="true"> <div class="user-div" @click="openSelectUserDialog"> <template v-for="(item, index) in formValidate.receiverList"> <span class="user-item" :title="item" :key="index">{{ item.userName + '(' + item.userAccount + ')' }}</span></template > </div> </el-form-item> </el-form> </div> <!--彈框--> <div> <SelectUser :selectUserDialogVisible="selectUserDialogVisible" :initUers="formValidate.receiverList" :cacheAllRoles="cacheAllRoles" :cacheAllRegions="cacheAllRegions" :cacheRoleRegionIndeterminateMap="cacheRoleRegionIndeterminateMap" v-if="selectUserDialogVisible" @cancelSelectUser="cancelSelectUser" @changeSelectUser="changeSelectUser" ></SelectUser> </div> </div> </template> <script> import SelectUser from './children/select-user'; export default { data() { return { // 表單數(shù)據(jù) formValidate: { receiverList: [] }, selectUserDialogVisible: false, //通訊錄緩存的角色信息 cacheAllRoles: [], //通訊錄緩存的區(qū)域信息 cacheAllRegions: [], //通訊錄緩存的區(qū)域復(fù)選框狀態(tài) cacheRoleRegionIndeterminateMap: {} }; }, methods: { //選擇用戶彈框 openSelectUserDialog() { this.selectUserDialogVisible = true; }, //關(guān)閉用戶選擇彈框 cancelSelectUser() { this.selectUserDialogVisible = false; }, //選擇用戶 changeSelectUser(users, cacheAllRoles, cacheAllRegions, cacheRoleRegionIndeterminateMap) { this.formValidate.receiverList = users; this.cancelSelectUser(); this.cacheAllRoles = cacheAllRoles; this.cacheAllRegions = cacheAllRegions; this.cacheRoleRegionIndeterminateMap = cacheRoleRegionIndeterminateMap; } } }, components: { SelectUser } }; </script>
子組件:右側(cè)用戶采用滾動加載
<!-- @format --> <template> <div> <el-dialog title="通訊錄" :visible.sync="dialogVisible" width="60%" @close="cancel"> <el-row class="user-row"> <el-col :span="12" class="role-region-user-col scoll-col"> <div class="header-query"> <el-input v-model.trim="userNameOrAccount" placeholder="輸入姓名/賬號" size="mini" ><i class="el-icon-search" slot="suffix" @click="searchUser"></i ></el-input> </div> <div class="role-region-user"> <!--錯誤提示--> <template v-if="isNoDataShow"> <p class="no-data">無搜索結(jié)果</p> </template> <!--正常數(shù)據(jù)--> <template v-else> <!--用戶列表復(fù)選框--> <template v-if="queryUsers && queryUsers.length > 0"> <el-row> <el-col :span="20"> <el-checkbox :indeterminate="userIsIndeterminate" @change="handleCheckAllUser" v-model="userCheckAll" >全選</el-checkbox > <el-checkbox-group v-model="checkedUserAccounts"> <el-checkbox v-for="user in queryUsers" :label="user.userAccount" :key="user.userAccount" @click.native="handleCheckUser($event, user)" @change="checkUserChange" >{{ user.userName + '(' + user.userAccount + ')' }}</el-checkbox > </el-checkbox-group></el-col > <el-col :span="2" v-if="isFromClickRegion"> <a @click="goBackToRegion($event)" class="goback-to-role" ><svg t="1628844742588" class="icon" viewBox="0 0 1482 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2061" width="40" height="40" > <path d="M584.884104 272.714912V0L0 477.152657l584.884104 477.073906V674.817811c406.119203 0 690.568023 108.991464 893.588249 347.528417-81.271091-340.755826-324.926863-681.354149-893.588249-749.631316" fill="#467CFD" p-id="2062" ></path></svg ></a> </el-col> </el-row> </template> <!--角色復(fù)選框--> <template v-else-if="!isRegionListShow"> <el-checkbox :indeterminate="roleIsIndeterminate" @change="handleCheckAllRole" v-model="roleCheckAll" >全選</el-checkbox > <el-checkbox-group v-model="checkedRoleCodes" @change="handleCheckedRoleChange"> <template v-for="(role, index) in allRoles"> <el-checkbox :label="role.value" :key="role.value" @click.native="handleCheckRole($event, role)" :indeterminate="role.indeterminate" >{{ role.text }} <a class="detail-btn" @click="clickRoleToRegionDetail($event, role)" :key="index">詳情</a> </el-checkbox> </template> </el-checkbox-group> </template> <!--區(qū)域復(fù)選框--> <template v-else> <el-row> <el-col :span="20"> <el-checkbox :indeterminate="roleRegionAllIndeterminateMap[currentClickRoleCode]" v-model="roleRegionAllCheckMap[currentClickRoleCode]" @change="handleCheckAllRegion" >全選</el-checkbox > <el-checkbox-group v-model="checkedRoleRegionsMap[currentClickRoleCode]"> <template v-for="(item, index) in allRegions"> <el-checkbox :label="item.value" :key="item.value" :indeterminate="roleRegionIndeterminateMap[currentClickRoleCode][item.value]" @click.native="handleCheckRegion($event, item.value)" >{{ item.value }} <a class="detail-btn" :key="index" @click="clickRegionToUserDetail($event, item.value)" >詳情</a > </el-checkbox> </template> </el-checkbox-group> </el-col> <el-col :span="2"> <a @click="goBackToRole($event)" class="goback-to-role" ><svg t="1628844742588" class="icon" viewBox="0 0 1482 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2061" width="40" height="40" > <path d="M584.884104 272.714912V0L0 477.152657l584.884104 477.073906V674.817811c406.119203 0 690.568023 108.991464 893.588249 347.528417-81.271091-340.755826-324.926863-681.354149-893.588249-749.631316" fill="#467CFD" p-id="2062" ></path></svg ></a> </el-col> </el-row> </template> </template> </div> </el-col> <!--右側(cè)--> <el-col :span="12" class="user-col"> <!--選中的用戶列表--> <!-- <div class="user-item" v-for="(user, index) in addUsers" :key="index"> {{ user.userName + '(' + user.userAccount + ')' }} <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="deleteAddUser(index)" class="delete-icon">X</a> </div> --> <div class="infinite-list-wrapper" style="overflow:auto"> <template> <p v-if="scrollUserLoading" class="load-user"><i class="el-icon-loading"></i></p> <ul class="infinite-list" v-infinite-scroll="scrollLoadUser" style="overflow:auto;height:300px"> <li v-for="i in scrollCount" class="infinite-list-item" :key="i" infinite-scroll-disabled="userScrollDisabled" > <div v-if="addUsers[i - 1]"> {{ addUsers[i - 1].userName + '(' + addUsers[i - 1].userAccount + ')' }} <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="deleteAddUser(i - 1)" class="delete-icon">X</a> </div> </li> </ul> </template> </div> </el-col> </el-row> <span slot="footer" class="dialog-footer"> <el-button @click="cancel()">取 消</el-button> <el-button type="primary" @click="ok()">確 定</el-button> </span> </el-dialog> </div> </template> <script> export default { props: { selectUserDialogVisible: {}, //初始化的用戶列表 initUers: {}, //緩存的角色列表,包含角色的半選狀態(tài) cacheAllRoles: {}, //緩存的區(qū)域列表 cacheAllRegions: {}, //緩存的區(qū)域復(fù)選框狀態(tài) cacheRoleRegionIndeterminateMap: {} }, data() { return { dialogVisible: false, userNameOrAccount: '', isNoDataShow: false, //右側(cè)的用戶列表 addUsers: [], //用戶列表復(fù)選框綁定值 checkedUserAccounts: [], //左側(cè)用戶復(fù)選框列表 queryUsers: [], //用戶復(fù)選列表全選框狀態(tài) userIsIndeterminate: true, userCheckAll: false, //角色列表 allRoles: [], //角色列表復(fù)選框綁定值 checkedRoleCodes: [], //角色復(fù)選列表全選框狀態(tài) roleIsIndeterminate: false, roleCheckAll: false, //區(qū)域列表 allRegions: [], allRegionCodes: [], //當(dāng)前點擊的角色 currentClickRole: '', currentClickRoleCode: '', isRegionListShow: false, //區(qū)域復(fù)選列表全選框狀態(tài) roleRegionAllIndeterminateMap: {}, roleRegionAllCheckMap: {}, //區(qū)域復(fù)選框綁定值,map:string->array,如{'管理員':['上海','北京']} checkedRoleRegionsMap: {}, //區(qū)域復(fù)選框狀態(tài),map:string->map,如{'管理員':{{'上海':true},{'北京':false}}} roleRegionIndeterminateMap: {}, //用戶列表來自區(qū)域詳情跳轉(zhuǎn)標(biāo)志 isFromClickRegion: false, //滾動加載 scrollCount: 0, scrollUserLoading: false }; }, created() { //獲取所有角色 this.findRoles().then(res => { //獲取所有區(qū)域 this.findRegions(); //初始化數(shù)據(jù)和勾選狀態(tài) this.init(); }); }, computed: { scrollUserNoMore() { return this.scrollCount >= this.addUsers.length; }, userScrollDisabled() { return this.scrollUserLoading || this.scrollUserNoMore; } }, methods: { scrollLoadUser() { //一次加載20條 let increaseCount = 20; let addAllCount = this.addUsers.length; if (this.scrollCount + increaseCount > addAllCount) { this.scrollCount = addAllCount; } else { this.scrollCount += increaseCount; } console.info('加載數(shù)據(jù):' + this.scrollCount); this.scrollUserLoading = false; }, init() { this.dialogVisible = this.selectUserDialogVisible; this.addUsers = this.addUsers.concat(this.initUers); this.handleCheckedValue(); this.handleCheckedRoleChange(this.checkedRoleCodes); this.roleRegionIndeterminateMap = this.cacheRoleRegionIndeterminateMap || {}; }, //處理用戶、角色、區(qū)域復(fù)選框綁定值和選擇狀態(tài) handleCheckedValue() { let checkedUserAccounts = []; let checkedRoleCodes = []; let checkedRoleRegionsMap = {}; this.addUsers.forEach(user => { let userAccount = user.userAccount; let roleCode = user.roleCode; let regionName = user.regionName; checkedUserAccounts.push(userAccount); checkedRoleCodes.push(roleCode); if (!checkedRoleRegionsMap[roleCode]) { checkedRoleRegionsMap[roleCode] = []; } else if (checkedRoleRegionsMap[roleCode].indexOf(regionName) === -1) { checkedRoleRegionsMap[roleCode].push(regionName); } }); //用戶列表復(fù)選框勾選 this.checkedUserAccounts = Array.from(new Set(checkedUserAccounts)); //角色列表復(fù)選框勾選 this.checkedRoleCodes = Array.from(new Set(checkedRoleCodes)); //角色-區(qū)域列表復(fù)選框勾選 this.checkedRoleRegionsMap = checkedRoleRegionsMap; }, handleCheckedUser() { let checkedUserAccounts = this.addUsers.map(function(item) { return item.userAccount; }); this.checkedUserAccounts = Array.from(new Set(checkedUserAccounts)); }, handleCheckedRoleCode() { let checkedRoleCodes = this.addUsers.map(function(item) { return item.roleCode; }); this.checkedRoleCodes = Array.from(new Set(checkedRoleCodes)); }, //處理區(qū)域綁定值和勾選狀態(tài) handleRegionCheckedAndStatus(deleteRegion) { //1、處理區(qū)域復(fù)選框綁定值與全選框狀態(tài) //角色選中 if (this.checkedRoleCodes.indexOf(this.currentClickRoleCode) > -1) { if (!this.currentClickRole.indeterminate) { //(1)全選狀態(tài) this.checkedRoleRegionsMap[this.currentClickRoleCode] = this.allRegionCodes; this.roleRegionAllCheckMap[this.currentClickRoleCode] = true; } else { //(2)半選狀態(tài) //獲取選擇的區(qū)域列表 let checkedRegions = this.addUsers.map(user => { if (user.roleCode === this.currentClickRoleCode) { return user.regionName; } }); if (checkedRegions.length === 0) { this.roleRegionAllCheckMap[this.currentClickRoleCode] = false; this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = false; } else { this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = true; } this.checkedRoleRegionsMap[this.currentClickRoleCode] = Array.from(new Set(checkedRegions)); } } else { this.checkedRoleRegionsMap[this.currentClickRoleCode] = []; this.roleRegionAllCheckMap[this.currentClickRoleCode] = false; this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = false; } //(3)其他情況,賦空值,防止空指針 if (!this.checkedRoleRegionsMap[this.currentClickRoleCode]) { this.checkedRoleRegionsMap[this.currentClickRoleCode] = new Array(); this.roleRegionAllCheckMap[this.currentClickRoleCode] = false; this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = false; } //2、處理區(qū)域復(fù)選框狀態(tài) let regionIndeterminateMap = {}; this.allRegionCodes.forEach(regionCode => { //區(qū)域是選中狀態(tài)且有刪除用戶操作,則狀態(tài)置為半選 if (this.checkedRoleRegionsMap[this.currentClickRoleCode].indexOf(regionCode) === -1) { //沒有勾選,為false regionIndeterminateMap[regionCode] = false; } else if (deleteRegion && regionCode === deleteRegion) { //勾選且本次被刪除了,為半選狀態(tài) console.info('刪除' + regionCode); regionIndeterminateMap[regionCode] = true; } else if (this.roleRegionIndeterminateMap && this.roleRegionIndeterminateMap[this.currentClickRoleCode]) { //使用原來的值 regionIndeterminateMap[regionCode] = this.roleRegionIndeterminateMap[this.currentClickRoleCode][regionCode]; } else { //其他情況 regionIndeterminateMap[regionCode] = false; } }); this.roleRegionIndeterminateMap[this.currentClickRoleCode] = regionIndeterminateMap; }, //獲取區(qū)域 findRegions() { if (this.cacheAllRegions && this.cacheAllRegions.length > 0) { this.allRegions = this.cacheAllRegions; this.allRegionCodes = this.allRegions.map(function(item) { return item.value; }); return; } //為空,第一次進入 this.$api['region/getRegions']().then(data => { this.allRegions = data; this.allRegionCodes = this.allRegions.map(function(item) { return item.value; }); }); }, //獲取角色 async findRoles() { if (this.cacheAllRoles && this.cacheAllRoles.length > 0) { this.allRoles = this.cacheAllRoles; return; } //為空,第一次進入,查詢接口 await this.$api['role/getRoles']().then(data => { data.forEach(item => { item.indeterminate = false; }); this.allRoles = data; }); }, cancel() { this.dialogVisible = false; this.$emit('cancelSelectUser'); }, ok() { this.dialogVisible = false; //發(fā)送對象 = 初始化的用戶+用戶列表中選擇的用戶+角色列表選擇的用戶 this.$emit('changeSelectUser', this.addUsers, this.allRoles, this.allRegions, this.roleRegionIndeterminateMap); }, //角色全選/全部取消,全量 handleCheckAllRole(val) { console.info('全選開始:' + new Date()); if (val) { //全選 this.scrollUserLoading = true; //1、處理角色多選 this.checkedRoleCodes = this.allRoles.map(function(item) { return item.value; }); this.getUsersByRoles(new Array()).then(users => { this.addUsers = users; }); //2、處理用戶多選 this.handleCheckedUser(); //3、處理區(qū)域多選、全選狀態(tài) this.checkedRoleCodes.forEach(roleCode => { this.checkedRoleRegionsMap[roleCode] = this.allRegionCodes; this.roleRegionAllCheckMap[roleCode] = true; this.roleRegionAllIndeterminateMap[roleCode] = false; }); } else { //取消全選 //1、處理角色多選 this.checkedRoleCodes = []; //2、處理用戶多選 this.addUsers = []; this.checkedUserAccounts = []; //3、處理區(qū)域多選、全選狀態(tài) this.checkedRoleRegionsMap = {}; this.roleRegionAllCheckMap = {}; this.roleRegionAllIndeterminateMap = {}; } //4、處理角色復(fù)選框狀態(tài) this.allRoles.forEach(function(item) { item.indeterminate = false; }); //5、處理角色全選框樣式 this.roleIsIndeterminate = false; console.info('全選結(jié)束:' + new Date()); }, //角色多選框勾選事件 handleCheckRole(e, role) { // 因為原生click事件會執(zhí)行兩次,第一次在label標(biāo)簽上,第二次在input標(biāo)簽上,故此處理 if (e.target.tagName === 'INPUT' || e.target.tagName === 'A') return; let roleCode = role.value; if (this.checkedRoleCodes.indexOf(roleCode) === -1) { //選中 //1、處理用戶多選 this.getUsersByRoles(new Array(roleCode)).then(users => { let addUsers = this.addUsers.concat(users); this.addUsers = this.uniqueUser(addUsers); }); this.handleCheckedUser(); //2、處理區(qū)域多選 this.checkedRoleRegionsMap[roleCode] = this.allRegionCodes; //3、處理角色-區(qū)域全選框狀態(tài) this.roleRegionAllCheckMap[roleCode] = true; this.roleRegionAllIndeterminateMap[roleCode] = false; } else { //取消 //1、處理用戶多選 this.addUsers = this.addUsers.filter(function(item) { return item.roleCode !== roleCode; }); this.handleCheckedUser(); //2、處理區(qū)域多選 this.checkedRoleRegionsMap[roleCode] = []; //3、處理角色復(fù)選框狀態(tài) role.indeterminate = false; //4、處理角色-區(qū)域全選框狀態(tài) this.roleRegionAllCheckMap[roleCode] = false; this.roleRegionAllIndeterminateMap[roleCode] = true; } }, //角色詳情單擊事件,取A標(biāo)簽的事件 clickRoleToRegionDetail(e, role) { if (e.target.tagName !== 'A') return; let roleCode = role.value; this.currentClickRoleCode = roleCode; this.currentClickRole = role; //初始化區(qū)域勾選值與勾選狀態(tài) this.handleRegionCheckedAndStatus(); this.isRegionListShow = true; }, //從區(qū)域列表返回到角色 goBackToRole(e) { //this.currentClickRoleCode = ''; this.isRegionListShow = false; }, //區(qū)域全選/全部取消事件 handleCheckAllRegion(val) { if (val) { //全選 this.getUsersByRoles(new Array(this.currentClickRoleCode)).then(users => { //1、處理用戶多選 let addUsers = this.addUsers.concat(users); this.addUsers = this.uniqueUser(addUsers); this.handleCheckedUser(); //2、處理角色多選 this.handleCheckedRoleCode(); }); //3、處理區(qū)域全選 this.checkedRoleRegionsMap[this.currentClickRoleCode] = this.allRegionCodes; } else { //取消全選 //3、處理區(qū)域多選 this.checkedRoleRegionsMap[this.currentClickRoleCode] = new Array(); this.$forceUpdate(); //1、處理用戶多選 let addUsers = this.addUsers.filter(user => { return user.roleCode !== this.currentClickRoleCode; }); this.addUsers = addUsers; this.handleCheckedUser(); //2、處理角色多選 this.checkedRoleCodes = this.checkedRoleCodes.filter(roleCode => { return roleCode !== this.currentClickRoleCode; }); } //4、處理角色全選框樣式 this.currentClickRole.indeterminate = false; this.roleIsIndeterminate = false; }, //區(qū)域勾選事件 handleCheckRegion(e, regionName) { // 原生click事件會執(zhí)行兩次,第一次在label標(biāo)簽上,第二次在input標(biāo)簽上 if (e.target.tagName !== 'INPUT') return; let checkRegions = this.checkedRoleRegionsMap[this.currentClickRoleCode]; if (checkRegions.indexOf(regionName) === -1) { //選中 this.getUsersByRoles(new Array(this.currentClickRoleCode), regionName).then(users => { //1、處理用戶多選 let addUsers = this.addUsers.concat(users); this.addUsers = this.uniqueUser(addUsers); this.handleCheckedUser(); //2、處理角色多選 this.handleCheckedRoleCode(); }); //3、處理角色多選狀態(tài);處理區(qū)域全選狀態(tài) if (checkRegions.length === this.allRegionCodes.length - 1) { //區(qū)域全部選中 this.currentClickRole.indeterminate = false; this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = false; } else { this.currentClickRole.indeterminate = true; this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = true; } } else { //取消,強制改變值 checkRegions = checkRegions.filter(item => { return item !== regionName; }); this.checkedRoleRegionsMap[this.currentClickRoleCode] = checkRegions; //1、處理用戶多選 let addUsers = this.addUsers.filter(item => { return !(item.roleCode === this.currentClickRoleCode && item.regionName === regionName); }); this.addUsers = addUsers; this.handleCheckedUser(); //2、處理角色多選、多選狀態(tài);處理區(qū)域全選狀態(tài) if (checkRegions.length === 0) { this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = false; this.checkedRoleCodes = this.checkedRoleCodes.filter(roleCode => { return roleCode !== this.currentClickRoleCode; }); } else { this.currentClickRole.indeterminate = true; this.roleRegionAllIndeterminateMap[this.currentClickRoleCode] = true; } } }, //區(qū)域詳情單擊事件 clickRegionToUserDetail(e, regionName) { if (e.target.tagName !== 'A') return; //阻止選中 e.preventDefault(); this.isFromClickRegion = true; this.getUsersByRoles(new Array(this.currentClickRoleCode), regionName).then(users => { this.queryUsers = users; }); }, //角色選擇改變 handleCheckedRoleChange(roleCodes) { let checkedCount = roleCodes.length; let totalCount = this.allRoles.length; this.roleCheckAll = checkedCount === totalCount; this.roleIsIndeterminate = checkedCount > 0 && checkedCount < totalCount; }, async getUsersByRoles(roleCodes, regionName) { let roleCodeStr = ''; if (roleCodes && roleCodes.length > 0) { roleCodeStr = roleCodes.join(','); } let queryUsers = []; await this.$api['user/getUserByRoleAndRegion']({ roleCodes: roleCodeStr, region: regionName }).then(data => { queryUsers = data; }); return queryUsers; }, //搜索用戶 searchUser() { if (this.userNameOrAccount) { this.$api['user/getByNameOrAccount']({ nameOrAccount: this.userNameOrAccount }).then(data => { this.queryUsers = data; if (data.length === 0) { this.isNoDataShow = true; } else { this.isNoDataShow = false; } }); this.isFromClickRegion = false; } else { this.isNoDataShow = false; this.queryUsers = []; this.isRegionListShow = false; } }, //從用戶列表返回到區(qū)域 goBackToRegion(e) { this.queryUsers = []; this.isRegionListShow = true; this.handleRegionCheckedAndStatus(); }, //用戶全選,這里選中的用戶是整體用戶的子集 handleCheckAllUser(val) { let queryRoleCodes = this.queryUsers.map(user => { return user.roleCode; }); if (val) { //全選 //1、處理用戶多選 let addUsers = this.addUsers.concat(this.queryUsers); this.addUsers = this.uniqueUser(addUsers); this.handleCheckedUser(); //2、處理角色多選框狀態(tài),新增的角色設(shè)為半選 this.allRoles.forEach(role => { let roleCode = role.value; if (queryRoleCodes.indexOf(roleCode) >= 0 && this.checkedRoleCodes.indexOf(roleCode) === -1) { role.indeterminate = true; } }); //3、處理角色多選 this.handleCheckedRoleCode(); } else { //全部取消 //1、處理用戶多選 let queryUserAccounts = this.queryUsers.map(function(item) { return item.userAccount; }); let addUsers = this.addUsers.filter(function(item) { return queryUserAccounts.every(function(item1) { return item.userAccount !== item1; }); }); this.addUsers = this.uniqueUser(addUsers); this.handleCheckedUser(); //2、處理角色多選 this.handleCheckedRoleCode(); //3、處理角色多選框狀態(tài),取消的角色去除選擇狀態(tài) this.allRoles.forEach(role => { let roleCode = role.value; if (queryRoleCodes.indexOf(roleCode) >= 0 && this.checkedRoleCodes.indexOf(roleCode) >= 0) { role.indeterminate = true; } else { role.indeterminate = false; } }); } //4、用戶全選樣式改變 this.userIsIndeterminate = false; //5、點擊后回到角色列表頁 if (!this.isFromClickRegion) { this.queryUsers = []; this.isRegionListShow = false; } }, //用戶復(fù)選框點擊事件 handleCheckUser(e, user) { // 原生click事件防止執(zhí)行多次 if (e.target.tagName !== 'SPAN') return; let userAccount = user.userAccount; let roleCode = user.roleCode; let regionName = user.regionName; if (this.checkedUserAccounts.indexOf(userAccount) === -1) { //選中 //1、處理用戶 let addUser = this.queryUsers.find(item => { return item.userAccount === userAccount; }); this.addUsers.push(addUser); this.addUsers = this.uniqueUser(this.addUsers); //2、處理角色多選、角色復(fù)選框選擇狀態(tài) this.handleCheckedRoleCode(); this.handleCheckedRoleChange(this.checkedRoleCodes); //3、角色復(fù)選框選中狀態(tài)改變 this.roleCheckStatusChange(roleCode); } else { //取消 //1、處理用戶 this.addUsers = this.addUsers.filter(function(item) { return item.userAccount !== userAccount; }); //2、處理角色多選、角色復(fù)選框選擇狀態(tài) this.handleCheckedRoleCode(); this.handleCheckedRoleChange(this.checkedRoleCodes); //3、角色復(fù)選框選中狀態(tài)改變 this.roleCheckStatusChange(roleCode); //4、處理區(qū)域復(fù)選框 this.handleRegionCheckedAndStatus(regionName); } //點擊后回到角色列表頁 if (!this.isFromClickRegion) { this.queryUsers = []; this.isRegionListShow = false; } }, checkUserChange(checkedUserAccounts) { //右側(cè)用戶列表包含左側(cè)復(fù)選框用戶列表,userCheckAll為true,userIsIndeterminate為false let isUserCheckAll = true; let isUserCheck = false; //是否都選中了,有一個沒選擇則為false this.queryUsers.forEach(item => { if (this.checkedUserAccounts.indexOf(item.userAccount) < 0) { isUserCheckAll = false; return; } }); //是否沒選擇的,有一個選擇則為true this.queryUsers.forEach(item => { if (this.checkedUserAccounts.indexOf(item.userAccount) >= 0) { isUserCheck = true; return; } }); this.userCheckAll = isUserCheckAll; if (isUserCheck && !isUserCheckAll) { //有勾選,全選才會存在半選狀態(tài) this.userIsIndeterminate = true; } else { this.userIsIndeterminate = false; } }, //用戶、角色全選框選中狀態(tài)改變 userAndRoleAllCheckStatusChange() { this.checkUserChange(this.checkedUserAccounts); //角色復(fù)選框選中狀態(tài)改變 this.handleCheckedRoleChange(this.checkedRoleCodes); }, //角色復(fù)選框選中狀態(tài)改變 roleCheckStatusChange(roleCode) { this.allRoles.forEach(item => { if (item.value === roleCode) { if (this.checkedRoleCodes.indexOf(roleCode) !== -1) { item.indeterminate = true; } else { item.indeterminate = false; } } }); }, //去重 uniqueUser(arr) { var obj = {}; arr = arr.reduce(function(item, next) { obj[next.userAccount] ? '' : (obj[next.userAccount] = true && item.push(next)); return item; }, []); return arr; }, //刪除本次新增的用戶 deleteAddUser(index) { let deleteUser = this.addUsers[index]; let deleteUserAccount = deleteUser.userAccount; let roleCode = deleteUser.roleCode; let regionName = deleteUser.regionName; //1、用戶復(fù)選框綁定值同步刪除 this.checkedUserAccounts = this.checkedUserAccounts.filter(function(value) { return value !== deleteUserAccount; }); //2、最后本次新增的用戶刪除 this.addUsers.splice(index, 1); //3、角色復(fù)選框綁定值同步變化 this.handleCheckedRoleCode(); //4、用戶全選狀態(tài)改變 this.userAndRoleAllCheckStatusChange(); //5、角色選中狀態(tài)改變,設(shè)置已選且有刪除用戶操作的角色indeterminate為true this.roleCheckStatusChange(roleCode); //6、區(qū)域選擇情況 this.handleRegionCheckedAndStatus(regionName); } }, watch: { queryUsers: { handler: function(val) { if (val && val.length > 0) { this.handleCheckedValue(); this.userAndRoleAllCheckStatusChange(); } } }, addUsers: { handler: function(val) { if (val && val.length > 0) { this.scrollLoadUser(); } } } } }; </script> <style scoped lang="less"> .role-region-user { .goback-to-role { //margin-right: 10px; } .no-data { color: red; } } .user-row { .role-region-user-col { /deep/ .el-checkbox { color: #606266; font-weight: 500; font-size: 14px; cursor: pointer; user-select: none; margin-right: 30px; display: block; } .detail-btn { float: right; margin-left: 20px; } } .user-col { .user-item { margin-left: 10px; } .delete-icon { float: right; margin-right: 20px; } .load-user { text-align: center; /deep/ .el-icon-loading { font-size: 30px; } } } //滾動條 .scoll-col { max-height: 300px; overflow-y: auto; } } </style>
從性能角度考慮,已知問題:
(1)左側(cè)用戶列表勾選操作,對應(yīng)的角色不會由半選變?yōu)槿x:如某角色先選中,再刪除右側(cè)某一人員,該角色變?yōu)榘脒x狀態(tài),再通過左側(cè)用戶列表單獨勾選或者全選的方式加上該用戶,該角色的狀態(tài)仍為半選;
(2)區(qū)域上方的全選框可以區(qū)分全選和半選,而每個區(qū)域的復(fù)選框不能嚴格區(qū)分半選和全選:
如執(zhí)行用戶添加動作,對應(yīng)的區(qū)域均為全選,執(zhí)行用戶刪除操作時,所屬區(qū)域狀態(tài)變?yōu)榘脒x,再次添加上刪除的用戶,區(qū)域仍為半選
到此這篇關(guān)于Vue3+ElementUI 多選框中復(fù)選框和名字點擊方法效果分離的文章就介紹到這了,更多相關(guān)Vue3 ElementUI 多選框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 關(guān)于extjs treepanel復(fù)選框選中父節(jié)點與子節(jié)點的問題
- vue基于element-ui的三級CheckBox復(fù)選框功能的實現(xiàn)代碼
- vue+element UI實現(xiàn)樹形表格帶復(fù)選框的示例代碼
- vuejs+element UI table表格中實現(xiàn)禁用部分復(fù)選框的方法
- element的el-tree多選樹(復(fù)選框)父子節(jié)點關(guān)聯(lián)不關(guān)聯(lián)
- el-table?選中行與復(fù)選框相互聯(lián)動的實現(xiàn)步驟
- 使用element組件table表格實現(xiàn)某條件下復(fù)選框無法勾選
- Vue el-table復(fù)選框全部勾選及勾選回顯功能實現(xiàn)
- el-table表格點擊該行任意位置時也勾選上其前面的復(fù)選框
相關(guān)文章
解決Mint-ui 框架Popup和Datetime Picker組件滾動穿透的問題
這篇文章主要介紹了解決Mint-ui 框架Popup和Datetime Picker組件滾動穿透的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11淺談angular4.0中路由傳遞參數(shù)、獲取參數(shù)最nice的寫法
下面小編就為大家分享一篇淺談angular4.0中路由傳遞參數(shù)、獲取參數(shù)最nice的寫法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03vue3中element-plus?Upload上傳文件代碼示例
這篇文章主要介紹了vue3中element-plus?Upload上傳文件的相關(guān)資料,在時間開發(fā)中上傳文件是經(jīng)常遇到的一個需求,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-08-08iview-table組件嵌套input?select數(shù)據(jù)無法雙向綁定解決
這篇文章主要為大家介紹了iview-table組件嵌套input?select數(shù)據(jù)無法雙向綁定解決示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09解決Element組件的坑:抽屜drawer和彈窗dialog
這篇文章主要介紹了解決Element組件的坑:抽屜drawer和彈窗dialog問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07