In the process of a project development, components similar to Cascader were needed, but the cascading selector was arranged horizontally, and the STYLE given by UI was arranged vertically (as shown below). Therefore, element’s Tree and Select components were used for secondary packaging. Implements the following functions to support single and multiple tree selection
Implementation code:
<div class="my-select">
<el-select :value="value" :multiple="multiple" placeholder="Please select" @remove-tag="removeTag"
:clearable="clearable" @clear="clearHandle">
<el-option :value="value">
<el-tree
id="tree-option"
ref="selectTree"
:accordion="accordion"
:data="treeData"
:props="defaultProps"
show-checkbox
:expand-on-click-node="false"
:node-key="defaultProps.value"
:check-strictly="true"
@check="handleNodeClick"
@check-change="handleCheckChange"
></el-tree>
</el-option>
</el-select>
</div>
Copy the code
// Style changes.my-select {
//display: flex;
//flex-direction: column;
//align-items: center;
}
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
height: auto;
padding: 0;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item.selected {
font-weight: normal;
}
ul li >>> .el-tree .el-tree-node__content {
height: auto;
padding: 0 20px;
}
.el-tree-node__label {
font-weight: normal;
}
.el-tree >>> .is-current .el-tree-node__label {
color: #409eff;
font-weight: 700;
}
.el-tree >>> .is-current .el-tree-node__children .el-tree-node__label {
color: # 606266;
font-weight: normal;
}
/deep/ .el-select {
width: 100% ! important;
}
Copy the code
To implement this, define props and accept parameters passed from the parent component
props: {
/* Configuration options */
defaultProps: {
type: Object.default: () = > {
return {
value: "id".// ID field name
label: "label".// Display the name
children: 'children' // Subfield name}}},/* Display data */
treeData: {
type: Array.default: () = >[]},/* Can clear options */
clearable: {
type: Boolean.default: () = > true
},
/* Automatically fold */
accordion: {
type: Boolean.default: () = > true
},
/* Optional initial value */
radioValue: {
type: String.default: () = > ' '
},
/* Multiple initial values */
multipleValues: {
type: Array.default: () = >[]},/* Select */
multiple: {
type: Boolean.default: () = > true}}Copy the code
Determine whether multiple or single options are available when initializing the loading component
mounted() {
// If the parent passes a multiple value of true, it is a single component. If the parent passes a multiple value, it calls the corresponding method to initialize the default data
this.multiple ? this.radioInit() : this.multipleInit();
}
Copy the code
Next, implement the corresponding method: initialize the default value
// Select multiple default values for initialization. If a default value is passed, the default value is displayed
multipleInit() {
// If a default value is passed, render it into the component
if (this.multipleValues.length > 0) {
this.$refs.selectTree.setCheckedKeys(this.multipleValues);
this.selectedNodes = this.$refs.selectTree.getCheckedNodes();
this.value = this.selectedNodes.map(item= > item[this.defaultProps.label]); }},// Initialize the radio option default value
radioInit() {
if (this.radioValue) {
this.$refs.selectTree.setCheckedKeys([this.radioValue]);
this.selectedNodes = this.$refs.selectTree.getCheckedNodes();
this.value = this.selectedNodes[0] [this.defaultProps.label]; }}Copy the code
Method of toggling options
handleNodeClick(node, el) {
this.selectedNodes = el.checkedNodes;
if (this.multiple) {
/ / multi-select
this.value = el.checkedNodes.map(item= > item[this.defaultProps.label]);
} else {
/ / radio
this.value = el.checkedNodes[0] [this.defaultProps.label]; }}Copy the code
Remove options
// Remove options (single remove)
removeTag(tag) {
let arr = this.selectedNodes.filter(item= > item[this.defaultProps.label] === tag);
this.$refs.selectTree.setChecked(arr[0].id, false);
this.value.splice(this.value.indexOf(tag), 1);
},
// Clear the selected items (clear all)
clearHandle() {
if (this.multiple) {
this.value = [];
} else {
this.value = ' ';
}
this.$refs.selectTree.setCheckedKeys([]);
}
Copy the code
$emit ejects this event to the parent component to retrieve the selected id
getCheckedKeys() {
return this.$refs.selectTree.getCheckedKeys()
},
// Call back when the node status changes
handleCheckChange(data, checked) {
if (!this.multiple && checked === true) {
/ / radio
this.$refs.selectTree.setCheckedNodes([data]); }}Copy the code