VueJS 2 - автозаполнение компонента с предварительной загрузкой - PullRequest
0 голосов
/ 13 сентября 2018

Я немного выдернул волосы и подумал, что буду просить о помощи. Я нашел несколько учебных пособий и библиотек по автозаполнению компонентов, но ни одна из них, казалось, не делала того, что мне действительно нужно, - это случайное заполнение поля ввода. Достаточно просто, верно…

Вот моя скрипка, я могу заставить автозаполнение работать действительно хорошо, только не предварительно заполнение… в скрипте, я бы хотел, чтобы parentVar предварительно заполнил поле ввода ВНУТРИ компонента автозаполнения, а затем, когда это поле ввода изменится , передайте это значение в parentVar (v-модель).

Vue.component('autocomplete', {
	template: '#autocomplete_template',
  name: 'autocomplete',
  props: {
    items: {
      type: Array,
      required: false,
      default: () => []
    },
    isAsync: {
      type: Boolean,
      required: false,
      default: false
    },
    presetVal: {
      type: String,
      required: false,
      default: ''
    }
  },
  data() {
    return {
      isOpen: false,
      results: [],
      search: this.presetVal,
      isLoading: false,
      arrowCounter: 0
    }
  },
  methods: {
    onChange() {
      // Let's warn the parent that a change was made
      this.$emit('input', this.search)

      // Is the data given by an outside ajax request?
      if (this.isAsync) {
        this.isLoading = true
      } else {
        // Let's search our flat array
        this.filterResults()
        this.isOpen = true
      }
    },

    filterResults() {
      // first uncapitalize all the things
      this.results = this.items.filter(item => {
        return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1
      })
    },
    setResult(result) {
      this.search = result
      this.isOpen = false
    },
    onArrowDown(evt) {
      if (this.arrowCounter < this.results.length) {
        this.arrowCounter = this.arrowCounter + 1
      }
    },
    onArrowUp() {
      if (this.arrowCounter > 0) {
        this.arrowCounter = this.arrowCounter - 1
      }
    },
    onEnter() {
      this.search = this.results[this.arrowCounter]
      this.isOpen = false
      this.arrowCounter = -1
    },
    handleClickOutside(evt) {
      if (!this.$el.contains(evt.target)) {
        this.isOpen = false
        this.arrowCounter = -1
      }
    }
  },
  watch: {
    items: function(val, oldValue) {
      // actually compare them
      if (val.length !== oldValue.length) {
        this.results = val
        this.isLoading = false
      }
    }
  },
  mounted() {
    document.addEventListener('click', this.handleClickOutside)
  },
  destroyed() {
    document.removeEventListener('click', this.handleClickOutside)
  }
})

var vm = new Vue({
  el: "#app",
  data: {
   parentVar: 'Apple',
   autoOptions: ['Apple','Orange','Banana','Peach']
  }
})
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin: 60px;
}
.autocomplete {
  position: relative;
}

.autocomplete-results {
  padding: 0;
  margin: 0;
  border: 1px solid #eeeeee;
  height: 120px;
  overflow: auto;
  width: 100%;
}

.autocomplete-result {
  list-style: none;
  text-align: left;
  padding: 4px 2px;
  cursor: pointer;
}

.autocomplete-result.is-active,
.autocomplete-result:hover {
  background-color: #4aae9b;
  color: white;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<div id="app">
<div style="margin-bottom: 30px;">You have selected "{{ parentVar }}"</div>
<label>Test Autocomplete</label>
<autocomplete v-model="parentVar" :preset-val="parentVar" :items="autoOptions" />


</div>

<template id="autocomplete_template">
  <div class="autocomplete">
    <input type="text" @input="onChange" v-model="search" @keyup.down="onArrowDown" @keyup.up="onArrowUp" @keyup.enter="onEnter" class="form-control" />
    <ul id="autocomplete-results" v-show="isOpen" class="autocomplete-results">
      <li class="loading" v-if="isLoading">
        Loading results...
      </li>
      <li v-else v-for="(result, i) in results" :key="i" @click="setResult(result)" class="autocomplete-result" :class="{ 'is-active': i === arrowCounter }">
        {{ result }}
      </li>
    </ul>
  </div>  
</template>

Я чувствую, что упускаю что-то маленькое: - /

Заранее спасибо за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...