title: Vuejs on blur for custom select element not working
body: <p><strong>Scenario</strong></p>
  
  <p>I've built custom autocomplete select component where it autocompletes but in addition, if the result is not found we can add new value.(I found it is not possible in vue-select module).</p>
  
  <p><a href="https://codepen.io/indrajeet183/pen/KReNLg" rel="noreferrer">Codepen Link </a></p>
  
  <p><strong>Question</strong></p>
  
  <p>I tried using @blur but the menu gets closed if I click on the item.
  I've custom div as a list of items for selecting which is getting toggled if the focus is on text field. If I remove blur it works perfect but it doesn't get closed it I click outside of text field.
  <strong>I've copied functions for handling keyup,keydown,keyenter,scrolling,handling pointer for select from vue-select</strong></p>
  
  <p><strong>CODE</strong></p>
  
  <pre><code>    &lt;template&gt;
      &lt;div class="vselect"&gt;
          &lt;div class="form-group"&gt;
              &lt;label&gt;{{label}}&lt;/label&gt;
              &lt;p class="control has-icon has-icon-right"&gt;
                  &lt;input ref="selected" @keyup="filterSelect($event)" @focus="onFocus" v-model="mutableValue" type="text" class="form-control"
                      @keydown.up.prevent="onKeyUp" @keydown.down.prevent="onKeyDown" @keydown.enter.prevent="onKeyEnter" @blur="onBlur"&gt;
              &lt;/p&gt;
          &lt;/div&gt;
          &lt;div ref="dropdown" class="my-dropdown" v-show="toggled" v-if="options"&gt;
              &lt;div v-for="(item,index) in filterList" :class="{'my-dropdwon--item':true,active:index === pointer}" @click="handleItemClick(item)"
                  @mouseover="pointer = index"&gt;{{item}}&lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
      export default {
          name: 'VSelect',
          props: {
              'options': Array,
              'label': String,
              'value': String,
          },
          data() {
              return {
                  selected: null,
                  toggled: false,
                  filterList: [],
                  mutableValue: null,
                  mutableOptions: [],
                  pointer: 0
              }
          },
          methods: {
              filterSelect: function (key) {
                  if (!this.toggled) this.toggled = !this.toggled;
                  let oldArr = this.options;
                  if (this.mutableValue &amp;&amp; this.mutableValue.length &lt;= 0)
                      this.filterList = this.mutableOptions;
                  else if (key.key.length == 1 || key.key == 'Backspace') {
                      oldArr = oldArr.filter(item =&gt; {
                          if (item.toLowerCase().includes(this.mutableValue.toLowerCase()))
                              return true;
                      })
                      this.filterList = oldArr;
                      //console.log('type', this.filterList)
                  }
                  // if (key.key == 'Enter')
                  //     this.toggled = !this.toggled;
                  this.$emit('input', this.mutableValue);
              },
              handleItemClick: function (item) {                
                  this.mutableValue = item;
                  this.$emit('input', item);                                    
                  this.toggled = !this.toggled;                               
              },
              onFocus: function () {
                  this.$refs.dropdown.scrollTop = 0;
                  this.toggled = !this.toggled;
              },
              onBlur: function () { 
                  this.handleItemClick(this.mutableValue)                
                  this.$refs.selected.blur();
              },
              onKeyUp: function () {
                  if (this.pointer &gt; 0) this.pointer--;
                  if (this.maybeAdjustScroll) {
                      this.maybeAdjustScroll()
                  }
              },
              onKeyDown: function () {            
                  if (this.pointer &lt; this.options.length &amp;&amp; this.filterList.length) this.pointer++;
                  if (this.pointer == this.options.length) this.pointer = 0;
                  if (this.maybeAdjustScroll) {
                      this.maybeAdjustScroll()
                  }
              },
              onKeyEnter: function () {
                  //console.log(this.filterList.length&gt; 0);
                  if(this.filterList.length &gt; 0)
                      this.handleItemClick(this.filterList[this.pointer])                
                  this.$refs.selected.blur();
                  this.$emit('input', this.mutableValue);
                  this.toggled = false;
              },
              maybeAdjustScroll() {
                  let pixelsToPointerTop = this.pixelsToPointerTop()
                  let pixelsToPointerBottom = this.pixelsToPointerBottom()
                  //console.log(pixelsToPointerTop,pixelsToPointerBottom);
                  if (pixelsToPointerTop &lt;= this.viewport().top) {
                      return this.scrollTo(pixelsToPointerTop)
                  } else if (pixelsToPointerBottom &gt;= this.viewport().bottom) {
                      return this.scrollTo(this.viewport().top + this.pointerHeight())
                  }
              },
  
              pixelsToPointerTop() {
                  let pixelsToPointerTop = 0
                  if (this.$refs.dropdown &amp;&amp; this.$refs.dropdown.children) {
                      for (let i = 0; i &lt; this.pointer; i++) {
                          pixelsToPointerTop += this.$refs.dropdown.children[i].offsetHeight
                      }
                  }
                  return pixelsToPointerTop
              },
  
              pixelsToPointerBottom() {
                  return this.pixelsToPointerTop() + this.pointerHeight()
              },
  
              pointerHeight() {
                  let element = this.$refs.dropdown ? this.$refs.dropdown.children[this.pointer] : false
                  return element ? element.offsetHeight : 0
              },
  
              viewport() {
                  return {
                      top: this.$refs.dropdown ? this.$refs.dropdown.scrollTop : 0,
                      bottom: this.$refs.dropdown ? this.$refs.dropdown.offsetHeight + this.$refs.dropdown.scrollTop : 0
                  }
              },
              scrollTo(position) {
                  //console.log(position);
                  return this.$refs.dropdown ? this.$refs.dropdown.scrollTop = position : null
              },
  
          },
          mounted() {
              this.filterList = this.options;
          },
          watch: {
              value(val) {
                  this.mutableValue = val
              },
              options(val) {
                  this.mutableOptions = val
              },
              pointer() {
                  this.maybeAdjustScroll()
              }
  
          }
      }
  &lt;/script&gt;
  
  &lt;style scoped&gt;
      .vselect {
          display: block;
          position: relative;
      }
  
      .my-dropdown {
          width: 100%;
          background: #f7f7f7;
          margin-top: 0.1rem;
          border: 1px solid #ced4da;
          border-radius: 3px;
          transition: all 0.5s;
          position: absolute;
          z-index: 1;
          max-height: 10rem;
          overflow: auto
      }
  
      .my-dropdwon--item {
          padding: 0.5rem;
          width: 100%;
          transition: all 0.5s;
      }
  
      .active {
          cursor: pointer;
          background-color: rgb(223, 221, 221);
      }
  
      /* .my-dropdwon--item:hover {
          cursor: pointer;
          background-color: rgb(223, 221, 221);
      } */
  
      .form-group {
          margin-bottom: 0px;
      }
  
      .control.has-icon has-icon-right {
          margin-bottom: 0px;
      }
  
      .form-group&gt;p {
          margin-bottom: 0px;
      }
  &lt;/style&gt;
  </code></pre>