vue 实现模糊查询 + 前端分页效果
查询 + 分页组件
<!-- 查询企业 编号 公司 组件 -->
<template>
<div class="search_business xSelect_container" v-clickoutside="clickoutside">
<el-input
class="xSelect_wrap"
:style="
labelWType == 1
? 'width: calc(100% - 94px)'
: 'width: calc(100% - 112px)'
"
style="height: '32px'"
v-model="input"
@input="inputChange"
placeholder="请输入"
@focus="inputFocus"
></el-input>
<span
:style="labelWType == 1 ? 'width:94px' : 'width:112px'"
class="xSelect_label"
><span class="xSelect_check" v-show="isCheck"></span>
<span> {{ selectOptions.title }}</span>
</span>
<div class="search_ul" ref="optionwrapper" :style="{display: displayFlag}" >
<ul ref="optionul">
<li
v-for="(item, idx) in currentPageData"
:key="item.id"
ref="optionitem"
@click="itemClick(item)"
@mouseover="move($event, idx)"
@mouseout="out($event)"
:class="item.name == currentName ? 'active' : ''"
>
<span>{{ item.code }}</span>
<span>{{ item.name }}</span>
</li>
</ul>
<el-pagination
v-show="total"
:current-page="cPage"
:page-size="10"
layout="total, prev, next"
:total="total"
@prev-click="prevPageClick"
@next-click="nextPageClick"
>
</el-pagination>
</div>
</div>
</template>
<script>
import Clickoutside from "@/utils/clickoutside";
export default {
name: "SearchBusiness",
components: {},
directives: {
Clickoutside,
},
props: {
labelWType: {
type: Number,
default: 1,
},
isCheck: {
type: Boolean,
default() {
return false;
},
},
defaultConfig: {
type: Object,
default: () => {},
},
cPage: {
type: Number,
default: 1,
},
currentName: {
type: String,
default: "",
},
clearBName: {
type: Boolean,
default :false
},
},
data() {
return {
input: "",
timer: null,
selectOptions: this.defaultConfig,
currentPageData: [],
pageSize: 10,
total: 0,
displayFlag: "none",
liClickFlag:false,
};
},
watch: {
defaultConfig: {
handler(newV) {
this.selectOptions = newV;
},
deep: true,
},
"defaultConfig.options"(newV) {
this.total = newV.length;
this.setCurrentPageData();
},
"cPage"() {
this.setCurrentPageData();
},
clearBName(val){
if(val){
this.input = "";
this.$store.commit("clearBName", false);
}
},
currentPageData(val){
if(val.length >= 1){
this.displayFlag = "block";
}else{
this.displayFlag = "none";
this.$emit("changeSelect", {});
}
},
input(newV){
if(newV && !this.liClickFlag){
this.displayFlag = "block";
}else{
this.displayFlag = "none";
}
}
},
computed: {
optionWrapper() {
return this.$refs.optionwrapper;
},
subjectList() {
return this.$refs.optionitem;
},
},
mounted() {
this.$refs.optionwrapper.style.transition = 2 + "s";
},
methods: {
inputChange() {
let _this = this;
clearInterval(this.timer);
this.timer = setTimeout(function () {
_this.$emit("inputChange", _this.input);
}, 500);
},
itemClick(item, idx) {
this.$emit("changeSelect", item, idx);
this.input = item.name;
this.displayFlag = "none";
this.liClickFlag = true;
},
inputFocus(){
if(this.input){
this.displayFlag = "block";
}else{
this.displayFlag = "none";
}
},
move(event, idx) {
for (let item of this.subjectList) {
item.classList.remove("hover");
}
event.currentTarget.classList.add("hover");
},
out(event) {
event.currentTarget.classList.remove("hover");
},
setCurrentPageData() {
let begin = (this.cPage - 1) * this.pageSize;
let end = this.cPage * this.pageSize;
this.currentPageData = this.selectOptions.options.slice(begin, end);
},
prevPageClick(val) {
this.$emit("pageClick",val)
},
nextPageClick(val) {
this.$emit("pageClick",val)
},
clickoutside() {
if(this.displayFlag){
this.displayFlag = "none";
}else{
this.displayFlag = "block";
}
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-input__inner {
height: 32px !important;
}
::v-deep .el-pagination {
padding: 2px 20px !important;
}
.search_business {
position: relative;
.search_ul {
z-index: 10;
position: absolute;
overflow: hidden;
top: 35px;
left: 10px;
width: 350px;
height: 370px;
border: 1px solid #e4e7ed;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
box-sizing: border-box;
ul {
height: 330px;
overflow: hidden;
padding: 5px 10px 2px;
cursor: pointer;
color: #515a6e;
li {
margin-bottom: 3px;
height: 30px;
line-height: 30px;
background: #fff;
span:nth-child(1) {
float: left;
width: 70px;
}
span:nth-child(2) {
padding-left: 10px;
float: left;
width: 256px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border-left: 1px solid #666;
}
}
}
.active {
color: #e82323;
background: #f5f7fa !important;
font-weight: 700;
}
.hover {
color: #e82323;
background: #f5f7fa !important;
}
}
}
</style>
点击外层 指令 Clickoutside.js
const clickoutsideContext = '@@clickoutsideContext'
export default {
bind(el, binding, vnode) {
const documentHandler = e => {
if (vnode.context && !el.contains(e.target)) {
vnode.context[el[clickoutsideContext].methodName]()
}
}
el[clickoutsideContext] = {
documentHandler,
methodName: binding.expression,
arg: binding.arg || 'click'
}
document.addEventListener(el[clickoutsideContext].arg, documentHandler)
},
update(el, binding) {
el[clickoutsideContext].methodName = binding.expression
},
unbind(el) {
document.removeEventListener(el[clickoutsideContext].arg, el[clickoutsideContext].documentHandler)
},
install(Vue) {
Vue.directive('clickoutside', {
bind: this.bind,
unbind: this.unbind
})
}
}
使用该 组件 实现模糊查询 + 前端 分页
<SearchBusiness :defaultConfig="BusinessName" @inputChange="bNameInputChange" @pageClick="pageClick" :cPage="cPage"
@changeSelect="bNameChangeSelect" :currentName="bNameCurrentName" :clearBName="clearBName" />
BusinessName: {
title: "企业编号:",
options: [],
},
cPage: 1,
bNameCurrentName:"",
watch:{
custno(newV){
if(!newV){
this.cPage = 1;
}
}
},
computed:{
customerNumber() {
return this.$store.state.creditMag.customerData;
},
}
bNameInputChange(val){
this.BusinessName.options = [];
if(!val){
this.BusinessName.options = [];
}else{
for(let i = 0; i < this.customerNumber.length - 1; i++ ){
if(val && this.customerNumber[i].name.toLowerCase().indexOf(val.toLowerCase()) !== -1 || this.customerNumber[i].code.indexOf(val) !== -1){
this.BusinessName.options.push(this.customerNumber[i])
}
}
}
},
pageClick(val){
this.cPage = val;
},
bNameChangeSelect(item){
this.custno = item.name;
this.bNameCurrentName = item.name;
},