How can vue click on other places without losing focus on input

I want to write a provincial and municipal selection box to make it similar to picker in iview, but when I write, I find that using the focus event control list to show / hide the switch is not easy to use. After searching for a long time, I can"t find a good solution

here is my code:

<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: -sharpfff;
    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: -sharpf4f4f4;
      margin: 10px 5px;
      &:hover {
        background-color: -sharpe0e0e0;
      }
    }
  }
  .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: -sharpfff;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
    .city-item {
      display: inline-block;
      padding: 3px 5px;
      background-color: -sharpf4f4f4;
      margin: 5px;
      &:hover {
        background-color: -sharpe0e0e0;
      }
    }
  }
  .proactive {
    background-color: -sharpe0e0e0 !important;
  }
}
</style>

the result of running is as follows:

clipboard.png

:

clipboard.png

Click the year text box will not lose focus of this kind, but think for a long time has not found a good way to achieve, I hope there is a god can help guide the train of thought, thank you very much!

Aug.22,2021

Don't hide in blur events, think differently.
should listen for mouseleave events in the element city-select-picker, hidden when the mouse leaves this element, or listen for mousedown events on the page, and the target clicked is hidden if it is not in the city-select-picker.


https://codesandbox.io/s/wnzv.


when you click, the text box loses focus event first, and then your click event. You can make it regain focus, which is not very good.
you can hide the pop-up box when you click on the outer layer, so you can control the display without focus.


input plus ref
cityClick event finally add this.$refs.input.foucs ()

Menu