search-bar.vue 4.65 KB
<template>
    <div class="search-slider">
        <div class="search-block">
            <input-search ref="search" class="search" v-model="keyword" :loading="product.isSearching" @enter="enter"></input-search>
            <button class="btn btn-trans btn-cancel" @click="cancel">取消</button>
        </div>
        <div class="search-content" v-show="extend">
            <div class="search-list" v-if="!searchEmpty">
                <ul>
                    <li
                        v-for="item in searchList"
                        :key="item.keyword"
                        @click="toSearch(item.keyword)">
                        {{item.keyword}}
                        <i class="icon icon-right"></i>
                    </li>
                </ul>
            </div>
            <div class="search-tip" v-else>
                <p class="chg">
                    未找到相关商品
                </p>
                <p class="eng">
                    Unfortunately there are no results
                    matching your request.
                </p>
            </div>
        </div>
    </div>
</template>

<script>
import InputSearch from '../input/input-search';
import {
    FETCH_SEARCH_REQUEST
} from 'store/product/types';
import {mapState} from 'vuex';
import {debounce} from 'common/utils';
export default {
    name: 'SearchBar',
    props: {
        full: Boolean,
        value: String
    },
    data() {
        return {
            searchList: [],
            searchEmpty: false
        };
    },
    computed: {
        ...mapState(['product']),
        extend() {
            if (this.full) {
                return true;
            }
            return this.searchEmpty || this.searchList.length;
        },
        keyword: {
            get() {
                return this.value;
            },
            set(val) {
                this.$emit('input', val);
                if (val) {
                    this.searchDebounce(val);
                } else {
                    this.clear();
                }
            }
        }
    },
    created() {
        this.searchDebounce = debounce(300, this.search);
    },
    methods: {
        cancel() {
            this.$emit('cancel');
        },
        clear() {
            this.searchEmpty = false;
            this.searchList = [];
        },
        enter() {
            this.toSearch(this.value);
        },
        toSearch(searchKey) {
            this.clear();
            this.$router.push(`/channel/search?query=${searchKey}`);
        },
        focus() {
            this.$refs.search.focus();
        },
        async search(val) {
            const result = await this.$store.dispatch(FETCH_SEARCH_REQUEST, {keyword: val});

            if (result && this.value) {
                if (result.data.length) {
                    this.searchEmpty = false;
                    this.searchList = result.data;
                } else {
                    this.searchEmpty = true;
                }
            }
        }
    },
    components: {InputSearch}
};
</script>

<style lang="scss">
.search-slider {
    .search-block {
        position: relative;
        width: 100%;
        height: 90px;
        padding: 14px 20px;
        background-color: #fff;
        display: flex;
        border-bottom: solid 1px #eee;
        z-index: 999;

        .search {
            flex: 1;
        }
        .btn-cancel {
            width: 125px;
            padding-right: 0px;
        }
    }
    .search-content {
        position: absolute;
        top: 90px;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 998;
        background: rgba(255, 255, 255, 0.9);

        .search-tip {
            width: 358px;
            height: 380px;
            margin: 380px auto;
            padding-top: 225px;
            background: url('~statics/img/search-tip.png') no-repeat;
            background-repeat: no-repeat;
            background-position: top center;
            background-size: 205px 201px;
            color: #b0b0b0;
            text-align: center;

            .chg {
                font-size: 34px;
            }
            .eng {
                font-size: 12PX;
            }
        }

        .search-list {
            li {
                width: 100%;
                line-height: 80px;
                padding: 0 30px;
                font-size: 30px;
                border-bottom: solid 1px #eee;
                background-color: #fff;

                i {
                    float: right;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    height: 80px;
                }
            }
        }
    }
}
</style>