| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- <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'>
- <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_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,
- getCurrentInstance
- } from 'vue';
- import {
- onLoad,
- onShow
- } from '@dcloudio/uni-app';
- import {
- productCategory
- } from '@/api/merchant.js';
- const instance = getCurrentInstance();
- 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)
- })
- let listArr = newArr.filter(item => item.code !== 'bb_mall')
- productList.value = listArr.sort((a, b) => a.sort - b.sort);
- // 使用 nextTick 确保 DOM 已更新
- // nextTick(() => {
- // setTimeout(() => {
- // infoScroll();
- // }, 500);
- // });
- } catch (error) {
- console.error('获取分类列表失败:', error);
- uni.showToast({
- title: '加载分类失败'
- });
- }
- };
- // 计算滚动相关数据
- const infoScroll = () => {
- nextTick(() => {
- setTimeout(() => {
- const len = productList.value.length;
- // 创建查询对象,并指定在当前组件实例中查询
- const query = uni.createSelectorQuery().in(instance);
- // 先查询所有元素
- query.selectAll('.listw').boundingClientRect((rects) => {
- if (rects) {
- hightArr.value = rects.map(rect => rect.top);
- console.log('hightArr:', hightArr.value);
- }
- }).exec();
- }, 500);
- });
- };
- // 点击左侧导航
- 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();
- // // 设置商品列表高度
- uni.getSystemInfo({
- success: (res) => {
- height.value = (res.windowHeight) * (750 / res.windowWidth) - (88 + 30 + 30);
- },
- });
- });
- defineExpose({
- infoScroll
- })
- </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>
|