| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- <template>
- <view class='productSort'>
- <view class='aside' :style="{bottom: tabbarH + 'px',height: height + 'rpx'}">
- <scroll-view scroll-y="true" scroll-with-animation='true' style="height: 100%;">
- <view class='item acea-row row-center-wrapper'
- :class='index==navActive?"on":""'
- v-for="(item,index) in productList"
- :key="index"
- @click='tap(index,"b"+index)'>
- <text>{{item.name}}</text>
- </view>
- </scroll-view>
- </view>
- <view class='conter'>
- <scroll-view scroll-y="true"
- :scroll-into-view="toView"
- :style='"height:"+height+"rpx;"'
- @scroll="scroll"
- scroll-with-animation='true'>
- <view v-for="(item,index) in productList" :key="index">
- <view class='listw' :id="'b'+index">
- <view class='title acea-row row-center-wrapper'>
- <view class='line'></view>
- <view class='name'>{{item.name}}</view>
- <view class='line'></view>
- </view>
- <view class='list acea-row'>
- <view v-for="(itemn,indexn) in item.child" :key="indexn">
- <navigator hover-class='none'
- :url='"/pages/goods/goods_search/index?cid="+itemn.id+"&title="+itemn.name+"&merchantId="+props.merchantId'
- class='item acea-row row-column row-middle'>
- <view class='name line1'>{{itemn.name}}</view>
- </navigator>
- </view>
- </view>
- </view>
- </view>
- <view :style='"height:"+(height-300)+"rpx;"' v-if="number<15"></view>
- </scroll-view>
- </view>
- </view>
- </template>
- <script setup>
- import { ref, onMounted, nextTick,watch} from 'vue';
- import { onLoad, onShow } from '@dcloudio/uni-app';
- import { productCategory } from '@/api/merchant.js';
- const props = defineProps({
- merchantId: {
- type: [String, Number],
- required: true
- }
- });
- // 响应式数据
- const productList = ref([]);
- const navActive = ref(0);
- const number = ref("");
- const height = ref(0);
- const hightArr = ref([]);
- const toView = ref("");
- const tabbarH = ref(0);
- // 获取分类列表
- const getAllCategory = async () => {
- console.log('============')
- console.log(props.merchantId)
- try {
- let obj = {
- type: 1,
- status: -1
- }
- const { data }= await productCategory(obj);
- const newArr = []
- data.forEach((value, index) => {
- newArr[index] = value
- if (value.child) newArr[index].child = value.child.filter(item => item.status === true)
- })
- productList.value = newArr.filter(item => item.code !== 'bb_mall')
- // 使用 nextTick 确保 DOM 已更新
- nextTick(() => {
- setTimeout(() => {
- infoScroll();
- }, 500);
- });
- } catch (error) {
- console.error('获取分类列表失败:', error);
- uni.showToast({ title: '加载分类失败' });
- }
- };
- // 计算滚动相关数据
- const infoScroll = () => {
- let len = productList.value.length;
- let child = productList.value[len - 1] && productList.value[len - 1].child
- ? productList.value[len - 1].child
- : [];
- number.value = child ? child.length : 0;
- // 设置商品列表高度
- uni.getSystemInfo({
- success: (res) => {
- height.value = (res.windowHeight) * (750 / res.windowWidth) - 98;
- },
- });
- let heightTemp = 0;
- let hightArrTemp = [];
- for (let i = 0; i < len; i++) {
- // 获取元素所在位置
- let query = uni.createSelectorQuery();
- let idView = "#b" + i;
- query.select(idView).boundingClientRect();
- query.exec((res) => {
- if (res && res[0]) {
- let top = res[0].top;
- hightArrTemp.push(top);
- hightArr.value = hightArrTemp;
- }
- });
- }
- };
- // 点击左侧导航
- const tap = (index, id) => {
- toView.value = id;
- navActive.value = index;
- };
- // 右侧滚动事件
- const scroll = (e) => {
- let scrollTop = e.detail.scrollTop;
- let scrollArr = hightArr.value;
- if (!scrollArr || scrollArr.length === 0) return;
- for (let i = 0; i < scrollArr.length; i++) {
- if (scrollTop >= 0 && scrollTop < scrollArr[1] - scrollArr[0]) {
- navActive.value = 0;
- } else if (scrollTop >= scrollArr[i] - scrollArr[0] && scrollTop < scrollArr[i + 1] - scrollArr[0]) {
- navActive.value = i;
- } else if (scrollTop >= scrollArr[scrollArr.length - 1] - scrollArr[0]) {
- navActive.value = scrollArr.length - 1;
- }
- }
- };
- // 监听 merchantId 变化
- watch(() => props.merchantId, (newVal) => {
- console.log('merchantId 变化了:', newVal);
- if (newVal) {
- getAllCategory();
- }
- }, { immediate: true }); // 立即执行一次
- // 页面加载
- onLoad(() => {
- });
- // 页面显示
- onShow(() => {
- getAllCategory();
- });
- </script>
- <style scoped lang="scss">
- .productSort .aside {
- position: absolute;
- width: 180rpx;
- left: 0;
- top:0;
- background-color: #fff;
- overflow-y: scroll;
- overflow-x: hidden;
- height: auto;
- border-radius: 16rpx;
- }
- .productSort .aside .item {
- height: 100rpx;
- width: 100%;
- font-size: 26rpx;
- color: #424242;
- }
- .productSort .aside .item.on {
- background-color: #fff;
- border-left: 6rpx solid #F8C008;
- width: 100%;
- text-align: center;
- color: #F8C008;
- font-weight: bold;
- }
- .productSort .conter {
- margin: 0rpx 0 0 200rpx;
- padding: 0 14rpx;
- background-color: #fff;
- border-radius: 16rpx;
- }
- .productSort .conter .listw {
- padding-top: 20rpx;
- }
- .productSort .conter .listw .title {
- height: 90rpx;
- }
- .productSort .conter .listw .title .line {
- width: 100rpx;
- height: 2rpx;
- background-color: #f0f0f0;
- }
- .productSort .conter .listw .title .name {
- font-size: 28rpx;
- color: #333;
- margin: 0 30rpx;
- font-weight: bold;
- }
- .productSort .conter .list {
- flex-wrap: wrap;
- }
- .productSort .conter .list .item {
- width: 177rpx;
- margin-top: 26rpx;
- }
- .productSort .conter .list .item .picture {
- width: 120rpx;
- height: 120rpx;
- border-radius: 50%;
- }
- .productSort .conter .list .item .picture image {
- width: 100%;
- height: 100%;
- border-radius: 50%;
- div{
- background-color: #f7f7f7;
- }
- }
- .productSort .conter .list .item .name {
- font-size: 24rpx;
- color: #333;
- height: 56rpx;
- line-height: 56rpx;
- width: 120rpx;
- text-align: center;
- }
- </style>
|