小程序实战之搜索框组件的封装与模糊搜索的实现

246 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

动画.gif

如上图功能所示,点击搜索框,跳转到搜索页,输入搜索词,可以获取到相关信息并渲染,从设计上来讲,整个需求需要拆分为两个核心步骤即搜索框组件封装模糊搜索,下面将从这两部分来讲。

搜索框组件

由于需要搜索框复用,所以需要封装一个搜索框组件,下面从组件属性,图标适配,控制跳转与输入,清空与搜索内容四个方面来拆解搜索框组件的封装

组件的属性

从功能上考虑组件需要一个文本提示属性,初始内容属性与读写控制属性,分别对应placeholder,valuereadOnly

    placeholder: {
      type: String,
      value: '请输入搜索内容',
    },

    value: {
      type: String,
      value: ''
    },
    readOnly: {
      type: Boolean,
      value: false
    }

图标适配

为了使搜索图标的大小能够适配各种机型,所以在组件attached生命周期中通过wx.getSystemInfoSync().screenWidth获取当前机型的屏幕宽度,再进行一个比例的计算,得到适合当下的搜索图标大小,最后再通过getApp()设置到全局变量中。

 let _screenWidth = wx.getSystemInfoSync().screenWidth;
      this.setData({
        iconSize: Math.round(_screenWidth / 750 * 25)
      });
      const app = getApp();
      this.setData({
              season:app.globalData.season
      })    

控制跳转事件

通过设置组件的属性值,来对点击跳转进行可控。

// 组件内触发属性事件
_readOnly: function () {
      this.triggerEvent('readOnlyEle')
    }

之后在应用页进行一个事件绑定即可

<search readOnly="true" bind:readOnlyEle="goSearch" />

其中在组件还需要只读属性,在作为装饰即点击跳转组件的时候将只读属性设置为false

输入,清空与搜索内容

输入内容需要将输入框内容设置子组件数据并将该数据通过triggerEvent进行组件传值,将数据传入父组件中

let _value = e.detail.value;
      this.setData({
        value: _value
      });
      this.triggerEvent('input', {
        value: _value
      });

在搜索完后想要再次搜索需要考虑将内容清空,所以在点击清空叉号后触发清空事件,将子组件和父组件的数据清空。

    _searchClear: function (e) {
      this.setData({
        value: ''
      });
      this.triggerEvent('clear', {});
    },

搜索在子组件通过传值方式触发父组件的搜索函数,将搜索内容解构出来并判断内容是否为空。

   _searchConfirm: function (e) {
      let { value } = this.data;
      if (!value) return false
      this.triggerEvent('search', { value });
    },

模糊搜索

小程序使用的是云开发,所以封装了一个搜云函数,核心的模糊搜索实现如下

let config = index != 1 ?
      {
        title: db.RegExp({
          regexp: content,//miniprogram做为关键字进行匹配
          options: 'i',//不区分大小写
        })
      } : {
        name: db.RegExp({
          regexp: content,//miniprogram做为关键字进行匹配
          options: 'i',//不区分大小写
        })
      }
    db.collection(types[index]).where(config).get().then((res) => {
      let { data } = res;
      if (data.length) result[types[index]] = data;
      resolve(recursion(content, result, types, index + 1));
    });

将传入的参数通过对象的形式封装起来,并赋于regexp属性用来匹配结果,最后通过db.collection调用在库中匹配搜索即完成模糊搜索功能