vue 简单的 diy 搜索框 封装,全局组件化,对象配置
Posted tianxiaxuange
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 简单的 diy 搜索框 封装,全局组件化,对象配置相关的知识,希望对你有一定的参考价值。
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 搜索框 封装,全局组件化,对象配置的主要内容,如果未能解决你的问题,请参考以下文章