vue如何能做到点击其他地方input不失去焦点

我想写一个省市的选择框做成类似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>

运行的结果如下图:

clipboard.png

当点击下面的弹出层的时候直接失去焦点就消失了,造成根本选不了的结果

我想要的结果是这种点击弹出的东西文本框不会失去焦点的样子,如截图:

clipboard.png

点击年份文本框是不会失去焦点的这种,但是想半天一直没找到好用的实现思路,希望有大神能帮忙指点下思路,非常感谢!

阅读 14.6k
4 个回答

不要在blur事件监听隐藏,换个思维。
应该在city-select-picker这个元素监听mouseleave事件,鼠标离开这个元素则隐藏;或者是监听页面mousedown事件,点击的target不在city-select-picker中则隐藏。

你点击的时候,先触发了文本框的失去焦点事件,然后才是你的点击事件,你可以让它重新获得焦点,不太好;
可以在点击外层的时候,再让弹出的框隐藏,就可以不用focus来控制显示隐藏了

input加上ref
cityClick事件最后加上this.$refs.input.foucs()

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题