我想写一个省市的选择框做成类似iview中picker那种,但是在写的时候发现,使用focus事件控制列表显示/隐藏切换不好用,查了半天没找到好的解决办法
下面是我的代码:
<template>
<span class="city-select-picker">
<!-- <label class="offset-l30"><span class="redFont">*</span>工作城市:</label> -->
<Input @on-focus="cityFocus(true)" @on-blur="cityFocus(false)" v-model="workCity.city" style="width: 170px"/>
<ul v-if="citylistshow===true" class="provice-list">
<li @click="provinceClick(item.province,$event)" v-for="item in cityList" :data-provcode="item.province_code" :key="item.province_code" class="provice-item" :class="[selprovice===item.province?'proactive':'']">{{item.province}}
<ul v-if="selprovice===item.province" class="city-list">
<li @click="cityClick(item.city_label,$event)" v-for="item in item.citys" :data-citycode="item.city_code" :key="item.city_code" class="city-item" :class="[selcity===item.city_label?'proactive':'']">{{item.city_label}}</li>
</ul>
</li>
</ul>
</span>
</template>
<script>
export default {
name: "cityDicker",
data() {
return {
citylistshow: false, // 城市选择面板
selprovice: "",
selcity: "",
workCity: "",
cityList: [
{
province: "北京",
province_code: "001",
citys: [
{
city_label: "北京市",
city_code: "001001"
},
{
city_label: "北京郊区",
city_code: "001002"
}
]
},
{
province: "上海",
province_code: "002",
citys: [
{
city_label: "上海市",
city_code: "002001"
},
{
city_label: "其他",
city_code: "002002"
}
]
},
{
province: "深圳",
province_code: "003",
citys: [
{
city_label: "深圳",
city_code: "003001"
},
{
city_label: "其他",
city_code: "003002"
}
]
}
]
};
},
methods: {
cityFocus(flag) {
if (this.cityfocus === true) {
this.cityfocus = false;
} else {
this.citylistshow = flag;
console.log(this.citylistshow);
}
},
provinceClick(prov, e) {
this.citylistshow = true;
if (this.selprovice === prov) {
this.selprovice = "";
} else {
this.selprovice = prov;
}
},
cityClick(prov, e) {
if (this.selcity === prov) {
this.selcity = "";
this.workCity = "";
} else {
this.selcity = prov;
this.workCity = {
provice: this.selprovice,
city: this.selcity,
citycode: e.target.dataset.citycode
};
}
this.$emit("getWorkerCity", this.workCity);
console.log(this.workCity);
}
}
};
</script>
<style lang="less">
.city-select-picker {
display: inline-block;
position: relative;
z-index: 100;
.provice-list {
position: absolute;
background-color: #fff;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
border-radius: 4px;
padding: 0 5px;
width: 500px;
left: 0;
top: 37px;
.provice-item {
display: inline-block;
padding: 3px 5px;
background-color: #f4f4f4;
margin: 10px 5px;
&:hover {
background-color: #e0e0e0;
}
}
}
.city-list {
position: absolute;
width: 500px;
left: 0;
margin-top: 10px;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
padding: 0 5px 10px;
background-color: #fff;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
.city-item {
display: inline-block;
padding: 3px 5px;
background-color: #f4f4f4;
margin: 5px;
&:hover {
background-color: #e0e0e0;
}
}
}
.proactive {
background-color: #e0e0e0 !important;
}
}
</style>
运行的结果如下图:
当点击下面的弹出层的时候直接失去焦点就消失了,造成根本选不了的结果
我想要的结果是这种点击弹出的东西文本框不会失去焦点的样子,如截图:
点击年份文本框是不会失去焦点的这种,但是想半天一直没找到好用的实现思路,希望有大神能帮忙指点下思路,非常感谢!
不要在blur事件监听隐藏,换个思维。
应该在city-select-picker这个元素监听mouseleave事件,鼠标离开这个元素则隐藏;或者是监听页面mousedown事件,点击的target不在city-select-picker中则隐藏。