天天看点

vue自定义组件搜索输入框

  1. 组件效果图
vue自定义组件搜索输入框

2.组件代码

<template>
    <div>
        <div class="mysearch" v-click-outsidee="onClickoutsidee">
            <Input  search v-model="showvalue"  @on-focus="onFocus"	@on-blur="onBlur"  @on-search="onSearch" /><Icon v-if="showvalue!=''" type="md-close-circle" class="clear" @click="cleardata"/>
            <div class="content" v-if="contentShow">
                <div class="detail">
                    <li v-for="item in listdata" :key="item.appId" @click="selectItem(item)" class="item" >{{item[showField]}}</li>
                    <li  v-if='listdata.length<=0' disabled class="item" ><span style="color:red">无搜索结果</span></li>
                    <Spin fix v-if="spinShow">
                            <Icon type="ios-loading" size=18 class="demo-spin-icon-load"></Icon>
                            <div>Loading</div>
                    </Spin>
                </div>
                <div class="page"><Page :current="currentPage" :total="total" simple @on-change="switchPage" :page-size="pageSize" style="background-color: #fff;"/></div>
            </div>
        </div>
    </div>
</template>
<script>
    import {directive as clickOutsidee} from 'v-click-outside-x';
    export default {
        directives: { clickOutsidee },
        props:{
            spinShow:{//是否在加载中
                type:Boolean,
                default:false
            },
            showField:{//显示的字段名
                type:String,
                required:true,
            },
            realField: {//组件真实字段名
                type:String,
                required:true
            },
            binddata:{},//组件绑定的数据
            pageSize:{
                type: Number,
                default: 20 //分页,默认20条
            },
            total:{//总数据条数,默认1
                type: Number,
                required:true,
                default: 1 
            },
            listdata:{//选择列表
                type:Array,
                default:[],
                required:true//必须
            }
        },
        data () {
            return {
                showvalue: '',//展示内容
                currentPage:1,//当前页
                contentShow:false//控件是否展示
            }
        },
        mounted(){//设置初始值
            if(this.binddata){
             if(this.binddata[this.showField]){
                 this.showvalue=this.binddata[this.showField]
             }
             
            }
        },
        methods:{
            onClickoutsidee(){//鼠标掉在组件外事件
                var me=this;
                me.contentShow=false
                if(me.binddata){
                    if(me.binddata[me.showField]){
                        me.showvalue=me.binddata[me.showField]
                    }else{
                        me.showvalue=""
                        me.binddata[this.realField]='';
                        me.binddata[this.showField]='';
                    }
                }
            },
            cleardata(){
                var me =this;
                me.showvalue=""
                me.binddata[this.realField]='';
                me.binddata[this.showField]='';
                this.$emit("onClear");
            },
            switchPage(currentPage){//切换分页事件
                this.currentPage=currentPage;
                this.$emit("onSearch",this.showvalue,currentPage,)
            },
            onBlur(){//输入框失去焦点事件
                this.$emit("onBlur"); 
            },
            onFocus(){//输入框聚焦事件
                this.$emit("onFocus"); 
            },
            onSearch(){//搜索事件
             var me=this;
             me.contentShow=true;
             me.$emit("onSearch",me.showvalue,me.currentPage)
            },
            selectItem(name){//选择数据事件
              var me=this;
              me.showvalue=name[this.showField];
              me.binddata[this.realField]=name[this.realField];
              me.binddata[this.showField]=name[this.showField];
              me.contentShow=false;
              me.$emit("selectItem",name); 
            }
        }

    }
</script>
<style scoped>
.item{
    list-style: none;
    padding: 5px 10px;
    color: #333;
    background-color: #fff;
    &:hover{
    background-color:#b7ddf8; 
    }
}
.content{
    max-height: 200px;
    position:absolute;
    top:30px;
    width: inherit;
    min-width: 160px;
    -webkit-box-shadow: #d8d8d8 0px 0px 10px;
   -moz-box-shadow: #d8d8d8 0px 0px 10px;
   box-shadow: #d8d8d8 0px 0px 10px;
   z-index: 1064
}
.detail{
    max-height: 170px;
    overflow: auto;
}
.page{
    text-align: center;
}
.mysearch{
    float:left; 
    position:relative;
    border:0;
    .clear{
        position: absolute;
        margin: 5px;
        right: 25px;
        font-size: 15px;
        top: 1px;
    }
    
}

</style>
           

3.组件API

属性名  说明 类型 是否必须 备注
binddata 组件绑定值 object false /
showField 展示字段名 String true /
realField 真实值字段名 String true /
spinShow 是否加载完成 Boolean false 异步接口请求,数据是否加载完成状态
pageSize 分页大小 Number fasle 不传则默认20
total 总数据条数 Number false 不传则默认1
listdata 选择数据列表 Array true
事件名 说明mouhs 有无返回值
onClear 清空事件,点击清空按钮触发
onSearch 切换分页,在回车和点击搜索按钮触发 showvalue:搜索关键字;currentPage:当前页
onBlur 输入框失去焦点时触发
onFocus 输入框获取焦点时触发
selectItem 选择选项时触发 itemdata:返回当前对象的值

4.组件使用实例:

<template>
<div>
    <SearchInput :spinShow="loadingok" :binddata="binddata" :total="totalCount" :pageSize=10 showField="name" realField="code" :listdata="listdata"   @onSearch="search" ></SearchInput>
</div>
</template>

<script>
    import SearchInput from "./SearchInput";
    export default {
        name: "testSearchInput",
        components: {SearchInput},
        data(){
            return{
                totalCount:0,
                listdata:[],
                binddata:{
                    name:'我是初始值',
                    code:3715
                },
                loadingok:false,
                rowDatas1:[
                    {
                        name:'山东1',
                        code:3715
                    },{
                        name:'山西2',
                        code:3716
                    },{
                        name:'湖南3',
                        code:3717
                    },{
                        name:'湖北4',
                        code:3718
                    }, {
                        name:'山东5',
                        code:3715
                    },{
                        name:'山西6',
                        code:3716
                    },{
                        name:'湖南7',
                        code:3717
                    },{
                        name:'湖北8',
                        code:3718
                    }, {
                        name:'山东9',
                        code:3715
                    },{
                        name:'山西10',
                        code:3716
                    },
                ],

                rowDatas2:[
                    {
                        name:'山西20',
                        code:3716
                    },
                    {
                        name:'山东21',
                        code:3715
                    },{
                        name:'山西22',
                        code:3716
                    },{
                        name:'湖南23',
                        code:3717
                    },{
                        name:'湖北24',
                        code:3718
                    }, {
                        name:'山东25',
                        code:3715
                    },{
                        name:'山西26',
                        code:3716
                    },{
                        name:'湖南27',
                        code:3717
                    },{
                        name:'湖北28',
                        code:3718
                    }, {
                        name:'山东29',
                        code:3715
                    },
                ],
                rowDatas3:[
                    {
                        name:'山西30',
                        code:3716
                    },
                    {
                        name:'山东31',
                        code:3715
                    },{
                        name:'山西32',
                        code:3716
                    },{
                        name:'湖南33',
                        code:3717
                    },{
                        name:'湖北34',
                        code:3718
                    }, {
                        name:'山东35',
                        code:3715
                    },{
                        name:'山西36',
                        code:3716
                    },{
                        name:'湖南37',
                        code:3717
                    },{
                        name:'湖北38',
                        code:3718
                    }, {
                        name:'山东39',
                        code:3715
                    },
                ],
            }
        },
        methods:{
            search(value,pageIndex){
                var me =this;
                 me.loadingok=true,
                  setTimeout(() => {
                   console.log("加载完成");
                   me.loadingok=false,
                   this.totalCount=30
                if(pageIndex === 1){
                        this.listdata = this.rowDatas1;
                    }else if(pageIndex === 2){
                        this.listdata = this.rowDatas2;
                    }else if(pageIndex === 3){
                        this.listdata = this.rowDatas3;
                    }
                }, 2000);
                
            }
        }
    }
</script>

<style scoped>

</style>