Поиск на сайте на vue

236
14 августа 2018, 04:10

Всем привет... вот сделал поиск на сайте, но вот как сделать пару условий типа: если поле ввода пустое, то div.search__dropdown исчезает(ну это легко); вот если ввести данные в поле, то в массив searchArr сразу записываются ответ сервера, а как к примеру сделать так: пользователь вводит в поле какое-то слово, ему выводится данные и когда он или стирает слово из поля или ему поле поиска больше не нужно( типа уводит курсор мыши), то чистить этот массив

Вот как он сейчас выглядит:

<template>
  <header class="uk-box-shadow-large uk-background-muted header">
    <div class="uk-container">
        <nav uk-navbar>
            <div class="uk-navbar-left">
                <router-link :to="{name:'home'}"><img src="" alt=""></router-link>
            </div>
            <div class="uk-navbar-right">
                <div class="search">
                      <input class="search__input" type="text" v-model="keywords" placeholder="Поиск...">
                      <button class="search__button" type="submit"><span uk-icon="icon:search"></span></button>
                </div>
                <div class="search__dropdown">
                    <ul class="uk-list">
                        <li v-for="rec in searchArr" :key="rec.id" v-text="rec.name"></li>
                    </ul>
                </div>
            </div>
        </nav>
    </div>
</header>

<script>
    import axios from 'axios';
    export default {
        data: function(){
            return{
                keywords: '',
                searchArr:[]
            }
        },
        watch: {
            keywords(after, before) {
                this.FetchData();
            }
        },
        methods: {
            FetchData(){
                axios.get('/api/search', { params: { keywords: this.keywords } })
                .then(res =>{
                    this.searchArr = res.data
                })
                .catch(err =>{
                });
            }
        }
    }
</script>
Answer 1

Смотри, тут пару моментов:

  1. Используй debounce функцию для того, чтобы не слать ajax запросы при каждом нажатии клавиши
  2. показывай блок результатов, когда массив searchArr непустой

    <header class="uk-box-shadow-large uk-background-muted header">
        <div class="uk-container">
            <nav uk-navbar>
                <div class="uk-navbar-left">
                    <router-link :to="{name:'home'}"><img src="" alt=""></router-link>
                </div>
                <div class="uk-navbar-right">
                    <div class="search">
                        <input class="search__input" type="text" v-model="keywords" placeholder="Поиск...">
                        <button class="search__button" type="submit">
                          <span uk-icon="icon:search"></span>
                        </button>
                    </div>
                    <div class="search__dropdown" v-if="searchArr.length">
                        <ul class="uk-list">
                            <li v-for="rec in searchArr" :key="rec.id" v-text="rec.name"></li>
                        </ul>
                    </div>
                </div>
            </nav>
        </div>
    </header>
    

Скрипт с debounce:

    <script>
    import axios from 'axios';
    const debounce = function (f, ms) {
        let timer = null;
        return function (...args) {
            const onComplete = () => {
                f.apply(this, args);
                timer = null;
            }
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(onComplete, ms);
        };
    }
    export default {
        data: function () {
            return {
                keywords: '',
                searchArr: []
            }
        },
        watch: {
            keywords(after, before) {
                this.FetchData();
            }
        },
        methods: {
            FetchData: debounce(function () {
                if(!this.keywords) return this.searchArr = []
                axios.get('/api/search', {
                        params: {
                            keywords: this.keywords
                        }
                    })
                    .then(res => {
                        this.searchArr = res.data
                    })
                    .catch(err => {
                    });
            }, 200)
        }
    }
</script>

Здесь ты следишь за изменением keywords и с задержкой 200ms после последнего изменения keywords отправляешь запрос к API

Обрати внимание на v-if="searchArr.length" - блок с результатами будет показан только тогда, когда массив результатов буден непуст

Можешь также добавить какой-нибудь прелоадер, ну это на свое усмотрение

READ ALSO
Не работают стили css в jQuery

Не работают стили css в jQuery

Пытаюсь вызывать меню по клику на элемент div

200
chrome.tabs.executeScript|insertCss срабатывает через раз

chrome.tabs.executeScript|insertCss срабатывает через раз

Добавляю стили и скрипты на определенный сайт в background

174