vuejs2 Autocomplete Create an autocomplete with Vuejs 2


Example

HTML

<div :class="classes">
    <input v-model="compValue"
           type="text"
           class="form-control"
           @keydown.enter = 'enter'
           @keydown.down = 'down'
           @keydown.up = 'up'
           @input = "change"
    >
    <ul :class="dropDownClasses">
        <li v-for="(suggestion, index) in matches"
            v-html="suggestion"
            v-on:mouseover="mouseOverLi(index)"
            :class="{'active': isActive(index)}"
            @click="suggestionClick(index)"
        >
        </li>
    </ul>
</div>

Script

<script>
    export default {
        data: function() {
            return {
                compValue: this.value,
                current: 0,
                open: false,
            }
        },

        props: {
            value: {
                type: String,
                default: '',
            },

            suggestions: {
                type: Array,
                default: []
            },

            disabled: {
                type: Boolean,
                default: false,
            },

            readonly: {
                type: Boolean,
                default: false,
            },
        },

        computed: {
            classes: function() {
                return {
                    'br-auto-complete': true,
                    'open': this.openSuggestion
                };
            },

            dropDownClasses: function() {
                return {
                    'dropdown-menu': true,
                };
            },

            matches: function() {
                return this.suggestions.filter((str) => {
                    return str.toUpperCase().indexOf(this.compValue.toUpperCase()) >= 0;
                });
            },

            openSuggestion() {
                return this.compValue !== "" &&
                    this.matches.length != 0 &&
                    this.open === true;
            },
        },

        methods: {
            //When enter pressed on the input
            enter: function() {
                this.compValue = this.matches[this.current];
                this.open = false;
            },

            //When up pressed while suggestions are open
            up: function() {
                if(this.current > 0)
                    this.current--;
            },

            //When up pressed while suggestions are open
            down: function() {
                if(this.current < this.matches.length - 1)
                    this.current++;
            },

            //For highlighting element
            isActive: function(index) {
                return index === this.current;
            },

            mouseOverLi: function(index){
                this.current = index;
            },

            //When the user changes input
            change: function() {
                if (this.open == false) {
                    this.open = true;
                    this.current = 0;
                }
                this.$emit('input', this.compValue);
            },

            //When one of the suggestion is clicked
            suggestionClick: function(index) {
                this.compValue = this.matches[index];
                this.open = false;
                this.$emit('input', this.compValue);
            },
        },
    }
</script>