359 lines
8.7 KiB
Vue
359 lines
8.7 KiB
Vue
<template> <!-- 商城 -->
|
|
<view class="wrap">
|
|
<!-- 吸顶 -->
|
|
<u-sticky offset-top="0" customNavHeight="0">
|
|
<!-- 顶部 -->
|
|
<uiheader title="金久信特产商城"></uiheader>
|
|
<!-- 搜索栏 -->
|
|
<cmsearch :k="keyword" @search="search" placeholder="请输入商品名称等搜索"></cmsearch>
|
|
<!-- 轮播图-传值:list="数组" -->
|
|
<cmswiper page="shop" height="320rpx"></cmswiper>
|
|
<view class="layout-sch bg-white flex justify-between align-center" @click="showAddress">
|
|
<view class="select down flex-1">{{ locationValue ? locationValue : '选择地区' }}</view>
|
|
<!-- <view class="flex-1"></view>-->
|
|
<view class="logo">
|
|
<image class="full" src="/static/img/shoplogo.png" mode=""></image>
|
|
</view>
|
|
<!-- <view class="name m-left-10">金久信特产商城</view>-->
|
|
</view>
|
|
<!-- 滑动区 -->
|
|
<view class="flex justify-start items-center bg-white">
|
|
<scroll-view class="scroll-box flex-1" @scroll="onCateScroll" scroll-x="true">
|
|
<view class="item" :class="{ active: categoryId === null }" @click="selectCate(null)">
|
|
<view class="text break">全部</view>
|
|
</view>
|
|
<view class="item" :class="{ active: categoryId === item._id }" v-for="(item,index) in categoryList"
|
|
:key="index" @click="selectCate(item._id)">
|
|
<view class="text break">{{ item.name }}</view>
|
|
</view>
|
|
</scroll-view>
|
|
<view >
|
|
<u-icon name="arrow-right-double" :color="hasMore ? '#A92924' : '#AAAAAA'"/>
|
|
</view>
|
|
</view>
|
|
</u-sticky>
|
|
<!-- 列表 -->
|
|
<uiswiper :ad="27" padding="10rpx 20rpx"></uiswiper>
|
|
<uiswiper :ad="28" padding="10rpx 20rpx"></uiswiper>
|
|
<uiswiper :ad="29" padding="10rpx 20rpx"></uiswiper>
|
|
<uiswiper :ad="30" padding="10rpx 20rpx"></uiswiper>
|
|
<uiswiper :ad="31" padding="10rpx 20rpx"></uiswiper>
|
|
<view class="layout layout-shop flex justify-between flex-wrap">
|
|
<view class="item pos-r" @click="detailLink(item._id)" v-for="(item, index) in goodsList" :key="index">
|
|
<view class="img">
|
|
<image class="full" :src="item.cover" mode="aspectFill"/>
|
|
</view>
|
|
<text class="recommend" v-if="item.recommend === 1">荐</text>
|
|
<view class="info">
|
|
<view class="title text-both">
|
|
{{ item.name }}
|
|
</view>
|
|
<view class="price m-top-10">
|
|
<text class="current">¥<text class="blod">{{ item.amount }}</text>
|
|
到手价
|
|
</text>
|
|
<!-- <text class="cost m-left-10">¥35.5</text>-->
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!-- 没有数据 u-empty是框架组件 cmempty是自己封装组件 -->
|
|
<u-empty mode="list" text="暂无更多内容~" v-if="goodsList.length === 0"></u-empty>
|
|
<!-- <cmempty></cmempty> -->
|
|
<collapse></collapse>
|
|
<AddressSelect ref="AddressSelect" @confirm="regionConfirm"/>
|
|
<view class="issue" @click="$jump('/pages/shop/cart')">
|
|
<u-icon name="shopping-cart" color="#fff" size="24"></u-icon>
|
|
<text class="cartNum" v-if="cartNum > 0">{{ cartNum }}</text>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import uiheader from '@/components/index/header'
|
|
import cmsearch from '@/components/common/search'
|
|
import cmempty from '@/components/common/empty'
|
|
import cmswiper from '@/components/common/swiper'
|
|
import Collapse from "@/components/index/collapse.vue";
|
|
import AddressSelect from "@/components/AddressSelect.vue";
|
|
import uiswiper from "@/components/index/swiper.vue";
|
|
|
|
export default {
|
|
components: {
|
|
uiswiper,
|
|
AddressSelect,
|
|
Collapse,
|
|
uiheader,
|
|
cmsearch,
|
|
cmempty,
|
|
cmswiper,
|
|
},
|
|
data() {
|
|
return {
|
|
categoryList: [],
|
|
goodsList: [],
|
|
options: [],
|
|
address: [],
|
|
pageIndex: 1,
|
|
pageSize: 20,
|
|
total: 0,
|
|
categoryId: null,
|
|
keyword: null,
|
|
locationValue: null,
|
|
region: {
|
|
province: {
|
|
code: null,
|
|
name: null,
|
|
},
|
|
city: {
|
|
code: null,
|
|
name: null,
|
|
},
|
|
},
|
|
cartNum: 0,
|
|
hasMore: true
|
|
}
|
|
},
|
|
methods: {
|
|
showAddress() {
|
|
this.$refs.AddressSelect.open(this.region, 2, true);
|
|
},
|
|
regionConfirm({province, city}) {
|
|
this.region = {province, city}
|
|
this.locationValue = `${province.name}${city.name}`
|
|
this.getGoodsList()
|
|
},
|
|
handTab(val, index) {
|
|
this.custIndex = index
|
|
},
|
|
detailLink(id) {
|
|
vk.navigateTo(`/pages/shop/detail?id=${id}`, {
|
|
id,
|
|
})
|
|
},
|
|
getCategoryList() {
|
|
vk.callFunction({
|
|
url: 'client/goods/category/pub/getList'
|
|
}).then(res => {
|
|
this.categoryList = res.rows
|
|
})
|
|
},
|
|
search(keyword) {
|
|
this.keyword = keyword
|
|
this.getGoodsList()
|
|
},
|
|
getGoodsList(pageIndex = 1) {
|
|
vk.callFunction({
|
|
url: 'client/goods/list/pub/getList',
|
|
data: {
|
|
pageIndex,
|
|
pageSize: this.pageSize,
|
|
city: this.region.city ? this.region.city.code : null,
|
|
parentId: this.categoryId,
|
|
keyword: this.keyword
|
|
}
|
|
}).then(res => {
|
|
this.goodsList = res.rows
|
|
})
|
|
},
|
|
getCartNum() {
|
|
vk.callFunction({
|
|
url: 'client/cart/kh/getNum',
|
|
}).then(({data}) => {
|
|
this.cartNum = data
|
|
})
|
|
},
|
|
selectCate(cateId) {
|
|
if (this.categoryId === cateId) this.categoryId = null
|
|
else this.categoryId = cateId
|
|
this.getGoodsList()
|
|
},
|
|
onCateScroll({detail: {scrollLeft, scrollWidth}}) {
|
|
const wrapWidth = uni.upx2px(690)
|
|
const maxScrollLeft = scrollWidth - wrapWidth
|
|
console.log(maxScrollLeft, scrollLeft)
|
|
this.hasMore = scrollLeft + 50 < maxScrollLeft
|
|
}
|
|
},
|
|
onLoad(option) {
|
|
if (option.keyword) this.keyword = option.keyword
|
|
this.getCategoryList()
|
|
this.getGoodsList()
|
|
this.getCartNum()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.layout-sch {
|
|
padding: 30rpx 30rpx;
|
|
|
|
.select {
|
|
position: relative;
|
|
width: 260rpx;
|
|
height: 40rpx;
|
|
font-size: 28rpx;
|
|
line-height: 40rpx;
|
|
color: #333;
|
|
padding: 10rpx 30rpx 10rpx 20rpx;
|
|
border: 1px solid #f2f2f2;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.down::after {
|
|
position: absolute;
|
|
right: 20rpx;
|
|
top: 50%;
|
|
z-index: 9;
|
|
content: '';
|
|
margin-top: -6rpx;
|
|
width: 0;
|
|
height: 0;
|
|
border-left: 10rpx solid transparent;
|
|
border-right: 10rpx solid transparent;
|
|
border-top: 12rpx solid #999999;
|
|
}
|
|
|
|
.logo {
|
|
width: 80rpx;
|
|
height: 60rpx;
|
|
}
|
|
|
|
.name {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
line-height: 44rpx;
|
|
color: #101010;
|
|
}
|
|
}
|
|
|
|
.scroll-box {
|
|
// width: 690rpx;
|
|
width: 690rpx;
|
|
//height: 80rpx;
|
|
padding: 0 30rpx;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
align-items: center;
|
|
white-space: nowrap;
|
|
background: #ffffff;
|
|
|
|
.item {
|
|
display: inline-block;
|
|
margin-right: 10rpx;
|
|
height: 60rpx;
|
|
padding: 0 20rpx;
|
|
font-size: 28rpx;
|
|
line-height: 60rpx;
|
|
text-align: center;
|
|
color: #454545;
|
|
border-radius: 6rpx;
|
|
background: #f2f2f2;
|
|
|
|
&:last-child {
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
|
|
.active {
|
|
color: #ffffff;
|
|
background: #A92924;
|
|
}
|
|
}
|
|
|
|
.layout-shop {
|
|
margin: 20rpx 30rpx;
|
|
|
|
.item {
|
|
margin-top: 30rpx;
|
|
width: 330rpx;
|
|
height: auto;
|
|
background: #ffffff;
|
|
border-radius: 20rpx;
|
|
overflow: hidden;
|
|
|
|
&:nth-child(1), &:nth-child(2) {
|
|
margin-top: 0rpx;
|
|
}
|
|
|
|
.img {
|
|
width: 100%;
|
|
height: 320rpx;
|
|
}
|
|
|
|
.info {
|
|
padding: 20rpx 10rpx;
|
|
|
|
.title {
|
|
width: 100%;
|
|
height: 72rpx;
|
|
font-size: 28rpx;
|
|
line-height: 36rpx;
|
|
color: #101010;
|
|
}
|
|
|
|
.bs {
|
|
font-size: 22rpx;
|
|
line-height: 32rpx;
|
|
color: #ffffff;
|
|
padding: 0 8rpx;
|
|
background: #A92924;
|
|
border-radius: 12rpx;
|
|
}
|
|
|
|
.price {
|
|
width: 100%;
|
|
//height: 32rpx;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.current {
|
|
font-size: 24rpx;
|
|
line-height: 32rpx;
|
|
color: #A92924;
|
|
|
|
.blod {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
.cost {
|
|
font-size: 24rpx;
|
|
line-height: 32rpx;
|
|
color: #666666;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
.recommend {
|
|
position: absolute;
|
|
right: 0;
|
|
top: 0;
|
|
padding: 5px;
|
|
background-color: #bf2b28;
|
|
color: white;
|
|
font-size: 30rpx;
|
|
z-index: 1;
|
|
}
|
|
|
|
.cartNum {
|
|
position: absolute;
|
|
right: -10rpx;
|
|
top: -10rpx;
|
|
padding: 5px;
|
|
background-color: #FFFFFF;
|
|
color: #bf2b28;
|
|
font-size: 20rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 25rpx;
|
|
width: 25rpx;
|
|
height: 25rpx;
|
|
border: 1px solid #bf2b28;
|
|
}
|
|
</style>
|