标签: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. 效果图:

标签:mob relative dde nts ons readonly inf syn sheet
原文地址:https://www.cnblogs.com/tianxiaxuange/p/11066069.html