Browse Source

feat: 商品列表页面;

pull/1/head
fox 2 months ago
parent
commit
4fa33db1e6
6 changed files with 175 additions and 117 deletions
  1. +2
    -2
      components/base/navbar.vue
  2. +2
    -2
      components/base/tabbar.vue
  3. +65
    -25
      components/product/productCard.vue
  4. +98
    -86
      pages/index/category.vue
  5. +2
    -1
      pages/index/index.vue
  6. +6
    -1
      uni.scss

+ 2
- 2
components/base/navbar.vue View File

@ -1,7 +1,7 @@
<template>
<!-- <view class="navbar"
:style="{backgroundColor : bgColor}"> -->
<view class="title"
<view class="title nav-bar__view"
:style="{backgroundColor : bgColor,color}">
<view class="left">
@ -110,7 +110,7 @@
left: 0;
padding-top: calc(var(--status-bar-height) + 20rpx);
width: 100%;
height: 100rpx;
height: $navbar-height;
background-color: #fff;
display: flex;
justify-content: center;


+ 2
- 2
components/base/tabbar.vue View File

@ -78,7 +78,7 @@
<style scoped lang="scss">
.tabbar-box {
height: 120rpx;
height: $tabbar-height;
padding-bottom: env(safe-area-inset-bottom);
.tabbar {
@ -89,7 +89,7 @@
justify-content: center;
align-items: center;
flex-direction: row;
height: 120rpx;
height: $tabbar-height;
padding-bottom: env(safe-area-inset-bottom);
z-index: 999999;
bottom: 0;


+ 65
- 25
components/product/productCard.vue View File

@ -1,34 +1,36 @@
<template>
<view class="card flex product" :class="[direction]">
<view class="card flex product" :class="[direction]" @click="$emit('click')">
<view class="img" :class="[ data.isRecommend ? 'is-recommend' : '']">
<image :src="data.imgUrl" mode="aspectFill"></image>
<image v-if="data.isRecommend" class="mark" src="@/static/image/home/mark-recommend.png"></image>
</view>
<view class="flex flex-column info">
<view class="title">{{ data.title }}</view>
<view>{{ data.desc }}</view>
<view class="flex price" :class="[role]">
<view>
<text class="price-unit">¥</text>
<text>{{ data.price }}</text>
</view>
<view class="flex right">
<view class="flex flex-column info">
<view class="title">{{ data.title }}</view>
<view>{{ data.desc }}</view>
<view class="flex price" :class="[role]">
<view>
<text class="price-unit">¥</text>
<text>{{ data.price }}</text>
</view>
<view class="flex tag" v-if="role === 'member-personal'">
<image class="icon" src="@/static/image/home/icon-member-personal.png"></image>
<text>个人会员价</text>
</view>
<view class="flex tag" v-else-if="role === 'member-business'">
<image class="icon" src="@/static/image/home/icon-member-business.png"></image>
<text>企业会员价</text>
</view>
<view class="flex tag" v-if="role === 'member-personal'">
<image class="icon" src="@/static/image/home/icon-member-personal.png"></image>
<text>个人会员价</text>
</view>
<view class="flex tag" v-else-if="role === 'member-business'">
<image class="icon" src="@/static/image/home/icon-member-business.png"></image>
<text>企业会员价</text>
<view class="flex sales">
<image class="icon" src="@/static/image/home/icon-sales.png"></image>
<text>{{ `已售出 ${data.sales}` }}</text>
</view>
</view>
<view class="flex sales">
<image class="icon" src="@/static/image/home/icon-sales.png"></image>
<text>{{ `已售出 ${data.sales}` }}</text>
</view>
<button plain class="btn" @click="goToPlaceOrder">立即下单</button>
</view>
<button class="btn">立即下单</button>
</view>
</template>
@ -60,7 +62,12 @@
return {
role: 'member-business', // member-personal | member-business
}
}
},
methods: {
goToPlaceOrder() {
// todo
}
},
}
</script>
@ -98,7 +105,6 @@
.info {
flex: 1;
align-items: flex-start;
padding-left: 14rpx;
}
.title {
@ -159,7 +165,9 @@
}
.btn {
border: none;
display: inline-block;
margin: 0;
border: none !important;
background-color: $uni-color-light;
color: $uni-text-color-inverse;
font-size: 22rpx;
@ -171,7 +179,39 @@
border-radius: 29rpx;
}
&.horizontal {
.right {
flex: 1;
padding-left: 14rpx;
}
&.vertical {
padding: 23rpx 22rpx;
.right {
flex-direction: column;
align-items: flex-start;
padding-left: 23rpx;
}
.img {
width: 215rpx;
height: 215rpx;
border-radius: 15rpx;
overflow: hidden;
}
.price {
.tag {
margin-left: 15rpx;
}
}
.btn {
margin-top: 4rpx;
background-image: linear-gradient(#84A73F, #D8FF8F);
padding: 12rpx 28rpx;
border-radius: 10rpx;
}
}
}
</style>


+ 98
- 86
pages/index/category.vue View File

@ -1,74 +1,74 @@
<template>
<view class="page">
<!-- 导航栏 -->
<navbar title="商品列表"
leftClick
@leftClick="$utils.navigateBack"
bgColor="#E3441A"
color="#fff" />
<navbar title="商品" class="nav-bar"
leftClick
@leftClick="$utils.navigateBack"
bgColor="#E3441A"
color="#fff"
/>
<!-- 搜索栏 -->
<view class="search">
<uv-search placeholder="搜你喜欢的产品" bgColor="#fff"
@search="search"
@change="search"
@custom="search"
v-model="queryParams.title"></uv-search>
<uv-search
v-model="queryParams.title"
placeholder="搜索项目名称"
bgColor="#F5F5F5"
inputAlign="center"
:showAction="false"
@search="search"
@change="search"
@custom="search"
></uv-search>
</view>
<!-- 商品列表 -->
<view style="position: 20rpx;"
v-if="queryParams.title">
<productList :list="list" />
<view v-if="queryParams.title" >
<productCard v-for="item in list" :data="item" :key="item.id"></productCard>
</view>
<!-- 分类商品列表 -->
<view class="category"
v-else>
<view class="tabs">
<uv-tabs
<!-- todo: check chain? -->
<view v-else class="" >
<uv-vtabs
:list="category"
:activeStyle="{color : '#f00', fontWeight : 600}"
lineColor="#f00"
:inactiveStyle="{color: 'rgba(0,0,0,.8)'}"
lineHeight="8rpx"
lineWidth="50rpx"
keyName="name"
:current="current"
@click="clickTabs"></uv-tabs>
</view>
<uv-vtabs
:list="category[current].children"
:current="currentChildren"
keyName="name"
:chain="false"
@change="change">
<!-- <view class="list"> -->
<!-- <template v-for="(item, index) in category[current].children">
<uv-vtabs-item :index="index" :key="index">
<view class="category-item">
<view class="category-title">
{{ item.name }}
</view>
<productItem :item="pro"
v-for="(pro, i) in item.shopList" :key="i"
@click="$utils.navigateTo(`/pages_order/product/productDetail?id=${pro.id}`)" />
</view>
</uv-vtabs-item>
</template> -->
<!-- </view> -->
:chain="true"
@change="change"
<uv-vtabs-item>
<view class="category-item">
<productItem :item="pro"
v-for="(pro, i) in categoryList.shopList" :key="i"
@click="$utils.navigateTo(`/pages_order/product/productDetail?id=${pro.id}`)" />
<uv-empty v-if="categoryList.shopList.length == 0" text="还没有呢"/>
</view>
</uv-vtabs-item>
barWidth="177rpx"
barBgColor="#F5F5F5"
:barItemStyle="{
color: '#000000',
fontSize: '28rpx',
fontWeight: 700,
}"
:barItemActiveStyle="{
color: '#84A73F',
backgroundColor: '#FFFFFF',
}"
:barItemActiveLineStyle="{
backgroundImage: 'linear-gradient(#84A73F, #D8FF8F)',
margin: '25rpx 3rpx',
}"
>
<template v-for="(item, index) in category">
<uv-vtabs-item :index="index" :key="item.id">
<template v-if="item.childrens.length">
<productCard
v-for="product in item.childrens"
:key="product.id"
:data="product"
direction="vertical"
></productCard>
</template>
<template v-else>
<uv-empty text="还没有呢"/>
</template>
</uv-vtabs-item>
</template>
</uv-vtabs>
</view>
@ -78,6 +78,8 @@
</template>
<script>
import productCard from '@/components/product/productCard.vue'
import productItem from '@/components/product/productItem.vue';
import mixinsList from '@/mixins/list.js'
import {
@ -88,22 +90,20 @@
export default {
mixins: [mixinsList],
components: {
productItem,
productCard,
tabber,
productItem,
productList,
},
data() {
return {
mixinsListApi: 'getClassShopPageList',
mixinsListApi: 'queryItemList',
current : 0,
currentChildren : 0,
}
},
computed: {
...mapState(['category']),
categoryList(){
return this.category[this.current].children[this.currentChildren]
},
},
onLoad({
search,
@ -127,11 +127,7 @@
methods: {
change(e) {
// this.queryParams.classId = this.category[e].id
this.currentChildren = e
},
clickTabs({index}){
this.current = index
this.currentChildren = 0
this.current = e
},
search(){
for(let i = 0;i < 10;i++){
@ -146,39 +142,55 @@
<style scoped lang="scss">
.page {
/deep/ .uv-vtabs {
height: calc(100vh - 600rpx) !important;
}
/deep/ .uv-vtabs__bar {
height: calc(100vh - 600rpx) !important;
}
background-color: #FFFFFF;
/deep/ .uv-vtabs__content {
height: calc(100vh - 600rpx) !important;
/deep/ .nav-bar__view {
background-image: linear-gradient(#84A73F, #D8FF8F);
}
.search {
position: relative;
background: #FFFFFF;
margin: 20rpx;
background: #F5F5F5;
margin: 15rpx 30rpx;
border-radius: 41rpx;
padding: 10rpx 20rpx;
display: flex;
align-items: center;
}
/deep/ .uv-search__action {
background-color: $uni-color;
color: #FFFFFF;
padding: 10rpx 20rpx;
border-radius: 30rpx;
}
$search-height: 108rpx;
$list-height: calc(#{$body-height} - #{$search-height});
/deep/ .uv-vtabs,
/deep/ .uv-vtabs__bar,
/deep/ .uv-vtabs__content {
height: $list-height !important;
}
&::v-deep .uv-vtabs__content {
background: transparent !important;
/deep/ .uv-vtabs {
background-color: #F5F5F5;
overflow: hidden;
}
/deep/ .uv-vtabs__bar {
// box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.16);
}
/deep/ .uv-vtabs__content {
margin-left: 6px;
margin-right: 10rpx;
}
/deep/ .uv-vtabs__bar-item {
padding: 25rpx 0 !important;
text-align: center;
}
&::v-deep .uv-vtabs__content {
background: #F5F5F5 !important;
// overflow: hidden;
}
}
.category {


+ 2
- 1
pages/index/index.vue View File

@ -41,7 +41,7 @@
</view>
<!-- 优惠券弹窗 -->
<couponPopup v-if="true || riceInfo.isGetCoupon"></couponPopup>
<couponPopup v-if="riceInfo.isGetCoupon"></couponPopup>
<!-- tabbar -->
<tabber select="home" />
@ -120,6 +120,7 @@
}
},
onShow() {
// todo: delete test code
return
this.getBanner()


+ 6
- 1
uni.scss View File

@ -102,4 +102,9 @@ $uni-font-size-paragraph:15px;
.uni-placeholder {
color: #C7C7C7;
font-size: 30rpx;
}
}
$navbar-height: 100rpx;
$tabbar-height: 120rpx;
$body-height: calc(100vh - #{$tabbar-height} - env(safe-area-inset-bottom) - #{$navbar-height} - var(--status-bar-height) - 20rpx);

Loading…
Cancel
Save