preface

It’s so depressing and I have to share it

First effect:

Problem resolution and resolution

The project uses the Element component library. When I first saw the design, I wanted to implement it with tree components. But later found that the visible page and the function of the selected permissions are actually irrelevant. One controls whether a page is visible, and the other determines what can be done to the page.

So they are divided into two pieces, with multi-check box + multi-check box group implementation

Let’s look at the green section first, which has the detailed code here:

1. The top multi-check box controls the remaining multi-check boxes, so when clicking “Visible page”, you need to control the checked and unchecked status of other multi-check boxes.

2. When a “page name X” checkbox is selected, the top checkbox should become indeTerminate.

3. If no page is selected, the upper-layer multiple check box is unselected.

4. If all pages are selected, the upper-layer box is selected.

You can do this by listening for the change event

The page structure looks like this:

<div class="range-page-checkbox"> <div class="root-title"> <el-checkbox v-model="checkPageAll" :indeterminate="isPageCheckAll" @change="handlePageCheckAllChange" > Visible page </el-checkbox> </div> <el-checkbox-group v-model="checkedPages" @change="handlePageCheckChange" > <el-checkbox v-for="item in pageData" :key="item.id" :label="item.id" > {{ item.label }} </el-checkbox> </el-checkbox-group> </div>Copy the code

To deal with problem 1, listen for the change event to trigger handlePageCheckAllChange, telling you that the checkbox for “optional pages” has been clicked. The parameter val tells you whether the current state of the “optional page” is selected or not, and then proceed to the next step.

handlePageCheckAllChange(val) {
      this.checkedPages = val ? this.pageDataKey : [];
      this.isPageCheckAll = false;
}
Copy the code

Question 234, which also listens to the change event trigger handlePageCheckChange to get all the selected “page names x”

HandlePageCheckChange (pages) {this.checkPageAll = pages. Length === this.pageData.length; this.isPageCheckAll = pages.length > 0 && pages.length < this.pageData.length; }Copy the code

The actual operation of the blue part is the same as that of the green module, but the blue part can only be selected when the green part is selected.

Therefore, I improved the data structure of pageData

Export const pageData = [{id: 111, / / page id, a unique identifier of the page. Label: 'the name of the page 1', / / the name of the page handleChecked: [0, 1], // page operation box checked permissions, refer to handleData ischecked: true, // whether the page ischecked, if the property is flase, can not operate function permissions multi-check box},... Export const handleData = [{key: 0, label: 'add '}, {key: 1, label:' modify '}, {key: 2, label: 'delete '}, {key: 3, label: 'View '},]Copy the code

The blue part needs to loop according to the value of pageData. The page structure and data structure are as follows

<div class="range-handle-checkbox"> <div class="root-title"> <div v-for="(_, index) in pageData" :key="pageData[index].id" class="handle-box" > <el-checkbox v-model="isHandleCheckAll[index].isCheckAll" :indeterminate="isHandleCheckAll[index].isIndeterminate" :disabled="! pageData[index].ischecked" @change="(val) => handleCheckAllChange(val, Index)" > </ el-checkbox-group v-model="isHandleCheckAll[index]. CheckedHandle "@change="(handles) => handleCheckChange(handles, index)" > <el-checkbox v-for="item in handleData" :key="item.key" :label="item.key" :disabled="! pageData[index].ischecked" > {{ item.label }} </el-checkbox> </el-checkbox-group> </div> </div>Copy the code
IsHandleCheckAll: [{id: 111, // page id, or whatever else, isIndeterminate: IsCheckAll :false; // Checkall: true; // Checkall :false; // CheckHandle :false; [], // All selected operations, label value},...Copy the code

The two functions that listen for change are the same as those in green, except that they operate on the array items. The ID and checkedHandle in the isHandleCheckAll array are determined by pageData

getIsHandleCheckAll(data) { const result = []; data.forEach((item) => { const temp = {}; let length = 0; temp.id = item.id; temp.checkedHandle = Clone(item.handleChecked); length = temp.checkedHandle.length; temp.isIndeterminate = !! ( length > 0 && length < this.handleDataKey.length ); (temp.isCheckAll = length === this.handleDataKey.length), result.push(temp); }); return result; }Copy the code

In order to select the green part and trigger the blue part optionally, you need to add some code to handlePageCheckChange.

ForEach ((_, index) => {this.$set(this.pageData[index], 'ischecked', false); }); ForEach ((I) => {const index = this.pagedata.findIndex ((item) => {return item.id === i; }); this.$set(this.pageData[index], 'ischecked', true); });Copy the code

Finally, update the blue checkedHandle to pageData

GetNewPageData () {getNewPageData() {getNewPageData() {getNewPageData() {getNewPageData() {getNewPageData() {getNewPageData(); Assign the checkedHandle of the corresponding item in isHandleCheckAll to handleChecked, False Yes [] this.pageData.foreach ((item, index) => { if (item.ischecked) { item.handleChecked = this.$utils.easyDeepClone( this.isHandleCheckAll[index].checkedHandle ); } else { item.handleChecked = []; }}); }Copy the code

\