自定义搜索组件实现全部功能

Posted 老张在线敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义搜索组件实现全部功能相关的知识,希望对你有一定的参考价值。

详情点击链接查看
如下代码只做记录没讲解
首先在项目的components文件夹的my-search文件中

写入代码如下:

<template>
 <view class="my-search-container" :style="'background-color': bgcolor">
   <view class="my-search-box" :style="'border-radius': radius + 'px'" @click="searchBoxHandler">
     <!-- 使用uni-ui的组件 -->
     <icon type="search" size="17"></icon>
     <text class="placeholder">搜索</text>
   </view>
 </view>
</template>

<script>
  export default 
    
    name:"my-search",
    data() 
      return 
        
      ;
    ,
    props: 
      // 背景颜色
      bgcolor: 
        type: String,
        default: '#C00000'
      ,
      // 圆角尺寸
      radius: 
        type: Number,
        // 单位是 px
        default: 18
      
    ,
    methods: 
      // 点击了模拟的 input 输入框
      searchBoxHandler() 
        // 触发外界通过 @click 绑定的 click 事件处理函数
        this.$emit('click')
      
    
  
</script>

<style lang="scss">
.my-search-container 
  // background-color: #c00000;
  height: 50px;
  padding: 0 10px;
  display: flex;
  align-items: center;


.my-search-box 
  height: 36px;
  background-color: #ffffff;
  // border-radius: 15px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;

  .placeholder 
    font-size: 15px;
    margin-left: 5px;
  

</style>

效果展示

在pages文件夹中的使用者文件中

<template>
  <view>
    <!-- 使用自定义的搜索组件 -->
    <view class="search-box" >
      <!-- 动态传入背景颜色值与圆角值   -->
    <mySearch @click="gotoSearch" :bgcolor="'#c00000'" :radius="15"></mySearch>
    </view>
    <view class="scroll-view-container">
    <!-- 左侧的滚动视图区域 -->
    <scroll-view class="left-scroll-view" scroll-y :style="height: wh + 'px'">
    <block v-for="(item, i) in cateList" :key="i">
      <view :class="['left-scroll-view-item', i === active ? 'active' : '']" @click="activeChanged(i)">item.cat_name</view>
    </block>
    </scroll-view>
      <!-- 右侧的滚动视图区域 -->
    <!-- 右侧的滚动视图区域 -->
    <scroll-view class="right-scroll-view" scroll-y :style="height: wh + 'px'" :scroll-top="scrollTop">
      <view class="cate-lv2" v-for="(item2, i2) in cateLevel2" :key="i2">
        <view class="cate-lv2-title">/ item2.cat_name /</view>
        <!-- 动态渲染三级分类的列表数据 -->
        <view class="cate-lv3-list">
          <!-- 三级分类 Item 项 -->
          <view class="cate-lv3-item" v-for="(item3, i3) in item2.children" :key="i3"  @click="gotoGoodsList(item3)">
            <!-- 图片 -->
            <image :src="item3.cat_icon" mode=""></image>
            <!-- 文本 -->
            <text>item3.cat_name</text>
          </view>
        </view>
      </view>
    </scroll-view>
    </view>
  </view>
</template>


<script>
  import mySearch from "@/components/my-search/my-search.vue"
   export default 
     components:
        mySearch
     ,
     data() 
       return 
         // 窗口的可用高度 = 屏幕高度 - navigationBar高度 - tabBar 高度
         wh: 0,
        // 分类数据列表
        cateList: [],
        // 当前选中项的索引,默认让第一项被选中
        active: 0,
         // 二级分类列表
        cateLevel2: [],
      // 滚动条距离顶部的距离
          scrollTop: 0
       ;
     ,
     onLoad() 
       // 获取当前系统的信息
       const sysInfo = uni.getSystemInfoSync()
       // 可用高度 = 屏幕高度 - navigationBar高度 - tabBar高度 - 自定义的search组件高度
       this.wh = sysInfo.windowHeight - 50
        // 调用获取分类列表数据的方法
        this.getCateList()
     ,
    methods: 
      async getCateList() 
        // 发起请求
        const  data: res  = await uni.$http.get('/api/public/v1/categories')
        // 判断是否获取失败
        if (res.meta.status !== 200) return uni.$showMsg()
        // 转存数据
        this.cateList = res.message
         // 为二级分类赋值
        this.cateLevel2 = res.message[0].children
        console.log(this.cateList)
      ,
        // 选中项改变的事件处理函数
        activeChanged(i) 
          this.active = i
          // 为二级分类列表重新赋值
          this.cateLevel2 = this.cateList[i].children
          console.log(this.cateLevel2)
          // 让 scrollTop 的值在 01 之间切换
          this.scrollTop = this.scrollTop?0 :1
         ,
        // 点击三级分类项跳转到商品列表页面
        gotoGoodsList(item3) 
          uni.navigateTo(
            url: '/subpkg/pages/goods_list/goods_list?cid=' + item3.cat_id
          )
        ,
        // 跳转到分包中的搜索页面
        gotoSearch() 
          uni.navigateTo(
            url: '/subpkg/pages/search/search'
          )
        
    
       

   
</script>

<style lang="scss">
.scroll-view-container 
  display: flex;

  .left-scroll-view 
    width: 120px;

    .left-scroll-view-item 
      line-height: 60px;
      background-color: #f7f7f7;
      text-align: center;
      font-size: 12px;

      // 激活项的样式
      &.active 
        background-color: #ffffff;
        position: relative;

        // 渲染激活项左侧的红色指示边线
        &::before 
          content: ' ';
          display: block;
          width: 3px;
          height: 30px;
          background-color: #c00000;
          position: absolute;
          left: 0;
          top: 50%;
          transform: translateY(-50%);
        
      
    
  
 .cate-lv2-title 
   font-size: 12px;
   font-weight: bold;
   text-align: center;
   padding: 15px 0;
 
 .cate-lv3-list 
   display: flex;
   flex-wrap: wrap;
 
   .cate-lv3-item 
     width: 33.33%;
     margin-bottom: 10px;
     display: flex;
     flex-direction: column;
     align-items: center;
 
     image 
       width: 60px;
       height: 60px;
     
 
     text 
       font-size: 12px;
     
   
 

</style>

效果

点击搜索跳转到的搜索组件(分包内的search组件)

<template>
<view class="">
  <view class="search-box">
      <uni-search-bar :focus="true"  @input="input" cancelButton="none">
   		</uni-search-bar>
      <!-- 搜索建议列表 -->
     
  </view>
   <view class="sugg-list"  v-if="searchResults.length !== 0">
        <view class="sugg-item" v-for="(item, i) in searchResults" :key="i" @click="gotoDetail(item.goods_id)">
          <view class="goods-name">item.goods_name</view>
          <uni-icons type="arrowright" size="16"></uni-icons>
        </view>
      </view>
      <!-- 搜索历史 -->
      <view class="history-box" v-else>
        <!-- 标题区域 -->
        <view class="history-title">
          <text>搜索历史</text>
         <uni-icons type="trash" size="17" @click="cleanHistory"></uni-icons>
        </view>
        <!-- 列表区域 -->
        <view class="history-list">
          <uni-tag :text="item" v-for="(item, i) in historys" :key="i"  @click="gotoGoodsList(item)">
            <text style="margin: 10rpx;border: 1rpx solid #999999;">item</text>
          </uni-tag>
        </view>
      </view>
</view>
</template>

<script>
  export default 
    data() 
      return 
            // 延时器的 timerId
            timer: null,
            // 搜索关键词
            kw: '',
            // 搜索结果列表
            searchResults: [],
            // 搜索关键词的历史记录
            historyList: ['a', 'app', 'apple']
      ;
    ,
    onLoad()
       this.historyList = JSON.parse(uni.getStorageSync('kw') || '[]')
    ,
    methods: 
      input(e) 
        // 清除 timer 对应的延时器
        clearTimeout(this.timer)
        // 重新启动一个延时器,并把 timerId 赋值给 this.timer
        this.timer = setTimeout(() => 
          // 如果 500 毫秒内,没有触发新的输入事件,则为搜索关键词赋值
          this.kw = e
          console.log(this.kw)
          this.getSearchList()
        , 500)
      ,
      // 根据搜索关键词,搜索商品建议列表
      async getSearchList() 
        // 判断关键词是否为空
        if (this.kw === '') 
          this.searchResults = []
          return
        
        // 发起请求,获取搜索建议列表
        const  data: res  = await uni.$http.get('/api/public/v1/goods/qsearch',  query: this.kw )
        if (res.meta.status !== 200) return uni.$showMsg()
        this.searchResults = res.message
        console.log(res.message)
        if(res.message.length==0)
          console.log(111)
          uni.showToast(
            title:"暂无相关内容",
            icon:"none"
          )
        else
          this.saveSearchHistory()
        
      ,
      gotoDetail(goods_id) 
        uni.navigateTo(
          // 指定详情页面的 URL 地址,并传递 goods_id 参数
          url: '/subpkg/pages/goods_detail/goods_detail?goods_id=' + goods_id
        )
      ,
      // 保存搜索关键词为历史记录
      saveSearchHistory() 
        const set = new Set(this.historyList)
        set.delete(this.kw)
        set.add(this.kw)
        this.historyList = Array.from(set)
        // 调用 uni.setStorageSync(key, value) 将搜索历史记录持久化存储到本地
        uni.setStorageSync('kw', JSON.stringify(this.historyList))
      ,
      // 清空搜索历史记录
      cleanHistory() 
        // 清空 data 中保存的搜索历史
        this.historyList = []
        // 清空本地存储中记录的搜索历史
        uni.setStorageSync('kw', '[]')
      ,
      // 点击跳转到商品列表页面
      gotoGoodsList(kw) 
        uni.navigateTo(
          url: '/subpkg/pages/goods_list/goods_list?query=' + kw
        )
      
    ,
    computed: 
      historys() 
        // 注意:由于数组是引用类型,所以不要直接基于原数组调用 reverse 方法,以免修改原数组中元素的顺序
        // 而是应该新建一个内存无关的数组,再进行 reverse 反转
        return [...this.historyList].reverse()
      
    
  
</script>

<style lang="scss">
.search-box 
  position: sticky;
  top: 0;
  z-index: 999;
  background: #c00000;
  padding: 10rpx;
  align-items: center;
  input
   height: 36px;
   background-color: #ffffff;
   border-radius: 15px;
   width: 100%;
   display: flex;
   align-items: center;
   justify-content: center;
   
   .placeholder 
     font-size: 15px;
     margin-left: 5px;
   
  

.sugg-list 
  padding: 0 5px;

  .sugg-item 
    font-size: 12px;
    padding: 13px 0;
    border-bottom: 1px solid #efefef;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .goods-name 
      // 文字不允许换行(单行文本)
      white-space: nowrap;
      // 溢出部分隐藏
      overflow: hidden;
      // 文本溢出后,使用 ... 代替
      text-overflow: ellipsis;
      margin-right: 3px;
    
  

.history-box 
  padding: 0 5px;

  .history-title 
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 40px;
    font-size: 13px;
    border-bottom: 1px solid #efefef;
  

  .history-list 
    display: flex;
    flex-wrap: wrap;

    .uni-tag 
      margin-top: 5px;
      margin-right: 5px;
    
  

</style>


效果

以上是关于自定义搜索组件实现全部功能的主要内容,如果未能解决你的问题,请参考以下文章

小程序关键字搜索功能(按钮搜索和回车搜索)

Android中ListView字母排序,实现字母挤压效果以及右侧快速选中字母,搜索关键字功能

Android中ListView字母排序,实现字母挤压效果以及右侧快速选中字母,搜索关键字功能

Android中ListView字母排序,实现字母挤压效果以及右侧快速选中字母,搜索关键字功能

使用APICloud AVM多端组件快速实现app中的搜索功能

salesforce lightning零基础学习(十三) 自定义Lookup组件(Single & Multiple)