码迷,mamicode.com
首页 > 其他好文 > 详细

vue 简单的 diy 搜索框 封装,全局组件化,对象配置

时间:2019-06-21 18:39:48      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:mob   relative   dde   nts   ons   readonly   inf   syn   sheet   

1. 目录结构:

技术图片

2. main.js 全局组件

技术图片

3. KjfSearch.vue 代码:

  • <template>
        <div class="kjf_search_box" :class="kjfSearchConfig.className">
            <label class="kjf_search_search_label clearfix">
                <input autocomplete="off" readonly="readonly" type="text" :placeholder="kjfSearchConfig.placeholder"
                       class="search_input" :ref="kjfSearchConfig.refName" v-model="kjfSearchKeyWord"
                       @blur="kjfClearPreSearchData" @focus="kjfHandleSearchEvent" @keyup="kjfHandleSearchEvent($event)" />
                <a class="search_by_inputs" href="javascript:" @click="kjfHandleSearchEvent(‘notEvent‘)">搜索</a>
            </label>
    
            <div class="search_list" v-show="kjfPreSearchData && kjfPreSearchData.length>0">
                <ul class="search_result">
                    <li v-for="(item, index) in kjfPreSearchData" :key="item.index"
                        :class="{active: index === kjfPreSearchItem}" @click="kjfChoosePreSearchItem(index, item.kjfShowSearchName)">
                        <span class="ellipsis" :title="item.kjfShowSearchName">
                            {{item.kjfShowSearchName}}
                        </span>
                    </li>
                </ul>
            </div>
        </div>
    </template>
    
    <script>
        import {getElementsByCss} from ‘../utils‘;
    
        export default {
            name: ‘KjfSearch‘,
            props: {
                kjfSearchConfig: {
                    type: Object
                }
            },
            data: function() {
                return {
                    kjfSearchKeyWord: ‘‘,
                    kjfPreSearchData: [],
                    kjfPreSearchItem: -1
                };
            },
            computed: {
            },
            watch: {
                kjfPreSearchData: {
                    deep: true,
                    handler(newArr) {
                        if (newArr && typeof this.kjfSearchConfig.watchCallBack === ‘function‘) {
                            return this.kjfSearchConfig.watchCallBack(newArr);
                        } else {
                            return [];
                        }
                    }
                }
            },
            mounted() {
            },
            methods: {
                kjfClearPreSearchData() {
                    this.$refs[this.kjfSearchConfig.refName].setAttribute(‘readonly‘, ‘readonly‘);
                    window.setTimeout(() => {
                        this.kjfPreSearchData = [];
                        this.kjfPreSearchItem = -1;
                    }, 200);
                },
                kjfChoosePreSearchItem(index, searchName) {
                    this.kjfSearchKeyWord = searchName;
                    this.kjfPreSearchData = [];
                    this.kjfPreSearchItem = -1;
                },
                async kjfHandleSearchEvent(e) {
                    this.$refs[this.kjfSearchConfig.refName].removeAttribute(‘readonly‘);
    
                    if (e && (e.key === ‘ArrowUp‘ || e.key === ‘ArrowDown‘)) {
                        this.kjfPreSearchItem = e.key === ‘ArrowUp‘ ? (this.kjfPreSearchItem - 1) : (this.kjfPreSearchItem + 1);
                        if (this.kjfPreSearchItem < 0) {
                            this.kjfPreSearchItem = -1;
                        }
                        if (this.kjfPreSearchItem >= this.kjfPreSearchData.length) {
                            this.kjfPreSearchItem = this.kjfPreSearchData.length - 1;
                        }
                        console.log(‘.‘ + this.kjfSearchConfig.className + ‘ .search_list .search_result‘);
                        const ele = getElementsByCss(‘.‘ + this.kjfSearchConfig.className + ‘ .search_list .search_result‘)[0];
                        ele && ele.scrollTo(0, this.kjfPreSearchItem * 31);
                        return;
                    } // 上、下选择下拉选项
    
                    if (e && (e.key === ‘Enter‘) && (this.kjfPreSearchItem !== -1)) {
                        this.kjfSearchKeyWord = this.kjfPreSearchData[this.kjfPreSearchItem].kjfShowSearchName;
                        this.kjfPreSearchData = [];
                        this.kjfPreSearchItem = -1;
                        this.$refs[this.kjfSearchConfig.refName].focus();
                        return;
                    } // 回车选中下拉选项
    
                    if ((e === ‘notEvent‘) || (e && e.key === ‘Enter‘)) {
                        window.setTimeout(async () => {
                            this.kjfSearchConfig.enterCallBack(this.kjfSearchKeyWord);
    
                            this.kjfPreSearchData = [];
                            this.kjfPreSearchItem = -1;
                        }, 200);
                        this.$refs[this.kjfSearchConfig.refName].focus();
                        return;
                    } // 回车键按下 或者 点击搜索按钮
    
                    window.clearTimeout(this.searchTimer);
                    this.searchTimer = window.setTimeout(async () => {
                        if (this.kjfSearchKeyWord && this.kjfSearchKeyWord.trim()) {
                            if (!this.kjfSearchKeyWord) {
                                this.kjfPreSearchData = [];
                                return;
                            }
                            if (typeof this.kjfSearchConfig.getPreSearchData === ‘function‘) {
                                this.kjfPreSearchData = await this.kjfSearchConfig.getPreSearchData(this.kjfSearchKeyWord);
                            }
                        } else {
                            this.kjfPreSearchData = [];
                            this.kjfPreSearchItem = -1;
                        }
                    }, 200); // 防抖 搜索
                }
            }
        };
    </script>
    
    <style lang="stylus" rel="stylesheet/stylus" scoped>
        @import "../../common/stylus/mixins.styl"
    
        .kjf_search_box
            width 100%
            height 100%
            input
                height 30px
                text-indent 2px
                border-radius 4px
                outline none
                border 1px solid #DCDFE6
            .kjf_search_search_label
                display block
                width 100%
                height 100%
                >input
                    float left
                    display block
                    width 240px
                >a
                    float right
                    display block
                    width 50px
                    height 100%
                    border-radius 4px
                    box-sizing border-box
                    padding 0 10px
                    background-color $themeColor
                    color #fff
            .search_list
                color $fontColor
                width 238px
                max-height 300px
                overflow hidden
                .search_result
                    position absolute
                    top 32px
                    left 2px
                    z-index 100
                    width 238px
                    max-height 300px
                    overflow-x hidden
                    overflow-y auto
                    border-radius 0 0 10px 10px
                    background-color #eee
                    padding 0 0 10px 10px
                    box-sizing border-box
                    >li
                        width 180px
                        margin-top 10px
                        color $fontColor
                        white-space normal
                        word-break break-all
                        word-wrap break-word
                        &.active,
                        &:hover
                            cursor pointer
                            >span
                                color #fff
                                background-color $themeColor
                        >span
                            color $fontColor
    
    </style>

4. 使用实例 主要代码: 

  • <template>
        <div id="company_pay_record">
            <ul class="company_pay_record_nav clearfix">
                <li class="right_company_pay_record_search_li clearfix">
                    <KjfSearch :kjfSearchConfig="companyPayRecordSearchConfig"></KjfSearch>
                </li>
            </ul>
        </div>
    </template>
    
    <script>
        import {mapState} from ‘vuex‘;
        import {requestMyLabs} from ‘../../../../axios‘;
    
        export default {
            name: ‘CompanyPayRecord‘,
            props: {
                isPC: Boolean
            },
            data () {
                return {
                    companyPayRecordSearchConfig: {
                        className: ‘company_pay_record_search‘,
                        refName: ‘companyPayRecordSearch‘,
                        placeholder: ‘请输入操作人/编号‘,
                        kjfShowSearchName: ‘expName‘,
                        enterCallBack: async (searchKeyWord) => {
                            searchKeyWord = searchKeyWord && searchKeyWord.trim();
                            await this.$store.dispatch(‘changeLabsCurPageNo‘, 1);
                            await this.$store.dispatch(‘changeLabsKeyWord‘, searchKeyWord);
                            let response = ‘ - 223 -‘;
                            try {
                                response = await this.$store.dispatch(‘getMyLabs‘, this.myLabsData); // 获取 myLabsData
                            } catch (e) {
                                this.myConsole(e);
                                this.myConsole(‘response 228: ‘);
                                this.myConsole(response);
                            }
                        },
                        getPreSearchData: async (searchKeyWord) => {
                            await this.$store.dispatch(‘changeLabsKeyWord‘, searchKeyWord);
                            const response = await requestMyLabs(this.myLabsData);
                            if (response.status === 200) {
                                return response.data.data.content;
                            }
                        },
                        watchCallBack: (newArr) => {
                            let i = 0;
                            for (; i < newArr.length; i++) {
                                newArr[i].kjfShowSearchName = newArr[i].experiment.experimentName;
                            }
                            return newArr;
                        }
                    }
                };
            },
            computed: {
                ...mapState({
                    myLabsData: state => state.myLabs.myLabsData
                })
            },
            async mounted () {
                this.initCompanyPayRecord();
            },
            methods: {
                async initCompanyPayRecord() {
                }
            }
        };
    </script>
    
    <style lang="stylus" rel="stylesheet/stylus" scoped>
        @import "../../../../common/stylus/mixins.styl"
    
        #company_pay_record
            width 100%
            margin 0 auto
            .company_pay_record_nav
                width 100%
                padding-top 20px
                padding-bottom 20px
                box-sizing border-box
                >li
                    float left
                    width 200px
                    height 30px
                    margin-right 14px
                    line-height 30px
                    &:last-child
                        margin-right 0
                .right_company_pay_record_search_li
                    float right
                    position relative
                    width 300px
                    height 30px
    
            .my_labs_pagination
                margin-top 15px
        #company_pay_record_info.is_mobile
            width 100%
            px(‘font-size‘, 14)    // 用于 mobile 设计图单位
    </style>

5. 效果图:

技术图片

vue 简单的 diy 搜索框 封装,全局组件化,对象配置

标签:mob   relative   dde   nts   ons   readonly   inf   syn   sheet   

原文地址:https://www.cnblogs.com/tianxiaxuange/p/11066069.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!