更新记录

1.0.1(2023-04-21)

  1. 功能自测
  2. 输入关键词,下拉列表展示搜索结果
  3. 类似百度搜索,搜索关键词变红
  4. 优化组件逻辑,方便父子组件传值
  5. 增加DEMO:/components/pages/index
  6. 增加完整说明文档 +案例

1.0.0(2023-04-20)

v1.0.0

搜索组件:

包含热门搜索,搜索联想,关键词标红


平台兼容性

Vue2 Vue3
×
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.3.13 app-vue app-nvue
钉钉小程序 快手小程序 飞书小程序 京东小程序
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
×

search 搜索页

  1. 【搜索页面,界面简洁大气,颜值即正义】
  2. 本地项目引入阿里图标库,小巧的字体文件节省空间
  3. 使用方法:“HBuilderX导入插件”,然后复制参考DEMO的代码

    参考DEMO /components/pages/index

    <zhangguangsen-search
    :hotList="hotList"
    :searchList="searchList"
    @onInput="onInput"\
    @onSearchConfirm="onSearchConfirm">
    </zhangguangsen-search>
    export default {
    data() {
        return {
            hotList:['aa','bb','cc','dd','测试一个超产的龙欧索','aa','bb','cc','dd','测试一个超产的龙欧索'],
            searchList:[]
        }
    },
    mounted(){
    },
    methods: {
        onInput(val){
            console.log('**input',val)
            //模拟后端返回数据,根据val调用接口
            setTimeout(()=>{
                 this.searchList = ['aabacd','bb','cc','dd','测试一个超产的龙欧索','aa',Math.random()]//这里模拟 axios 返回的数据
            },2000)
        },
        onSearchConfirm(searchVal){
            console.log('搜索词',searchVal)
        }
    }
    }

    组件代码

    • 可复制代码,自己封一个组件;再需要下载插件ZIP,将字体文件引入项目即可;
    • 推荐的用法,还是通过“HBuilderX导入插件”
      <view class="search">
      <view class="search-head">
      <view class="head-icon__search iconfont icon-sousuo1"></view>
      <view class="head-input__search">
          <input v-model="val" :focus="true" :adjustPosition="false" placeholder="请输入配件名称" placeholder-class="head-input__placeholder" confirmType="搜索" :confirmHold="false" @input="handleInput" @click="handleClick" @confirm="handleConfirm"/>
          <button @click="handleConfirm">搜索</button>
      </view>
      </view>
      <view class="hotSearch">
      <view class="hotSearch-head">
          <view class="hotSearch-icon__hot iconfont icon-remensousuo"></view>
          <text class="hotSearch-text__hot">
               热门搜索
          </text>
      </view>
      <view class="hotSearch-list">
          <view class="hotSearch-li" v-for="(item,index) in hotList" :key="index" @click="handleConfirm(item)">
              {{item}}
          </view>
      </view>
      </view>
      <view v-show="showPop">
      <view class="pop-search__list">
          <view class="pop-search__li" v-for="(item,index) in formatSearchList" :key="index" @click="handleConfirm(item)">
              <text v-for="(titem,tindex) in item" :key="tindex" :class="titem.key ? 'active' : ''">{{titem.str}}</text>
          </view>
      </view>
      <view class="pop-search__mask" @click="showPop=false"></view>
      </view>
      </view>
props:{
    hotList:{
        type:Array
    },
    searchList:{
        type:Array
    }
},
watch:{
    searchList:{
        handler(searchList){
            uni.hideLoading();
            console.log('watch',searchList)
            if(searchList.length>0 && this.val){
                this.formatSearchList = searchList.map(item=>this.hilight_word(this.val, item))
            }
        },
        deep:true
    }
},
data() {
    return {
        val:'',
        showPop:false,
        formatSearchList:[]
    }
},
mounted(){
},
methods: {
    handleConfirm(val){
        let searchVal = val
        if(Array.isArray((val))){
            searchVal = val.map(({str})=>str).join('')
        }else if(val instanceof Object){
            searchVal = this.val
        }
        this.$emit('onSearchConfirm',searchVal)
    },
    handleClick(){
        this.showPop = !!this.val
    },
    handleInput(e){
        this.showPop = !!this.val
        if(!this.val) {
            return
        }
        uni.showLoading({
            title: '加载中'
        });
        setTimeout(()=>uni.hideLoading(),3000)
        this.$emit('onInput',this.val)
    },
    // 根据搜索字分割字符
    hilight_word: function (key, word) {
        key=key.trim()
        word=''+word
        let idx = word.indexOf(key), t = [];

        if (idx > -1) {
          if (idx == 0) {
            t =this.hilight_word(key, word.substr(key.length));
            t.unshift({ key: true, str: key });
            return t;
          }

          if (idx > 0) {
            t =this.hilight_word(key, word.substr(idx));
            t.unshift({ key: false, str: word.substring(0, idx) });
            return t;
          }
        }
        return [{ key: false, str: word }];
    }
}
<style lang="scss">
@font-face {
  font-family: "iconfont"; /* Project id 3928599 */
  src: url('@/static/zhangguangsen-search/zhangguangsen-search.woff2?t=1681960188787') format('woff2'),
       url('@/static/zhangguangsen-search/zhangguangsen-search.woff?t=1681960188787') format('woff'),
       url('@/static/zhangguangsen-search/zhangguangsen-search.ttf?t=1681960188787') format('truetype');
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-remensousuo:before {
  content: "\e73d";
}

.icon-sousuo1:before {
  content: "\e61c";
}

.search{
    background-color: #fff;
    overflow: hidden;
    &-head{
        display: flex;
        align-items: center;
        padding:0 10rpx 0 47rpx;
        margin:30rpx 30rpx 0;
        height: 70rpx;
        background: #F5F5F5;
        border-radius: 35rpx;
        .head-icon__search{
            font-size: 30rpx;
            color: #231815;
        }
        .head-input__search{
            display: flex;
            align-items: center;
            flex: 1;
            input{
                margin-left: 15rpx;
                border: none;
                height: 29rpx;
                font-size: 30rpx;
                font-weight: 400;
                color: #AAAAAA;
                line-height: 28rpx;
                flex:1;
            }
            button{
                width: 128rpx;
                height: 53rpx;
                background: linear-gradient(0deg, #0AA0F5, #00E3F2);
                border-radius: 30rpx;
                font-size: 28rpx;
                font-weight: 500;
                color: #FFFFFF;
                line-height: 42rpx;
            }
            .head-input__placeholder{
                color: #AAAAAA;
            }
        }
    }
    .hotSearch{
        margin-top: 30rpx;
        &-head{
            display: flex;
            align-items: center;
            padding:0 0 0 30rpx;
        }
        &-icon__hot{
            margin-left: 10rpx;
            font-size: 30rpx;
            color: rgb(255,43,57);
        }
        &-text__hot{
            margin-left: 10rpx;
            font-size: 30rpx;
            color: #999999;
        }
        &-list{
            padding: 20rpx 0 50rpx 30rpx;
            display: flex;
            flex-wrap: wrap;
        }
        &-li{
            margin: 10rpx 0 0 10rpx;
            padding: 0 20rpx;
            border-radius: 20rpx;
            background: #f2f2f2;
            line-height: 50rpx;
            &:first-child{
                margin-left: 0;
            }
        }
    }
}
.pop{
    &-search{
        &__mask{
            position: fixed;
            top: 100rpx;
            bottom: 0;
            left: 0;
            right: 0;
            background-color: rgba(0, 0,0,.3);
            z-index: 1;
        }
        &__list{
            padding:0 30rpx;
            position: fixed;
            top: 100rpx;
            left: 0;
            right: 0;
            background-color: #fff;
            z-index: 9;
        }
        &__li{
            font-size: 30rpx;
            color: #231815;
            line-height: 90rpx;
            border-bottom: solid 1px #F5F5F5;
            .active{
                color: red;
            }
        }
    }
}
</style>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问