微信小程序 van-sticky + swiper + scroll-view + DropdownMenu + TreeSelect 实现顶部固定、可滑动/滚动/点击切换、选择地区、刷新、分页加载

 一、如图:

  二、js:

import {
  getArea,
  getProductList
} from "../../../../../api/dsxapi";
const ui = require("../../../../../utils/ui");
Page({
  data: {
    navData: ['法律', '财税', '投融资', '知识产权', '企业产业链', '园区招商', '综合业务'],
    currentTab: 0, //标签下标
    navScrollLeft: 0,
    itemTitle: "服务地区",
    mainActiveIndex: 0,
    activeId: null,
    items: null,
    province: '', //省
    provinceId: null, //省份id
    marketId: null, //市id
    ProductList: [], //产品列表
    pages: 0,
    current: 1,
    top: 0
  },
  onLoad(options) {
    // 滚动
    wx.getSystemInfo({
      success: (res) => {
        this.setData({
          windowWidth: res.windowWidth
        })
      },
    })
  },
  onShow() {
    this.ObtainArea()
    this.ObtainProductList(this.data.current)
  },

  //获取地区
  ObtainArea() {
    getArea().then((res) => {
      let ress = res.data.map((item) => {
        return {
          text: item.areaName,
          id: item.areaId,
          children: [{
              text: '全部',
              id: -1
            },
            ...item.children.map((items) => {
              return {
                text: items.areaName,
                id: items.areaId
              }
            })
          ]
        }
      })
      ress.unshift({
        text: "全国"
      });
      this.setData({
        items: ress
      })
    }).catch(function (imError) {})
  },

  //获取产品列表
  ObtainProductList(current) {
    let params
    let category
    if (this.data.currentTab == 0) {
      category = 100621
    } else if (this.data.currentTab == 1) {
      category = 100622
    } else if (this.data.currentTab == 2) {
      category = 100623
    } else if (this.data.currentTab == 3) {
      category = 100624
    } else if (this.data.currentTab == 4) {
      category = 100625
    } else if (this.data.currentTab == 5) {
      category = 100626
    } else if (this.data.currentTab == 6) {
      category = 100627
    }
    if (this.data.marketId !== null) {
      params = {
        category: category, //标签id
        provinceId: this.data.provinceId, //省id
        cityId: this.data.marketId, //市id
        current: current,
        searchId: 11,
        size: 100,
      };
    } else {
      params = {
        category: category, //标签id
        current: current,
        size: 20,
      };
    }
    getProductList(params).then((res) => {
      let ProductList
      if (res.data.current == 1) {
        ProductList = res.data.records;
        ProductList.forEach((item, index) => {
          item.proTags = item.proTags.split(",")
        })
      } else {
        ProductList = this.data.ProductList;
        res.data.records.forEach((item, index) => {
          item.proTags = item.proTags.split(",")
        })
        Array.prototype.push.apply(ProductList, res.data.records);
      }
      this.setData({
        pages: res.data.pages,
        current: res.data.current,
        ProductList: ProductList
      });
    }).catch(function (imError) {
      console.log(imError);
    })
  },

  //跳转产品详情
  goDetails(event) {
    wx.navigateTo({
      url: `/subPackag/pages/consult_jump/EnterprisePiece/product/product?id=${event.currentTarget.dataset.id}`
    })
  },

  //地区选择外层
  onClickNav({
    detail = {}
  }) {
    if (detail.index == 0) {
      this.setData({
        itemTitle: this.data.items[detail.index].text,
        marketId: null
      })
      this.selectComponent('#item').toggle();
      // 这里请求全部的
      this.ObtainProductList(this.data.current)
      this.setData({
        top: 0
      })
    } else {
      this.setData({
        province: this.data.items[detail.index].text,
        provinceId: this.data.items[detail.index].id,
      })
    }
    this.setData({
      mainActiveIndex: detail.index || 0,
    });
  },

  //点击地址选项赋值关闭下拉菜单
  onClickItem({
    detail = {}
  }) {
    const activeId = this.data.activeId === detail.id ? null : detail.id;
    if (detail.text == '全部') {
      this.setData({
        activeId: activeId,
        itemTitle: this.data.province,
        marketId: detail.id
      });
    } else {
      this.setData({
        activeId: activeId,
        itemTitle: this.data.province + '-' + detail.text,
        marketId: detail.id
      });
    }
    this.selectComponent('#item').toggle();
    this.ObtainProductList(this.data.current)
    this.setData({
      top: 0
    })
  },

  //点击标签切换、滚动
  switchNav(event) {
    let cur = event.currentTarget.dataset.current;
    //每个tab选项宽度占1/5
    let singleNavWidth = this.data.windowWidth / 5;
    //tab选项居中                            
    this.setData({
      navScrollLeft: (cur - 2) * singleNavWidth
    })
    if (this.data.currentTab == cur) {
      return false;
    } else {
      this.setData({
        currentTab: cur
      })
    }
  },

  //滑动切换滚动
  switchTab(event) {
    let cur = event.detail.current;
    let singleNavWidth = this.data.windowWidth / 5;
    this.setData({
      currentTab: cur,
      navScrollLeft: (cur - 2) * singleNavWidth,
      current: 1
    });
    this.ObtainProductList(this.data.current)
    this.setData({
      top: 0
    })
  },

  //上拉触底
  onReachBottom() {
    if (this.data.current < this.data.pages) {
      this.ObtainProductList(this.data.current + 1);
    } else if (this.data.current > this.data.pages || this.data.current == this.data.pages) {
      // wx.showToast({ //如果全部加载完成了弹一个框
      //   title: '已经没有更多啦!',
      //   icon: 'success',
      //   duration: 1500
      // });
      ui.showToast('已经没有更多啦');
    }
  },

  //下拉刷新
  onPullDownRefresh() {
    let thi = this
    setTimeout(function () {
      thi.ObtainProductList(1)
      wx.stopPullDownRefresh(); //停止下拉刷新
    }, 100);
  },

  onShareAppMessage: function () { //分享好友
    return {
      title: '企服集市',
      desc: '51大师兄',
      path: '/subPackag/pages/consult_jump/EnterprisePiece/market/market',
      imageUrl: '',
      success: function (res) {
        wx.showToast({
          title: '分享成功',
          icon: "none"
        });
      },
      fail: function (res) {
        wx.showToast({
          title: '分享失败',
          icon: "none"
        })
      }
    }
  },
  onShareTimeline: function () { //分享朋友圈
    return {
      title: '51大师兄 - 企服集市',
      query: '/subPackag/pages/consult_jump/EnterprisePiece/market/market',
      imageUrl: '',
      success: function (res) {
        wx.showToast({
          title: '分享成功',
          icon: "none"
        });
      },
      fail: function (res) {
        wx.showToast({
          title: '分享失败',
          icon: "none"
        })
      }
    }
  },
})

 三、wxml:

<van-sticky style="padding-top: 32rpx;">
  <!-- 搜索框 -->
  <view class="box" style="padding-top: 22rpx;">
    <navigator url="/subPackag/pages/consult_jump/search/search" hover-class="none">
      <view class="search-header">
        <image class="search-icon" src="https://wx.applet.style.51dsx.cn/img/search_icon_search@2x.png" mode="widthFix"></image>
        <input disabled="true" type="text" confirm-type="search" class="search-input" placeholder="产品标题、分类" />
      </view>
    </navigator>
  </view>
  <!-- Tab标签页切换 -->
  <scroll-view scroll-x="true" class="nav" scroll-left="{{navScrollLeft}}" scroll-with-animation="{{true}}" enhanced show-scrollbar>
    <block wx:for="{{navData}}" wx:for-index="idx" wx:for-item="navItem" wx:key="idx">
      <view class="nav-item {{currentTab == idx ?'active':''}}" data-current="{{idx}}" bindtap="switchNav">
        <text>{{navItem}}</text>
      </view>
    </block>
  </scroll-view>
  <!-- 地区下拉分类菜单 -->
  <view class="area-box">
    <van-dropdown-menu>
      <van-dropdown-item id="item" title="{{itemTitle}}">
        <van-tree-select items="{{ items }}" main-active-index="{{ mainActiveIndex }}" active-id="{{ activeId }}" bind:click-nav="onClickNav" bind:click-item="onClickItem" />
      </van-dropdown-item>
    </van-dropdown-menu>
  </view>
</van-sticky>
<!-- 页面内容 -->
<swiper class="tab-box" current="{{currentTab}}" duration="300" bindchange="switchTab">
  <swiper-item wx:for="{{[0,1,2,3,4,5,6]}}" wx:for-item="{{item}}" wx:for-index="idx" wx:key="idx" class="tab-content" skip-hidden-item-layout="true">
    <scroll-view scroll-y="true" bindscrolltolower="onReachBottom" scroll-top="{{top}}">
      <view class="tabulation" wx:if="{{ProductList.length>0}}">
        <view class="product-item {{item.weigh>1?'arrange':''}}" wx:for="{{ProductList}}" wx:key="item" data-id="{{item.id}}" bindtap="goDetails">
          <view class="insideBox">
            <image class="img" src="{{item.proCover}}" mode="aspectFill" />
            <view class="product-content">
              <view class="tetle">{{item.proName}}</view>
              <view style="display: flex;">
                <view class="tag tag1" wx:if="{{item.proTags[0]}}">{{item.proTags[0]}}</view>
                <view class="tag tag2" wx:if="{{item.proTags[1]}}">{{item.proTags[1]}}</view>
              </view>
              <view class="price"> {{item.payType == 2 ? "面议" : '¥'+item.proPrice}}</view>
            </view>
          </view>
        </view>
      </view>
      <view wx:else class="custom-image">
        <van-empty class="custom-image" image="https://wx.applet.style.51dsx.cn/img/dsx_image_default.png" description="未找到相关的内容" />
      </view>
    </scroll-view>
  </swiper-item>
</swiper>

 四、wxss:

page {
  width: 100%;
  height: 100%;
  background: transparent;
}

.box {
  padding: 0 28rpx;
  background-color: #F9F9F9;
}

.search-header {
  margin: 0rpx 10rpx 0 0;
  border-radius: 30rpx;
  display: inline-block;
  display: flex;
  align-items: center;
  width: 100%;
  height: 68rpx;
  border-radius: 80rpx;
  opacity: 1;
  border: 1px solid rgba(0, 0, 0, 0.3);
}

.search-icon {
  height: auto;
  display: inline-block;
  width: 40rpx;
  margin-left: 25rpx;
  margin-right: 10rpx;
  background-size: 60rpx;
}

.search-icon2 {
  display: inline-block;
  width: 40rpx;
  height: 40rpx;
  margin-left: 20rpx;
  margin-right: 20rpx;
  background-size: 60rpx;
}

.search-input {
  line-height: 60rpx;
  width: 100%;
  display: inline-block;
}

.area-box {
  background: #F9F9F9;
  width: 100%;
  padding-left: 32rpx;
  height: 84rpx;
}

.area-box .van-dropdown-menu {
  box-shadow: none;
  display: inline-block;
  padding: 12rpx 30rpx 12rpx 24rpx;
  background: #F1F1F1;
  line-height: 36rpx;
  border-radius: 30rpx;
  height: auto;
}

.area-box .van-dropdown-menu .van-ellipsis {
  font-size: 24rpx !important;
  color: #676767;
}

.area-box .van-dropdown-menu .van-dropdown-menu__title {
  padding: 0 16rpx 0 0;
}

.tab-box .tabulation {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}

.tab-box {
  padding: 0 24rpx;
  background: #F9F9F9;
  height: calc(100vh - 255rpx);
}

.tab-box scroll-view {
  height: 100% !important;
}

.tab-box .product-item {
  width: 340rpx;
  background-image: linear-gradient(141deg, rgba(255, 241, 190, 1), rgba(255, 187, 84, 1));
  border-radius: 16rpx;
  margin-bottom: 20rpx;
}

.tab-box .arrange {
  width: 338rpx !important;
  padding: 2rpx;
}

.tab-box .insideBox {
  width: 100%;
  background: #fff;
  border-radius: 16rpx;
}

.tab-box .product-item .img {
  width: 100%;
  height: 340rpx;
  border-radius: 16rpx 16rpx 0rpx 0rpx;
}

.tab-box .product-item .product-content {
  padding: 16rpx;
}

.tab-box .product-item .product-content .tetle {
  min-height: 80rpx;
  font-size: 30rpx;
  font-weight: 500;
  color: #333333;
  line-height: 40rpx;
  margin-bottom: 12rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.tab-box .product-item .product-content .tag {
  display: inline-block;
  padding: 2rpx 12rpx;
  margin-right: 8rpx;
  font-size: 24rpx;
  font-weight: 400;
  line-height: 32rpx;
  margin-bottom: 20rpx;
}

.tab-box .product-item .product-content .tag1 {
  background: #FFE9E7;
  border-radius: 4rpx 4rpx 4rpx 4rpx;
  color: #ED3329;
}

.tab-box .product-item .product-content .tag2 {
  background: #FFEFD7;
  border-radius: 4rpx 4rpx 4rpx 4rpx;
  opacity: 1;
  color: #EE922D;
}

.tab-box .product-item .product-content .price {
  font-size: 36rpx;
  font-family: Avenir-Medium, Avenir;
  font-weight: 500;
  color: #EF3822;
  line-height: 40rpx;
}

.nav {
  height: 80rpx;
  padding: 0 32rpx;
  box-sizing: border-box;
  overflow: hidden;
  line-height: 80rpx;
  background: #F9F9F9;
  font-size: 16px;
  white-space: nowrap;
  display: flex;
  justify-content: space-around;
  z-index: 99;
}

.nav-item {
  font-size: 30rpx;
  font-weight: 400;
  color: #676767;
  line-height: 40rpx;
  margin: 0 20rpx;
  display: inline-block;
  text-align: center;
}

.nav-item:first-child {
  margin-left: 0;
}

.nav-item:last-child {
  margin-right: 0;
}

.nav-item.active {
  color: #000;
  font-weight: 600;
}

.nav-item.active:after {
  content: "";
  display: block;
  margin: -10rpx auto 0;
  width: 100%;
  height: 8rpx;
  background: linear-gradient(138deg, #4787FF 0%, #ADCEFF 100%);
  opacity: 0.4;
}

.tab-content {
  overflow-y: scroll;
}

.custom-image {
  margin-top: 10vh !important;
}

::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
  color: transparent;
}

::-ms-scrollbar {
  display: none;
  width: 0;
  height: 0;
  color: transparent;
}

::-moz-scrollbar {
  display: none;
  width: 0;
  height: 0;
  color: transparent;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D_evin_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值