uniapp s搜索功能实现

首先搜索功能实现

一、布局

搜索栏普遍出现在app首页 同时我们在点击搜索栏之后会跳转到搜索页面 草图例
在这里插入图片描述在这里插入图片描述
相比而言我们发现这个搜索栏在上方样式和布局基本差不多 所以我们把这个搜索栏抽离出来封装成一个组件进行复用

<template>
  <view class="nav-bar">
    <view class="nav-bar-top">
      <view :style="{height:statusHeight + 'rpx'}"></view>

      <!--当界面为搜索界面的时候,添加回退按钮  -->
      <view @click="returnArticleList" :style="{top:statusHeight + 'rpx'}"
       class="return-icon" v-if="isSearch">
        <uni-icons type="back" size="22" color="white"></uni-icons>
      </view>

      <view @click="goSearchPage" class="nav-bar-content" 
      :style="{marginRight:marginRight + 'rpx',marginLeft:isSearch?'20rpx':''}">
        <uni-icons class="nav-bar-search-icon" type="search" color="#999"></uni-icons>
        <view v-if="!isSearch" class="nav-bar-search-txt">输入文章标题进行搜索</view>
        <input @confirm="changeInputVal" confirm-type="search" 
        v-else class="search-input" v-model.trim="searchVal" type="text" placeholder="输入文章标题进行搜索">
      </view>
    </view>
    <!-- 底部垫片 -->
    <view :style="{height:80 + statusHeight + 'rpx'}"></view>
  </view>
</template>

首先我们作为uniapp要考虑到多端适配在小程序中 会出现胶囊 右上角双按键
同时在布局上小程序会在上面出现 时间 任务栏 WiFi 等标志 所以我们的布局也要考虑到小程序适配问题
我们把这个小程序单独进行配置

  created () {
    /* 初始化获取状态栏高度 */
    this.initStatusBarHeight()
  },
   methods: {
	initStatusBarHeight () {
	      const systemInfo = uni.getSystemInfoSync()
	      this.statusHeight = systemInfo.statusBarHeight ? systemInfo.statusBarHeight * 2 : 20;
	      /* 如果是小程序的换,进行胶囊处理*/
	      // #ifdef MP-WEIXIN
	      const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
	      this.marginRight = menuButtonInfo.width * 2
	      this.statusHeight = menuButtonInfo.top * 2
	      // #endif
	    },
    }

同时我们添加一个点击搜索栏就跳转,同时我们跳转到搜索页面之后 会有一个返回按钮
同时我们注意在h5刷新之后 历史记录站会清空 跳转不回来 这里需要我们单独布置

goSearchPage () {
      if (this.isSearch) return
      uni.navigateTo({
        url: '/pages/search/search'
      })
    },
    // 返回文章列表界面
    returnArticleList () {
      // #ifdef H5
      uni.switchTab({
        url: '../../pages/index/index'
      })
      // #endif
      // #ifndef H5
      uni.navigateBack()
      // #endif
    },

在搜索页面中 布局如下

<template>
  <view class="search-container">
    <!-- 搜索导航组件 -->
    <NavBar @sendSearchData="_sendSearchData" :isSearch="isSearch" :parentVal="parentVal" @updateVal="parentVal=$event"></NavBar>
    <!-- 搜索包裹 -->
    <view v-if="isShowHistory" class="search-wrapper">
      <!-- 没有进行搜索的操作 -->
      <view class="search-history-container">
        <!-- 头部 -->
        <view class="search-header">
          <text class="history-text">搜索历史</text>
          <text class="history-clean" @click="cleanHistory">清空</text>
        </view>
        <!-- 内容部分 -->
        <view v-if="historyList.length" class="search-history-content">
          <view @click="openHistory(item)" class="history-content-item" v-for="(item,index) in historyList" :key="index">{{item}}</view>
        </view>
        <view v-else class="no-data">当前没有搜索历史</view>
      </view>
    </view>
    <!-- 开始进行搜索的操作 -->
    <view v-else class="search-list-container">
      <ListItem  @saveHistory="saveHistory" :isShowLoading="isShowLoading" :articleList="searchList" @loadmore="loadmore" v-if="searchList.length"></ListItem>
      <view v-else class="no-data">没有搜索到相关数据</view>
    </view>
  </view>
</template>

主要目的是
获取搜索内容
搜索之后出发请求返回数据渲染
将当前搜索内容进行存储为历史
渲染搜索历史 如果没有不显示
点击历史搜索可直接跳转

export default {
  data () {
    return {
      isSearch: true,
      searchList: [],
      parentVal: '',
      isShowLoading: false,
      isShowHistory: true,
    }
  },
  methods: {
    // 开始进行内容搜索
    async _sendSearchData () {
      this.isShowHistory = false
      if (!this.parentVal) {
        this.isShowHistory = true
        this.searchList = []
        return
      }
      const { articleList, total } = await this.$http.get_search_data({ searchVal: this.parentVal })
      this.searchList = articleList
    },
    // 弹出搜索内容
    openHistory(val) {
      this.parentVal = val
      this._sendSearchData()
    },  
    // 进行收藏历史记录操作
    saveHistory(val) {
      this.setHistory(this.parentVal)
    },
    ...mapMutations(['setHistory','cleanHistory'])
  },
  computed: {
    ...mapState(['historyList'])
  }
}

数据库操作跟我们的文章列表类似 只不过索引变为关键词

'use strict';
const db = uniCloud.database()
exports.main = async (event, context) => {
  const {
    searchVal,
  } = event


  const list = await db.collection('article')
    .aggregate() // 使用聚合的形式进行数据的获取
    // 使用正则表达式进行模糊匹配,只要是包含,就进行返回操作
    .match({ title: new RegExp(searchVal) })
    .project({
      content: 0 // 本次查询不需要返回文章详情给前端
    })
    .end()


  //返回数据给客户端
  return {
    code: 0,
    msg: "搜索数据请求成功",
    data: {
      articleList: list.data
    },
  }
};


版权声明:本文为weixin_41558808原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。