|
@@ -1,15 +1,31 @@
|
|
|
<template>
|
|
|
<view class="content">
|
|
|
<scroll-view scroll-y class="left-aside">
|
|
|
- <view v-for="item in flist" :key="item.id" class="f-item b-b" :class="{ active: item.id === currentId }" @click="tabtap(item)">{{ item.cate_name }}</view>
|
|
|
+ <view v-for="(item,ind) in flist" :key="item.id" class="f-item b-b" :class="{ active:ind === index }"
|
|
|
+ @click="tabtap(item,ind)">{{ item.cate_name }}</view>
|
|
|
</scroll-view>
|
|
|
- <scroll-view scroll-with-animation scroll-y class="right-aside" @scroll="asideScroll" :scroll-top="tabScrollTop">
|
|
|
- <view v-for="item in flist" :key="item.id" class="s-list" :id="'main-' + item.id">
|
|
|
- <text class="s-item">{{ item.cate_name }}</text>
|
|
|
- <view class="t-list ">
|
|
|
- <view @click="navToList(item.id, titem.id)" class="t-item" v-for="titem in item.children" :key="titem.id">
|
|
|
- <image :src="titem.pic"></image>
|
|
|
- <text>{{ titem.cate_name }}</text>
|
|
|
+ <scroll-view scroll-with-animation scroll-y class="right-aside" @scroll="asideScroll"
|
|
|
+ :scroll-top="tabScrollTop">
|
|
|
+ <view class="list-box-h">
|
|
|
+ <view v-if="flist[index]" v-for="(item, index) in flist[index].list" :key="index" class="guess-item" @click="navToDetailPage(item)">
|
|
|
+ <image class="itemImg" :src="item.image"></image>
|
|
|
+ <view class="guess-box">
|
|
|
+ <view class="title clamp2">{{ item.store_name }}</view>
|
|
|
+ <!-- <view class="price-box flex">
|
|
|
+ <view class="yuanprice">{{ item.ot_price }}</view>
|
|
|
+ <image src="../../static/img/jiantou.png" mode=""></image>
|
|
|
+ <view class="jiang">直降{{ (item.ot_price - item.price).toFixed(2) }}元</view>
|
|
|
+ </view> -->
|
|
|
+ <view class="price">¥{{ item.price }}</view>
|
|
|
+ <view class="btn">立即购买</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="noData" v-if="flist[index]?flist[index].list.length==0:true">
|
|
|
+ <view v-if="flist[index].loading">
|
|
|
+ 暂无数据
|
|
|
+ </view>
|
|
|
+ <view v-else>
|
|
|
+ 数据加载中...
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
@@ -18,199 +34,194 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { getCategoryList } from '@/api/product.js';
|
|
|
-export default {
|
|
|
- data() {
|
|
|
- return {
|
|
|
- sizeCalcState: false,
|
|
|
- tabScrollTop: 0,
|
|
|
- currentId: 9,
|
|
|
- flist: [],
|
|
|
- };
|
|
|
- },
|
|
|
- onLoad() {
|
|
|
- this.loadData();
|
|
|
- },
|
|
|
- // 监听导航栏输入框点击事件
|
|
|
- onNavigationBarSearchInputClicked(e) {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages/product/search'
|
|
|
- });
|
|
|
- },
|
|
|
- methods: {
|
|
|
- // 载入数据
|
|
|
- async loadData() {
|
|
|
- let obj = this;
|
|
|
- getCategoryList({})
|
|
|
- .then(({ data }) => {
|
|
|
- obj.flist = data.map(function(s) {
|
|
|
- return s;
|
|
|
- });
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.log(err);
|
|
|
- });
|
|
|
- },
|
|
|
- //一级分类点击
|
|
|
- tabtap(item) {
|
|
|
- console.log(item);
|
|
|
- // 判断有没有初始化页面高度对象数据
|
|
|
- if (!this.sizeCalcState) {
|
|
|
- this.calcSize();
|
|
|
- }
|
|
|
- // 获取当前点击的id
|
|
|
- this.currentId = item.id;
|
|
|
- console.log(item.top);
|
|
|
- this.tabScrollTop = item.top;
|
|
|
- console.log(this.tabScrollTop);
|
|
|
- },
|
|
|
- //右侧栏滚动
|
|
|
- asideScroll(e) {
|
|
|
- // 判断有没有初始化页面高度对象数据
|
|
|
- if (!this.sizeCalcState) {
|
|
|
- this.calcSize();
|
|
|
- }
|
|
|
- let scrollTop = e.detail.scrollTop;
|
|
|
- let box = 0; //列表包裹框高度初始化
|
|
|
- let bottom = 10; //距离页面底部多少像素左侧列表切换到最后一个一级分类
|
|
|
- // 查询当前页面对象
|
|
|
- let view = uni.createSelectorQuery().select('.content');
|
|
|
- view.fields(
|
|
|
- {
|
|
|
- id: true,
|
|
|
- dataset: true,
|
|
|
- rect: true,
|
|
|
- size: true,
|
|
|
- scrollOffset: true
|
|
|
- },
|
|
|
- function(e) {
|
|
|
- // 保存包裹框高度
|
|
|
- box = e.height;
|
|
|
- }
|
|
|
- ).exec();
|
|
|
- // 获取所有距离顶部大于滚轮距离页面高度的所有分类
|
|
|
- let tabs = this.flist.filter(item =>( item.top-10) <= scrollTop).reverse();
|
|
|
- if (tabs.length > 0) {
|
|
|
- // 判断是否已经到达滚轮底部
|
|
|
- if (box + scrollTop + bottom >= e.detail.scrollHeight) {
|
|
|
- this.currentId = this.flist[this.flist.length - 1].id;
|
|
|
- } else {
|
|
|
- this.currentId = tabs[0].id;
|
|
|
- }
|
|
|
- }
|
|
|
+ import {
|
|
|
+ getCategoryList,
|
|
|
+ getProducts
|
|
|
+ } from '@/api/product.js';
|
|
|
+ export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ sizeCalcState: false,
|
|
|
+ tabScrollTop: 0,
|
|
|
+ currentId: 9,
|
|
|
+ index: 0, //当前选中的对象
|
|
|
+ flist: [],
|
|
|
+ };
|
|
|
},
|
|
|
- //计算右侧栏每个tab的高度等信息
|
|
|
- calcSize() {
|
|
|
- let h = 0;
|
|
|
- this.flist.forEach(item => {
|
|
|
- let view = uni.createSelectorQuery().select('#main-' + item.id);
|
|
|
- view.fields(
|
|
|
- {
|
|
|
- size: true
|
|
|
- },
|
|
|
- data => {
|
|
|
- item.top = h;
|
|
|
- h += data.height;
|
|
|
- item.bottom = h;
|
|
|
- }
|
|
|
- ).exec();
|
|
|
- });
|
|
|
- this.sizeCalcState = true;
|
|
|
+ onLoad() {
|
|
|
+ this.loadData();
|
|
|
},
|
|
|
- navToList(sid, tid) {
|
|
|
- // 点击导航跳转到详细页面
|
|
|
+ // 监听导航栏输入框点击事件
|
|
|
+ onNavigationBarSearchInputClicked(e) {
|
|
|
uni.navigateTo({
|
|
|
- url: '/pages/product/list?fid='+this.currentId+'&sid='+sid+'&tid='+tid
|
|
|
+ url: '/pages/product/search'
|
|
|
});
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 载入数据
|
|
|
+ async loadData() {
|
|
|
+ let obj = this;
|
|
|
+ getCategoryList({
|
|
|
+ sid: 10
|
|
|
+ })
|
|
|
+ .then(({
|
|
|
+ data
|
|
|
+ }) => {
|
|
|
+ obj.flist = data[0].children.map((e) => {
|
|
|
+ let data = {
|
|
|
+ id: e.id,
|
|
|
+ pic: e.pic,
|
|
|
+ cate_name: e.cate_name,
|
|
|
+ loading: false,
|
|
|
+ list: [],
|
|
|
+ }
|
|
|
+ return data
|
|
|
+ });
|
|
|
+ obj.currentId = obj.flist[0].id;
|
|
|
+ obj.loadProducts(obj.flist[0])
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ console.log(err);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //一级分类点击
|
|
|
+ tabtap(item, ind) {
|
|
|
+ this.index = ind;
|
|
|
+ if (!item.loading) {
|
|
|
+ this.loadProducts(item)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //加载商品 ,带下拉刷新和上滑加载
|
|
|
+ loadProducts(item) {
|
|
|
+ let obj = this;
|
|
|
+ let data = {
|
|
|
+ page: 1,
|
|
|
+ limit: 1000,
|
|
|
+ sid: item.id //分类id
|
|
|
+ };
|
|
|
+ getProducts(data).then(function(e) {
|
|
|
+ console.log(e.data);
|
|
|
+ item.list = e.data;
|
|
|
+ item.loading = true;
|
|
|
+ }).catch((e) => {
|
|
|
+ item.loading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ navToDetailPage(item) {
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/pages/product/product?id=' + item.id
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
-};
|
|
|
+ };
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
-page,
|
|
|
-.content {
|
|
|
- height: 100%;
|
|
|
- background-color: #f8f8f8;
|
|
|
-}
|
|
|
+ page,
|
|
|
+ .content {
|
|
|
+ height: 100%;
|
|
|
+ background-color: #f8f8f8;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
|
|
|
-.content {
|
|
|
- display: flex;
|
|
|
-}
|
|
|
-.left-aside {
|
|
|
- flex-shrink: 0;
|
|
|
- width: 200rpx;
|
|
|
- height: 100%;
|
|
|
- background-color: #fff;
|
|
|
-}
|
|
|
-.f-item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- width: 100%;
|
|
|
- height: 100rpx;
|
|
|
- font-size: 28rpx;
|
|
|
- color: $font-color-base;
|
|
|
- position: relative;
|
|
|
- &.active {
|
|
|
- color: $base-color;
|
|
|
- background: #f8f8f8;
|
|
|
- &:before {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- top: 50%;
|
|
|
- transform: translateY(-50%);
|
|
|
- height: 36rpx;
|
|
|
- width: 8rpx;
|
|
|
- background-color: $base-color;
|
|
|
- border-radius: 0 4px 4px 0;
|
|
|
- opacity: 0.8;
|
|
|
+ .left-aside {
|
|
|
+ flex-shrink: 0;
|
|
|
+ width: 200rpx;
|
|
|
+ height: 100%;
|
|
|
+ background-color: #fff;
|
|
|
+
|
|
|
+ .f-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 100rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: $font-color-base;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ color: $base-color;
|
|
|
+ background: #f8f8f8;
|
|
|
+
|
|
|
+ &:before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ height: 36rpx;
|
|
|
+ width: 8rpx;
|
|
|
+ background-color: $base-color;
|
|
|
+ border-radius: 0 4px 4px 0;
|
|
|
+ opacity: 0.8;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-.right-aside {
|
|
|
- flex: 1;
|
|
|
- overflow: hidden;
|
|
|
- padding-left: 20rpx;
|
|
|
- padding-right: 20rpx;
|
|
|
-}
|
|
|
-.s-item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- height: 70rpx;
|
|
|
- padding-top: 8rpx;
|
|
|
- font-size: 28rpx;
|
|
|
- color: $font-color-dark;
|
|
|
-}
|
|
|
-.t-list {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- border-radius: 15rpx;
|
|
|
- width: 100%;
|
|
|
- background: #fff;
|
|
|
- padding-top: 12rpx;
|
|
|
- &:after {
|
|
|
- content: '';
|
|
|
- flex: 99;
|
|
|
- height: 0;
|
|
|
+ .right-aside {
|
|
|
+ flex: 1;
|
|
|
+ overflow: hidden;
|
|
|
+ padding-left: 20rpx;
|
|
|
+ padding-right: 20rpx;
|
|
|
+ padding-top: 20rpx;
|
|
|
+ .noData{
|
|
|
+ color: #a3a3a3;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
-.t-item {
|
|
|
- flex-shrink: 0;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- flex-direction: column;
|
|
|
- width: 171rpx;
|
|
|
- font-size: 26rpx;
|
|
|
- color: #666;
|
|
|
- padding-bottom: 20rpx;
|
|
|
|
|
|
- image {
|
|
|
- width: 140rpx;
|
|
|
- height: 140rpx;
|
|
|
+ .guess-item {
|
|
|
+ padding: 10rpx;
|
|
|
+ display: flex;
|
|
|
+ min-width: 100%;
|
|
|
+ width: 0;
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 10rpx;
|
|
|
+ box-shadow: 0px 0px 20rpx 0px rgba(50, 50, 52, 0.06);
|
|
|
+ image {
|
|
|
+ width: 200rpx;
|
|
|
+ height: 200rpx;
|
|
|
+ border-radius: 10rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+ .guess-box {
|
|
|
+ width: 100%;
|
|
|
+ padding: 5px;
|
|
|
+ .title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #333333;
|
|
|
+ height: 2.5em;
|
|
|
+ line-height: 1.25em;
|
|
|
+ }
|
|
|
+ .price-box {
|
|
|
+ margin-top: 80rpx;
|
|
|
+ justify-content: flex-start;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-family: PingFang SC;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #FF6F0F;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ background: #16cc9f;
|
|
|
+ border-radius: 28rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #ffffff;
|
|
|
+ float: right;
|
|
|
+ padding: 5rpx 20rpx;
|
|
|
+ margin-top: 20rpx;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
</style>
|