Files
frontend-app/pages/sort/sort.vue
T
2025-08-06 22:24:53 +08:00

343 lines
8.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="sort_warp">
<view class="sort_header">
<!-- 分类切换 -->
<view class="sort_category_header">
<view :class="selCategory === 1 ? 'category_item category_item_sel' : 'category_item'" @click="checkCategory(1)">
<view>分类</view>
<view v-if="selCategory === 1" class="category_item_sel_but"></view>
</view>
<!-- <view :class="selCategory === 2 ? 'category_item category_item_sel':'category_item'" @click="checkCategory(2)">
<view>品牌</view>
<view v-if="selCategory === 2" class="category_item_sel_but"></view>
</view> -->
</view>
<!-- 搜索 -->
<view style="width: 200rpx;" @click="jumpSearch">
<up-search shape="square" bgColor="#EEEEEEFF" color="#666666FF" :showAction="false"
placeholder="搜索"></up-search>
</view>
</view>
<view class="u-menu-wrap">
<!-- 左侧类别 -->
<scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop">
<view v-for="(item, index) in tabbarList" :key="index" class="u-tab-item"
:class="[current == index ? 'u-tab-item-active' : '']" :data-current="index" @tap.stop="swichMenu(item, index)">
<text class="u-line-1">{{ item.name }}</text>
</view>
</scroll-view>
<!-- 商品类别数据 -->
<scroll-view scroll-y class="right-box">
<!-- banner图 -->
<view style="padding: 0rpx 20rpx;">
<up-swiper :list="bannerList" height="80px"></up-swiper>
</view>
<view class="page-view">
<!-- 这里还有一层循环 -->
<up-loading-page :loading="tabbarContentLoading"></up-loading-page>
<view class="class-item" v-for="(item, index) in tabbarContentList" :key="index">
<view class="item-title">
<text>{{ item.name }}</text>
</view>
<view class="item-container" v-if="item.foods && item.foods.length !== 0">
<view class="thumb-box" v-for="(item1, index1) in item.foods" :key="index1" @click="jumpSearch(item1)">
<image class="item-menu-image" :src="item1.icon ? item1.icon : '/static/common/def_img.jpg'" mode="">
</image>
<view class="item-menu-name">{{ item1.name }}</view>
</view>
</view>
<view v-else class="not_order_warp">
<view class="not_order_warp_img"><up-image
src="https://cex-pub.s3.ap-southeast-1.amazonaws.com/static/not_shopping.png" width="100" height="100"
bgColor="#f1f6ff00"></up-image></view>
<view class="not_order_msg_warp">暂无分类,快去添加吧~</view>
</view>
</view>
</view>
</scroll-view>
</view>
<CustomTabBar :tabIndex="1" />
</view>
</template>
<script>
import { getCascadeCategory, getCarouselImage } from '@/api/common.js';
import CustomTabBar from '@/components/custom-tab-bar.vue';
import { APP_PAGE_TYPE } from '@/utils/enumUtils.js'
export default {
components: { CustomTabBar },
data() {
return {
selCategory: 1,
scrollTop: 0, //tab标题的滚动条位置
current: null, // 预设当前项的值
menuHeight: 0, // 左边菜单的高度
menuItemHeight: 0, // 左边菜单item的高度
bannerList: [],
tabbarList: [],// 左侧的主分类
tabbarContentList: [],// 右侧内容的分类
tabbarContentLoading: false,
}
},
onShow() {
/*#ifdef APP-PLUS*/
uni.hideTabBar({
animation: false
})
/*#endif*/
const then = this;
this.getSort(0).then(resp => {
if (resp && resp.length !== 0) {
this.tabbarList = resp;
const sortId = uni.getStorageSync('sortId');
// 如果有默认的参数就默认选中参数
if (sortId && sortId !== 0) {
let fData = {};
let currentIndex = 0;
resp.map((item, index) => {
if (item.id === sortId) {
fData = item;
currentIndex = index;
return;
}
})
this.swichMenu(fData, currentIndex);
} else {
const fData = resp[0];
// 否则就选中第一个
this.swichMenu(fData, 0);
}
}
});
this.getCarouselImage();
},
methods: {
checkCategory(val) {
this.selCategory = val;
},
// 查询轮播图
async getCarouselImage() {
const params = {
pageUi: APP_PAGE_TYPE.SORT,
}
const resp = await getCarouselImage(params);
if (resp && resp.bizcode === 100) {
const data = resp.data || [];
this.bannerList = data.length !== 0 ? data.map(obj => obj.carouselImage) : [];
}
},
jumpSearch(item) {
let path = "/pages/other_package/search/search";
if (item && Object.keys(item).length !== 0) {
path = path + "?keyword=" + item.name;
}
uni.navigateTo({
url: path,
})
},
// 查询分类
async getSort(pId) {
const params = {
parentId: pId,
}
const resp = await getCascadeCategory(params);
if (resp && resp.bizcode === 100) {
return resp.data;
}
return [];
},
getImg() {
return Math.floor(Math.random() * 35);
},
// 点击左边的栏目切换
async swichMenu(item, index) {
if (index == this.current) return;
this.tabbarContentLoading = true;
const firstData = await this.getSort(item.id);
for (let fItem of firstData) {
const twoData = await this.getSort(fItem.id);
fItem.foods = twoData;
}
this.tabbarContentList = firstData;
this.current = index;
// 如果为0,意味着尚未初始化
if (this.menuHeight == 0 || this.menuItemHeight == 0) {
await this.getElRect('menu-scroll-view', 'menuHeight');
await this.getElRect('u-tab-item', 'menuItemHeight');
}
// 将菜单菜单活动item垂直居中
this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
this.tabbarContentLoading = false;
},
// 获取一个目标元素的高度
getElRect(elClass, dataVal) {
new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(this);
query.select('.' + elClass).fields({ size: true }, res => {
// 如果节点尚未生成,res值为null,循环调用执行
if (!res) {
setTimeout(() => {
this.getElRect(elClass);
}, 10);
return;
}
this[dataVal] = res.height;
}).exec();
})
},
},
}
</script>
<style lang="scss" scoped>
.sort_warp {
padding: 130rpx 0rpx 0rpx;
height: calc(100vh - 270rpx); // 130 上边的导航栏,140下边的导航栏
}
.sort_header {
display: flex;
justify-content: space-between;
padding: 0 30rpx;
.sort_category_header {
display: flex;
align-items: center;
}
.category_item {
width: 140rpx;
font-weight: bold;
font-size: 36rpx;
color: #999999;
}
.category_item_sel {
font-size: 44rpx;
color: #1A1A1A;
}
.category_item_sel_but {
height: 8rpx;
width: 50rpx;
background: $app-bt-bj;
margin-top: 4rpx;
margin-left: 12%;
border-radius: 20rpx;
}
}
.sort_content {}
.u-menu-wrap {
flex: 1;
display: flex;
overflow: hidden;
margin-top: 20rpx;
height: calc(100vh - 356rpx);
}
.u-search-inner {
background-color: rgb(234, 234, 234);
border-radius: 100rpx;
display: flex;
align-items: center;
padding: 10rpx 16rpx;
}
.u-search-text {
font-size: 26rpx;
color: $u-tips-color;
margin-left: 10rpx;
}
.u-tab-view {
width: 200rpx;
height: 100%;
background: #f6f6f6;
}
.u-tab-item {
height: 110rpx;
// background: #f6f6f6;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #444;
font-weight: 400;
line-height: 1;
}
.u-tab-item-active {
position: relative;
color: #000;
font-size: 30rpx;
font-weight: 600;
background: #fff;
}
.u-tab-item-active::before {
content: "";
position: absolute;
border-left: 4px solid $app-bt-bj;
height: 32rpx;
left: 0;
top: 39rpx;
}
.u-tab-view {
height: 100%;
}
.right-box {
background-color: rgb(250, 250, 250);
}
.page-view {
padding: 16rpx;
}
.class-item {
margin-bottom: 30rpx;
background-color: #fff;
padding: 16rpx;
border-radius: 8rpx;
}
.item-title {
font-size: 26rpx;
color: $u-main-color;
font-weight: bold;
}
.item-menu-name {
font-weight: normal;
font-size: 24rpx;
color: $u-main-color;
margin-top: 10rpx;
}
.item-container {
display: flex;
flex-wrap: wrap;
}
.thumb-box {
width: 33.333333%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-top: 20rpx;
}
.item-menu-image {
width: 110rpx;
height: 110rpx;
}
</style>