zhangyaowen 4 luni în urmă
părinte
comite
870ff8d002
3 a modificat fișierele cu 250 adăugiri și 272 ștergeri
  1. 167 191
      pages/index/category.vue
  2. 34 34
      pages/index/components/first-two.vue
  3. 49 47
      pages/index/components/second-one.vue

+ 167 - 191
pages/index/category.vue

@@ -5,50 +5,28 @@
       <view :style="[{ height: pageHeight + 'px' }]" class="three-level-wrap ss-flex ss-col-top">
         <!-- 产品大纲(左) -->
         <scroll-view :style="[{ height: pageHeight + 'px' }]" class="side-menu-wrap" scroll-y>
-          <view
-            v-for="(item, index) in state.categoryList"
-            :key="item.id"
-            :class="[{ 'menu-item-active': index === state.activeMenu }]"
-            class="menu-item ss-flex"
-            @tap="onMenu(index)"
-          >
+          <view v-for="(item, index) in state.categoryList" :key="item.id"
+            :class="[{ 'menu-item-active': index === state.activeMenu }]" class="menu-item ss-flex"
+            @tap="onMenu(index)">
             <view class="menu-title ss-line-1">
               {{ item.name }}
             </view>
           </view>
         </scroll-view>
         <!-- 产品大纲(右) -->
-        <scroll-view
-          v-if="state.categoryList?.length"
-          :style="[{ height: pageHeight + 'px' }]"
-          class="goods-list-box"
-          scroll-y
-          @scrolltolower="handleScrollToLower"
-        >
-          <image
-            v-if="state.categoryList[state.activeMenu].picUrl"
-            :src="sheep.$url.cdn(state.categoryList[state.activeMenu].picUrl)"
-            class="banner-img"
-            mode="widthFix"
-          />
+        <scroll-view v-if="state.categoryList?.length" :style="[{ height: pageHeight + 'px' }]" class="goods-list-box"
+          scroll-y @scrolltolower="handleScrollToLower">
+          <image v-if="state.categoryList[state.activeMenu].picUrl"
+            :src="sheep.$url.cdn(state.categoryList[state.activeMenu].picUrl)" class="banner-img" mode="widthFix" />
           <first-one v-if="state.style === 'first_one'" :pagination="state.pagination" />
           <first-two v-if="state.style === 'first_two'" :pagination="state.pagination" />
-          <second-one
-            v-if="state.style === 'second_one'"
-            :activeMenu="state.activeMenu"
-            :data="state.categoryList"
-          />
-          <uni-load-more
-            v-if="
-              (state.style === 'first_one' || state.style === 'first_two') &&
-              state.pagination.total > 0
-            "
-            :content-text="{
-              contentdown: '点击查看更多',
-            }"
-            :status="state.loadStatus"
-            @tap="loadMore"
-          />
+          <second-one v-if="state.style === 'second_one'" :activeMenu="state.activeMenu" :data="state.categoryList" />
+          <uni-load-more v-if="
+            (state.style === 'first_one' || state.style === 'first_two') &&
+            state.pagination.total > 0
+          " :content-text="{
+            contentdown: '点击查看更多',
+          }" :status="state.loadStatus" @tap="loadMore" />
         </scroll-view>
       </view>
     </view>
@@ -56,183 +34,181 @@
 </template>
 
 <script setup>
-  import secondOne from './components/second-one.vue';
-  import firstOne from './components/first-one.vue';
-  import firstTwo from './components/first-two.vue';
-  import sheep from '@/sheep';
-  import CategoryApi from '@/sheep/api/product/category';
-  import SpuApi from '@/sheep/api/product/spu';
-  import { onLoad } from '@dcloudio/uni-app';
-  import { computed, reactive } from 'vue';
-  import _ from 'lodash-es';
-  import { handleTree } from '@/sheep/util';
-
-  const state = reactive({
-    style: 'second_one', // first_one(一级 - 样式一), first_two(二级 - 样式二), second_one(二级)
-    categoryList: [], // 产品大纲树
-    activeMenu: 0, // 选中的一级菜单,在 categoryList 的下标
-
-    pagination: {
-      // 产品分页
-      list: [], // 产品列表
-      total: [], // 产品总数
-      pageNo: 1,
-      pageSize: 6,
-    },
-    loadStatus: '',
-  });
-
-  const { safeArea } = sheep.$platform.device;
-  const pageHeight = computed(() => safeArea.height - 44 - 50);
-
-  // 加载产品大纲
-  async function getList() {
-    const { code, data } = await CategoryApi.getCategoryList();
-    if (code !== 0) {
-      return;
-    }
-    state.categoryList = handleTree(data);
-  }
-
-  // 选中菜单
-  const onMenu = (val) => {
-    state.activeMenu = val;
-    if (state.style === 'first_one' || state.style === 'first_two') {
-      state.pagination.pageNo = 1;
-      state.pagination.list = [];
-      state.pagination.total = 0;
-      getGoodsList();
-    }
-  };
-
-  // 加载产品列表
-  async function getGoodsList() {
-    // 加载列表
-    state.loadStatus = 'loading';
-    const res = await SpuApi.getSpuPage({
-      categoryId: state.categoryList[state.activeMenu].id,
-      pageNo: state.pagination.pageNo,
-      pageSize: state.pagination.pageSize,
-    });
-    if (res.code !== 0) {
-      return;
-    }
-    // 合并列表
-    state.pagination.list = _.concat(state.pagination.list, res.data.list);
-    state.pagination.total = res.data.total;
-    state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
+import secondOne from './components/second-one.vue';
+import firstOne from './components/first-one.vue';
+import firstTwo from './components/first-two.vue';
+import sheep from '@/sheep';
+import CategoryApi from '@/sheep/api/product/category';
+import SpuApi from '@/sheep/api/product/spu';
+import { onLoad } from '@dcloudio/uni-app';
+import { computed, reactive } from 'vue';
+import _ from 'lodash-es';
+import { handleTree } from '@/sheep/util';
+
+const state = reactive({
+  style: 'second_one', // first_one(一级 - 样式一), first_two(二级 - 样式二), second_one(二级)
+  categoryList: [], // 产品大纲树
+  activeMenu: 0, // 选中的一级菜单,在 categoryList 的下标
+
+  pagination: {
+    // 产品分页
+    list: [], // 产品列表
+    total: [], // 产品总数
+    pageNo: 1,
+    pageSize: 6,
+  },
+  loadStatus: '',
+});
+
+const { safeArea } = sheep.$platform.device;
+const pageHeight = computed(() => safeArea.height - 44 - 50);
+
+// 加载产品大纲
+async function getList() {
+  const { code, data } = await CategoryApi.getCategoryList();
+  if (code !== 0) {
+    return;
   }
-
-  // 加载更多产品
-  function loadMore() {
-    if (state.loadStatus === 'noMore') {
-      return;
-    }
-    state.pagination.pageNo++;
+  state.categoryList = handleTree(data);
+}
+
+// 选中菜单
+const onMenu = (val) => {
+  state.activeMenu = val;
+  if (state.style === 'first_one' || state.style === 'first_two') {
+    state.pagination.pageNo = 1;
+    state.pagination.list = [];
+    state.pagination.total = 0;
     getGoodsList();
   }
-
-  onLoad(async (params) => {
-    await getList();
-
-    // 首页点击分类的处理:查找满足条件的分类
-    const foundCategory = state.categoryList.find((category) => category.id === Number(params.id));
-    // 如果找到则调用 onMenu 自动勾选相应分类,否则调用 onMenu(0) 勾选第一个分类
-    onMenu(foundCategory ? state.categoryList.indexOf(foundCategory) : 0);
+};
+
+// 加载产品列表
+async function getGoodsList() {
+  // 加载列表
+  state.loadStatus = 'loading';
+  const res = await SpuApi.getSpuPage({
+    categoryId: state.categoryList[state.activeMenu].id,
+    pageNo: state.pagination.pageNo,
+    pageSize: state.pagination.pageSize,
   });
-
-  function handleScrollToLower() {
-    loadMore();
+  if (res.code !== 0) {
+    return;
+  }
+  // 合并列表
+  state.pagination.list = _.concat(state.pagination.list, res.data.list);
+  state.pagination.total = res.data.total;
+  state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
+}
+
+// 加载更多产品
+function loadMore() {
+  if (state.loadStatus === 'noMore') {
+    return;
   }
+  state.pagination.pageNo++;
+  getGoodsList();
+}
+
+onLoad(async (params) => {
+  await getList();
+
+  // 首页点击分类的处理:查找满足条件的分类
+  const foundCategory = state.categoryList.find((category) => category.id === Number(params.id));
+  // 如果找到则调用 onMenu 自动勾选相应分类,否则调用 onMenu(0) 勾选第一个分类
+  onMenu(foundCategory ? state.categoryList.indexOf(foundCategory) : 0);
+});
+
+function handleScrollToLower() {
+  loadMore();
+}
 </script>
 
 <style lang="scss" scoped>
-  .s-category {
-    :deep() {
-      .side-menu-wrap {
-        width: 200rpx;
-        height: 100%;
-        padding-left: 12rpx;
-        background-color: #f6f6f6;
-
-        .menu-item {
-          width: 100%;
-          height: 88rpx;
+.s-category {
+  :deep() {
+    .side-menu-wrap {
+      width: 200rpx;
+      height: 100%;
+      padding-left: 12rpx;
+      background-color: #f6f6f6;
+
+      .menu-item {
+        width: 100%;
+        height: 88rpx;
+        position: relative;
+        transition: all linear 0.2s;
+
+        .menu-title {
+          line-height: 32rpx;
+          font-size: 30rpx;
+          font-weight: 400;
+          color: #333;
+          margin-left: 28rpx;
           position: relative;
-          transition: all linear 0.2s;
-
-          .menu-title {
-            line-height: 32rpx;
-            font-size: 30rpx;
-            font-weight: 400;
-            color: #333;
-            margin-left: 28rpx;
-            position: relative;
-            z-index: 0;
+          z-index: 0;
 
-            &::before {
-              content: '';
-              width: 64rpx;
-              height: 12rpx;
-              background: linear-gradient(
-                90deg,
+          &::before {
+            content: '';
+            width: 64rpx;
+            height: 12rpx;
+            background: linear-gradient(90deg,
                 var(--ui-BG-Main-gradient),
-                var(--ui-BG-Main-light)
-              ) !important;
-              position: absolute;
-              left: -64rpx;
-              bottom: 0;
-              z-index: -1;
-              transition: all linear 0.2s;
-            }
+                var(--ui-BG-Main-light)) !important;
+            position: absolute;
+            left: -64rpx;
+            bottom: 0;
+            z-index: -1;
+            transition: all linear 0.2s;
           }
+        }
 
-          &.menu-item-active {
-            background-color: #fff;
-            border-radius: 20rpx 0 0 20rpx;
-
-            &::before {
-              content: '';
-              position: absolute;
-              right: 0;
-              bottom: -20rpx;
-              width: 20rpx;
-              height: 20rpx;
-              background: radial-gradient(circle at 0 100%, transparent 20rpx, #fff 0);
-            }
+        &.menu-item-active {
+          background-color: #fff;
+          border-radius: 20rpx 0 0 20rpx;
+
+          &::before {
+            content: '';
+            position: absolute;
+            right: 0;
+            bottom: -20rpx;
+            width: 20rpx;
+            height: 20rpx;
+            background: radial-gradient(circle at 0 100%, transparent 20rpx, #fff 0);
+          }
 
-            &::after {
-              content: '';
-              position: absolute;
-              top: -20rpx;
-              right: 0;
-              width: 20rpx;
-              height: 20rpx;
-              background: radial-gradient(circle at 0% 0%, transparent 20rpx, #fff 0);
-            }
+          &::after {
+            content: '';
+            position: absolute;
+            top: -20rpx;
+            right: 0;
+            width: 20rpx;
+            height: 20rpx;
+            background: radial-gradient(circle at 0% 0%, transparent 20rpx, #fff 0);
+          }
 
-            .menu-title {
-              font-weight: 600;
+          .menu-title {
+            font-weight: 600;
 
-              &::before {
-                left: 0;
-              }
+            &::before {
+              left: 0;
             }
           }
         }
       }
+    }
 
-      .goods-list-box {
-        background-color: #fff;
-        width: calc(100vw - 100px);
-        padding: 10px;
-      }
+    .goods-list-box {
+      background-color: #fff;
+      width: calc(100vw - 100px);
+      padding: 10px;
+    }
 
-      .banner-img {
-        width: calc(100vw - 130px);
-        border-radius: 5px;
-        margin-bottom: 20rpx;
-      }
+    .banner-img {
+      width: calc(100vw - 130px);
+      border-radius: 5px;
+      margin-bottom: 20rpx;
     }
   }
+}
 </style>

+ 34 - 34
pages/index/components/first-two.vue

@@ -18,49 +18,49 @@
 </template>
 
 <script setup>
-  import sheep from '@/sheep';
-  import { fen2yuan } from '@/sheep/hooks/useGoods';
+import sheep from '@/sheep';
+import { fen2yuan } from '@/sheep/hooks/useGoods';
 
-  const props = defineProps({
-    pagination: Object,
-  });
+const props = defineProps({
+  pagination: Object,
+});
 </script>
 
 <style lang="scss" scoped>
-  .goods-box {
-    width: calc((100% - 20rpx) / 2);
-    margin-bottom: 20rpx;
+.goods-box {
+  width: calc((100% - 20rpx) / 2);
+  margin-bottom: 20rpx;
 
-    .goods-img {
-      width: 100%;
-      height: 246rpx;
-      border-radius: 10rpx 10rpx 0px 0px;
-    }
-
-    .goods-content {
-      width: 100%;
-      background: #ffffff;
-      box-shadow: 0px 0px 20rpx 4rpx rgba(199, 199, 199, 0.22);
-      padding: 20rpx 0 32rpx 16rpx;
-      box-sizing: border-box;
-      border-radius: 0 0 10rpx 10rpx;
+  .goods-img {
+    width: 100%;
+    height: 246rpx;
+    border-radius: 10rpx 10rpx 0px 0px;
+  }
 
-      .goods-title {
-        font-size: 26rpx;
-        font-weight: bold;
-        color: #333333;
-      }
+  .goods-content {
+    width: 100%;
+    background: #ffffff;
+    box-shadow: 0px 0px 20rpx 4rpx rgba(199, 199, 199, 0.22);
+    padding: 20rpx 0 32rpx 16rpx;
+    box-sizing: border-box;
+    border-radius: 0 0 10rpx 10rpx;
 
-      .goods-price {
-        font-size: 24rpx;
-        font-family: OPPOSANS;
-        font-weight: 500;
-        color: #e1212b;
-      }
+    .goods-title {
+      font-size: 26rpx;
+      font-weight: bold;
+      color: #333333;
     }
 
-    &:nth-child(2n + 1) {
-      margin-right: 20rpx;
+    .goods-price {
+      font-size: 24rpx;
+      font-family: OPPOSANS;
+      font-weight: 500;
+      color: #e1212b;
     }
   }
+
+  &:nth-child(2n + 1) {
+    margin-right: 20rpx;
+  }
+}
 </style>

+ 49 - 47
pages/index/components/second-one.vue

@@ -9,16 +9,11 @@
     </view>
     <!-- 二级分类的名字 -->
     <view class="goods-item-box ss-flex ss-flex-wrap ss-p-b-20">
-      <view
-        class="goods-item"
-        v-for="item in props.data[activeMenu].children"
-        :key="item.id"
-        @tap="
-          sheep.$router.go('/pages/goods/list', {
-            categoryId: item.id,
-          })
-        "
-      >
+      <view class="goods-item" v-for="item in props.data[activeMenu].children" :key="item.id" @tap="
+        sheep.$router.go('/pages/goods/list', {
+          categoryId: item.id,
+        })
+        ">
         <image class="goods-img" :src="item.picUrl" mode="aspectFill" />
         <view class="ss-p-10">
           <view class="goods-title ss-line-1">{{ item.name }}</view>
@@ -29,52 +24,59 @@
 </template>
 
 <script setup>
-  import sheep from '@/sheep';
+import sheep from '@/sheep';
 
-  const props = defineProps({
-    data: {
-      type: Object,
-      default: () => ({}),
-    },
-    activeMenu: [Number, String],
-  });
+const props = defineProps({
+  data: {
+    type: Object,
+    default: () => ({}),
+  },
+  activeMenu: [Number, String],
+});
 </script>
 
 <style lang="scss" scoped>
-  .title-box {
-    .title-line-left,
-    .title-line-right {
-      width: 15px;
-      height: 1px;
-      background: #d2d2d2;
-    }
+.title-box {
+
+  .title-line-left,
+  .title-line-right {
+    width: 15px;
+    height: 1px;
+    background: #d2d2d2;
   }
+}
 
-  .goods-item {
-    width: calc((100% - 20px) / 3);
-    margin-right: 10px;
-    margin-bottom: 10px;
+.goods-item {
+  width: calc((100% - 50px) / 3);
+  margin-right: 10px;
+  margin-bottom: 10px;
+  background: #eee;
+  box-shadow: 0px 0px 20rpx 8rpx rgba(199, 199, 199, 0.22);
+  border-radius: 20rpx;
+  padding: 10rpx;
 
-    &:nth-of-type(3n) {
-      margin-right: 0;
-    }
+  &:nth-of-type(3n) {
+    margin-right: 0;
+  }
 
-    .goods-img {
-      width: calc((100vw - 140px) / 3);
-      height: calc((100vw - 140px) / 3);
-    }
+  .goods-img {
+    width: calc((100vw - 180px) / 3);
+    height: calc((100vw - 180px) / 3);
+    border-radius: 20rpx;
 
-    .goods-title {
-      font-size: 26rpx;
-      font-weight: bold;
-      color: #333333;
-      line-height: 40rpx;
-      text-align: center;
-    }
+  }
+
+  .goods-title {
+    font-size: 26rpx;
+    font-weight: bold;
+    color: #333333;
+    line-height: 40rpx;
+    text-align: center;
+  }
 
-    .goods-price {
-      color: $red;
-      line-height: 40rpx;
-    }
+  .goods-price {
+    color: $red;
+    line-height: 40rpx;
   }
+}
 </style>