1 初步想法剛開始選用了el-select中在option裏嵌套一個el-tree樹形控件,發現有問題,當點擊非文字區域或者框的時候,el-select中會出現錯誤信息,如下:
此問題沒解決掉,就換了另一種思路,用el-input框模仿實現一個el-select下拉框方案,發現可行,解決方法效果圖如下:
直接上代碼,代碼方法如下:
<template>
<div v-clickoutside="handleClickOutside" style="width:200px">
<el-input
style="width:200px"
v-model="carSelectParam"
placeholder="請選擇車輛"
readonly
@click.native="handleInput"
:suffix-icon="icon"
></el-input>
<div style="position:absolute;z-index: 3333;" v-show="treeShowFlag">
<div class="aaa"></div>
<div class="numberScreening">
<div style="display:flex;flex-direction:row" class="traceScreeningMb">
<el-input
placeholder="輸入關鍵字進行過濾"
v-model="filterText"
class="inputBg"
style="width:280px"
></el-input>
<el-button
@click="hangleSearchVehicle"
style="background-color:#006BFF;width:20px;line-height:40px"
>
<img src="@/image/search.png">
</el-button>
</div>
<el-tree
class="numberScreeningTree fontSize12"
:data="datas"
show-checkbox
highlight-current
:props="defaultProps"
@check-change="handleCheckChange"
:filter-node-method="filterNode"
ref="tree"
:render-content="renderContent"
></el-tree>
</div>
</div>
</div>
</template>
<script>
import carDatas from "@/datas/cars.js";
import eventBus from "@/assets/eventBus";
import requestUrl from "@/api/Waybill";
import request from "@/utils/request";
import Clickoutside from "element-ui/src/utils/clickoutside";
import "@/utils/directives.js";
let arrList = [];
export default {
data() {
return {
treeShowFlag: false,
filterText: "",
datas: null,
defaultProps: {
children: "children",
label: "label"
},
carSelectParam: "",
icon: "el-icon-arrow-down",
vehicleIds: []
};
},
mounted() {
this.organizationDataTree();
},
directives: { Clickoutside },
methods: {
handleClickOutside() {
this.treeShowFlag = false;
},
handleInput() {
this.treeShowFlag = !this.treeShowFlag;
if (this.treeShowFlag == true) {
this.icon = "el-icon-arrow-up";
} else {
this.icon = "el-icon-arrow-down";
}
},
hangleSearchVehicle() {
this.$refs.tree.filter(this.filterText);
},
// 調用車輛結構的數據
organizationDataTree() {
const url = requestUrl.carsInfo;
const organizationId = localStorage.getItem("organizationId");
let params = {};
let requestBody = {};
requestBody.organizationId = organizationId;
params.requestBody = requestBody;
request.post(url, params, "json").then(res => {
if (res.data) {
this.datas = res.data;
}
});
},
handleCheckChange() {
let res = this.$refs.tree.getCheckedNodes(true, true); //這裏兩個true,1. 是否只是葉子節點 2. 是否包含半選節點(就是使得選擇的時候不包含父節點)
arrList = []; //存放數組車牌和車牌id的list
let arrLabel = [];
let arr = [];
res.forEach(item => {
if (item.vehicleId != null) {
arrLabel.push(item.label);
arr.push(item.vehicleId);
}
});
arrList.push({ licensePlate: arrLabel, vehicleIds: arr });
this.editSelectedCars(arrList);
},
editSelectedCars(datas) {
this.carSelectParam = "";
if (datas[0].licensePlate.length == 0) {
this.carSelectParam = "";
} else if (datas[0].licensePlate.length == 1) {
this.carSelectParam = datas[0].licensePlate[0];
} else {
this.carSelectParam =
datas[0].licensePlate[0] +
" " +
"+" +
(datas[0].licensePlate.length - 1);
}
this.vehicleIds = [];
for (let i = 0; i < datas[0].vehicleIds.length; i++) {
this.vehicleIds.push(datas[0].vehicleIds[i]);
}
this.licensePlateArrs = datas[0].licensePlate;
},
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
renderContent(h, { node, data, store }) {
if (data.vehicleId == null) {
return (
<span class="custom-tree-node carImage">
<img
src={require("@/image/orgVehicles.png")}
style="margin-right:8px"
/>
<span>{node.label}</span>
</span>
);
} else {
return (
<span class="custom-tree-node carImage">
<img
src={require("@/image/vehicle.png")}
style="margin-right:8px"
/>
<span>{node.label}</span>
</span>
);
}
}
}
};
</script>
<style>
.numberScreening {
height: 460px;
width: 320px;
padding: 10px;
background-color: #fff;
display: flex;
flex-direction: column;
box-shadow: 1px 2px 8px 1px rgba(0, 0, 0, 0.2);
}
.numberScreening .numberScreeningTree {
height: 420px;
overflow: auto;
width: 300px;
}
.numberScreening .numberScreeningTree .carImage {
display: flex;
flex-direction: row;
align-items: center;
margin: 5px 0px;
}
.aaa {
width: 0px;
margin-left: 60px;
border-width: 6px;
border-style: solid;
border-color: transparent transparent #006bff transparent;
}
.confirmSelectCar {
display: flex;
justify-content: center;
padding-top: 20px;
}
</style>
使用vue的Clickoutside,來控制在下拉框外部點擊時,彈框進行收起狀態。