效果图:

正版多商户小程序拼团,开发中
https://www.kancloud.cn/tpcms/merchant

search.js

const app = getApp(), util = require('../utils/util.js');

Page({
  data: {
    isLoading: true,
    isOperate: false,
    goods: [],
    isHideLoadMore: true,
    isNoNetError: true,
    isHideNoMore: true,
    searchKeyword: ""
  },
  setSearchKeyword(e) {
    this.setData({
      searchKeyword: e.detail.value
    })
  },
  goodsList: function () {
    var that = this, size = 30;
    
    if(!this.data.searchKeyword) {
      util.toast(that, "请输入关键词")
      return;
    }
    

    that.data.goods = [];
    wx.request({
      url: app.globalData.proApiUrl + 'v1.0/goods',
      data: { offset: that.data.goods.length, size: size, keyword: this.data.searchKeyword },
      success: function (res) {
        that.setData({
          goods: res.data.goods
        });

        let goodsIds = [];
        res.data.goods.forEach(item => {
          goodsIds.push(item.goods_id);
        });

        that.setData({
          isNoNetError: true
        });
      },
      fail: function (res) {
        that.setData({
          isNoNetError: false
        });
      },
      complete: function (res) {
        wx.stopPullDownRefresh();
        that.setData({
          isLoading: false
        });

        if (res.data.goods.length < size) {
          that.setData({ isHideNoMore: false, isHideLoadMore: true });
        }
      }
    });
  },


  loadData: function () {
    var that = this;
    this.goodsList();
  },

  onNetErrorRefresh: function () {
    util.loading(this),
    this.loadData();
  },

  onPullDownRefresh: function () {
    this.setData({isHideNoMore: true}),
    this.loadData();
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    if (this.data.isHideLoadMore && this.data.isHideNoMore) {
      this.loadMore();
    }
  },

  loadMore: function () {
    var that = this, size = 15;
    that.setData({
      isHideLoadMore: false
    });
    wx.request({
      url: app.globalData.apiUrl + 'v1.0/goods',
      data: { offset: that.data.goods.length, size: size, merchant_id: merchantId},
      success: function (res) {
        that.setData({
          goods: that.data.goods.concat(res.data.goods)
        });
        
        let goodsIds = [];
        res.data.goods.forEach(item => {
          goodsIds.push(item.goods_id);
        });
      },
      fail: function (res) {

      },
      complete: function (res) {

        that.setData({
          isHideLoadMore: true
        });

        if (res.data.goods.length < size) 
        {
          that.setData({ isHideNoMore: false });
        }
      }
    });
  },

  onLoad: function (options) {
    // this.loadData();
  },

  onShow: function () {
  },

  goTop: function () {
    wx.pageScrollTo({ scrollTop: 0 });
  },
  
  onPageScroll: function (e) {
    if (e.scrollTop != undefined && app.globalData.windowHeight < e.scrollTop) {
      this.setData({ "goTopClass": 'bgt-top-button-show' });
    } else {
      this.setData({ "goTopClass": 'bgt-top-button-hide' });
    }
  },
  
  onTabItemTap: function (item) {
    wx.startPullDownRefresh();
  },
  onShareAppMessage: function () {
    return app.share({ title: "", desc: "", path: "" });
  },
  bannerClick: function (e) {
    var bannerType = e.currentTarget.dataset.banner_type, targetUrl = e.currentTarget.dataset.target_url;

    switch (bannerType) {
      case "1":
        wx.navigateTo({
          url: targetUrl,
        });
        break;

      case "2":
        wx.navigateTo({
          url: './webview?url=' + targetUrl,
        });
        break;

      default:
        break;
    }

  },
  bindRedirect: function(e) {
    util.redirect(e.currentTarget.dataset.url);
  }
})

search.wxml

<view class="search-header">
  <input class="search-base" placeholder="请输入关键词" bindinput="setSearchKeyword" />
  <view class="search-button" bind:tap="loadData">搜索</view>
</view>

<page-loading isLoading="{{isLoading}}" isOperate="{{isOperate}}"></page-loading>

<block>
  <view class="div" id="pmv" hidden="{{(isLoading && !isOperate) || !isNoNetError}}" style="background-color:#f2f2f2;box-sizing: border-box;">

    <block hidden="{{!searchKeyword}}">
      <view class="div" id="pcv" style="">
        <view class="div" id="pcv-tv1-14" style="">
          <view id="pcv-tv1-14-pcl" class="div react-base-list-wrapper pcl-list-wrapper" style="">
            <block wx:key="item" wx:for="{{goods}}">
              <view id="cat-14-g-30397685" class="div double-grid-one double-grid-one-0" bindtap="bindRedirect" data-url="./goods?goods_id={{item.goods_id}}">
                <view class="div double-grid-item gap-right">
                  <view class="div std-goods-image-square goods-image">
                    <image src="{{item.image_url}}" mode="aspectFill" />
                  </view>
                  <view class="div goods-name">{{item.goods_name}}</view>

                  <view class="div detail">
                    <view class="b price-icon">¥</view>
                    <view class="b price">{{item.group_price}}</view>
                    <view class="div info">
                      <view class="span">
                        已团{{item.sell_count}}件</view>
                    </view>
                  </view>
                </view>
              </view>
            </block>
          </view>
        </view>
      </view>
    </block>

    <view class="div no-empty-center" wx:if="{{goods.length == 0}}">
      <view class="p no-empty-tips" data-reactid="196">暂无商品~</view>
    </view>

    <view class="div bgt-go-top {{goTopClass}}" catchtouchstart="goTop" catchtouchend="goTop">
      <view class="span">顶部</view>
    </view>
  </view>
</block>

<net-error-tips isNoNetError="{{isNoNetError}}" bind:loadData="onNetErrorRefresh"></net-error-tips>
<load-more isHideLoadMore="{{isHideLoadMore}}" isHideNoMore="{{isHideNoMore || goods.length == 0}}"></load-more>

search.wxss

/* pages/search.wxss */
.search-header {
  background: #fff;
  font-size: 32rpx;
  padding: 24rpx;
  display: flex;
  align-items: center;
}

.search-base {
  background-color: #ededed;
  color: #9c9c9c;
  height: 76rpx;
  display: flex;
  align-items: center;
  border-radius: 16rpx;
  flex: 1;
  padding: 0 32rpx;
}

.search-button {
  margin-left: 24rpx;
  color: #FFC300;
  font-size: 36rpx;
  font-weight: bold;
}


.no-empty-center {
  text-align: center;
}

.load-all-tips,.no-empty-tips {
  color: #9c9c9c;
  font-size: 28rpx;
  margin-top: 240rpx;
}

ThinkPHP
4 声望3 粉丝