微信小程序> 小程序自定义搜索选择组件

小程序自定义搜索选择组件

浏览量:2453 时间: 来源:weixin_34327223

引言

在开发中经常遇到需要搜素之后在返回的列表中再选择的需求,能便利在大量数据中的选择行为,有一些已有的组件例如select2.js、iview的AutoComplete组件等等。由于小程序没有类似的组件,只能自己写一个,其实比较基础,欢迎阅读。

分析思路

思路是这样的:

  • 为了适应各种返回格式不同的接口,组件应该直接接收一个数组,数据请求最好由父页面完成,后台返回的数据可能不是字符串数组,更有可能是对象数组,因此还要有参数指定显示的属性名;
  • 搜索却是在组件中进行的,所以搜索内容要传给父级页面作为接口参数,接口需要做节流;
  • 选中后将选中的下标返回父页,然后执行回调,因为很多选中后还会联动其余值的填入,其他数据一般也在选中的对象中,在父页面用下标直接从数组中获取就可以了;

效果图如下,截图是开发工具里的,手机上滚动条没这么丑^ ^

组件编写

组件名为search-picker,在开发工具右键新建Components,由于组件内及父页面都能控制组件的显示隐藏(组件内是选中后直接隐藏),所以隐藏状态要保持一致,否则会出现父页面触发了却不显示的问题。

1、组件的js

//components/search-picker/search-picker.jsComponent({    properties: {        list:{            type:Array,            value:[]        },//可选列表        placeholder:{            type:String,            value:'请输入内容进行选择'        },        key:{            type:String,            value:'title'        },//列表显示的字段名,默认是title        show:{            type:Boolean,            value:false        },//是否显示组件    },    data: {        inputVal:'',//输入内容    },    methods: {        //获取组件输入的内容传递给父页面        getInput: function (e) {            this.setData({                inputVal:e.detail.value            });            this.triggerEvent('getInput', this.data.inputVal);        },        //选中结果后,将下标传递给父页面,并隐藏组件        select: function (e) {            let index = e.currentTarget.dataset.index;            let key = this.data.key;            this.setData({                show:false            });            this.triggerEvent('getSelect',index)        },        //清空输入        clearSelect: function () {            this.setData({                inputVal:'',            });        },        //隐藏组件,必须将隐藏状态传递给父页面,因为父页面也有控制隐藏显示的属性,不传递的话,该属性还是true        hidePicker: function () {            this.setData({                show:false,            });            this.triggerEvent('showFn',false)        }    }});复制代码

2、组件的wxml

<!--components/search-picker/search-picker.wxml--><!--搜索选择组件,父级包含组件的元素要相对定位,否则组件无法定位--><view class="searchPicker" hidden="{{!show}}">    <view class="inputView">        <input type="text"               value="{{inputVal}}"               placeholder="{{placeholder}}"               placeholder-class="placeholder"               bindinput="getInput"        />        <!--清空输入-->        <icon type="clear" size="18" hidden="{{inputVal==''}}" bindtap="clearSelect"></icon>    </view>    <scroll-view class="list" scroll-y>        <!--有结果显示列表-->        <block wx:if="{{list.length!=0}}">            <view wx:for="{{list}}"                  wx:key="{{index}}"                  class="item"                  bindtap="select"                  data-index="{{index}}">                  <!--如果没有传key,说明是字符串数组,直接访问item-->                <text class="item">{{item[key]||item}}</text>            </view>            <text class="tips">没有想要的结果?请输入更精确的关键字~</text>        </block>        <!--没有结果-->        <text wx:if="{{inputVal!='' && list.length==0}}" class="tips">抱歉,没有结果哦~</text>    </scroll-view></view><!--用来点击组件外部隐藏--><view class="closePicker" hidden="{{!show}}" bindtap="hidePicker"></view>复制代码

组件使用

1、使用页面的json中要声明

"usingComponents": {    "search-picker":"/components/search-picker/search-picker"}复制代码

2、组件标签的使用

<!--组件使用页面.wxml--><view class="formItem" style="position: relative">    <text class="itemTitle">**名称<text class="red">*</text></text>    <input type="text" disabled value="{{clientname}}" bindtap="showPickerFn"     placeholder="请选择**名称" placeholder-class="placeholder"/>    <search-picker            placeholder="请输入名称进行选择"            key="{{clientKey}}"            list="{{clientList}}"            show="{{showSearch}}"            bindgetInput="getInput"            bindgetSelect="getSelect"            bindshowFn="showFn"            class="searchPicker"    ></search-picker></view>复制代码

3、组件所需参数及回调

//组件使用页面.js...data:{    clientname: '',//选中名称    clientList: [],//机构可选列表    showSearch:false,//是否显示    clientKey:'name',//列表中显示的字段名    timeout:'',//计时器    ...},//显示搜索选择框showPickerFn:function(){    this.setData({        showSearch:!this.data.showSearch    });    //可以在这里提前传空值请求一次列表,可返回一个初始的列表    this.getClientList('');},//获取组件中输入的内容getInput: function(e){    let that = this;    //    若已经有定时任务,将其清除,重新定义新的计时器,在输入长时间停顿之前不请求接口    if(this.data.timeout!=''){        clearTimeout(this.data.timeout);    }    let timeout = setTimeout(function () {        that.getClientList(e.detail)    },800);    this.setData({        timeout:timeout    });},//根据输入的内容请求数据,搜索数据列表getClientList: function(key){    let that = this;    <!--这里是项目里封装好的wx.request,可直接用wx.request-->    app.ajax({        method:'post',        url:'/url/clients',        data:{            key:key        }    }).then(resp=>{        that.setData({            clientList:resp.list,        })    });},//将组件选中的项回填getSelect: function(e){    let index = e.detail;    let that = this;    this.setData({        clientname:that.data.clientList[index].title,        clientid:that.data.clientList[index].id,        showSearch:false    })    //把选中的数据重置为空    this.resetData();    //根据id做其他数据请求    this.getCompany(that.data.clientList[index].id);    ···},// 隐藏回调,即组件中隐藏了组件后,父级也要同步showFn: function(e){    this.setData({        showSearch:e.detail,    })},···复制代码

样式就不粘了,需要的话可以去github。以上就是全部啦,有问题的话,欢迎指正~

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

最新资讯

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎