1 Star 0 Fork 1

yufeng/vue-goods-category

forked from Smile/vue-goods-category 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
category.vue 14.88 KB
一键复制 编辑 原始数据 按行查看 历史
Smile 提交于 2020-12-09 15:58 . update goods category
<template>
<div class="categoryWrap">
<!-- 搜索 -->
<div class="search bd">
<div class="search-bar">
<div class="searchBox" @click="toCommTap('search')">
<i class="iconfont icon-sousuo"></i>
<p>搜索</p>
</div>
</div>
</div>
<main>
<!-- 左侧菜单分类 -->
<aside class="fixeds" ref="l_list">
<ul class="left-menu">
<li ref="l_item" :class="{'active': index === currentIndex}"
@click="changeMenu(index, item.name)" v-for="(item, index) in categoryList" :key="index">
<div class="cname" ref="cname">{{item.name}}</div>
</li>
</ul>
</aside>
<!-- 右侧商品列表 -->
<section class="right_list fixeds" ref="r_list">
<div>
<div class='listsWrap'>
<ul class="goods-list" v-for="(outerItem, outerIdx) in categoryList" :key="outerIdx" ref="good">
<li class="goods-li bd" v-for="(item, index) in outerItem.goods" :key="index" @click="toCommTap('goods?id='+ item.id +'&goodsType='+ item.goodsType)">
<div class="goods-item bd">
<div class="goods-thumb">
<img v-lazy="item.goodsMainImage" alt="">
</div>
<div class="goods-content">
<div class="title">{{item.goodsName}}</div>
<div class="subTit">{{item.goodsSummary}}</div>
<div class="tagBox">
<van-tag class="integral" v-if="parseInt(item.discountIntegral) > 0" color="#fdf0ea" text-color="#fe5303">最高可用{{item.discountIntegral}}积分</van-tag>
<van-tag class="vanTag" color="#fff" text-color="#999">剩余{{item.goodsStock}}</van-tag>
</div>
<div class="goods-desc">
<div class="price">
<p class="memberPrice">
<span>{{item.goodsRetailPrice}}</span>
</p>
<p class="retailPrice">
<span>{{item.goodsMarketPrice}}</span>
</p>
</div>
<div class="addCard" @click.stop="addToShopCart(item)"></div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<!-- 右侧标题 标签 -->
<div class="shortcut-bar bd">
<div class="cname">{{fixedTitle}}</div>
<div class="tagList">
<div class="tag-name" :class="{'active': index === tagIndex}" v-for="(item,index) in tagList" :key="index" @click="chageTag(index, item.type)">
{{item.name}}
</div>
</div>
</div>
</section>
</main>
<ball ref="balls"></ball>
<!-- 引入tabbar组件 -->
<footerGuide></footerGuide>
</div>
</template>
<script>
import footerGuide from "@/components/common/footer";
import BScroll from "better-scroll";
import ball from "@/components/common/ball";
export default {
data() {
return {
currentIndex: 0, // 当前选中index
scrollY: 0,
heightList: [0], // 存储某个分类下的商品高度列表
flag: false, // 解决是否选中当前分类index
fixedTitle: '', // 当前分类标题
tagList: [{"type": 1, "name": "全部"}, {"type": 2, "name": "热销"}], //分类列表
tagIndex: 0, //分类tag当前index
type: 1, // 1:全部 2:热销
categoryList: [ // 数据仅供测试,请自行copy多些来看效果
{
categoryId: 1,
name: "健康蔬菜",
goods: [
{
goodsName: '大个小番茄',
goodsSummary: '绿色小番茄',
goodsStock: 231,
goodsRetailPrice: 5.4,
goodsMarketPrice: 6.8,
// goodsMainImage: require('../../assets/images/icon/icon_1.png')
goodsMainImage: 'xxxxx'
},
{
goodsName: '新鲜小奶白菜',
goodsSummary: '清脆、鲜嫩蔬菜',
goodsStock: 134,
goodsRetailPrice: 3.8,
goodsMarketPrice: 5.5,
goodsMainImage: 'xxxxx'
},
]
},
{
categoryId: 2,
name: "时令蔬菜",
goods: [
{
goodsName: '大又甜地瓜',
goodsSummary: '自家种植放心品尝',
goodsStock: 344,
goodsRetailPrice: 6.5,
goodsMarketPrice: 8.4,
goodsMainImage: 'xxxxx'
},
{
goodsName: '精美套餐',
goodsSummary: '健康搭配新鲜蔬菜',
goodsStock: 1099,
goodsRetailPrice: 45.9,
goodsMarketPrice: 65.8,
goodsMainImage: 'xxxxx'
},
{
goodsName: '水果黄瓜',
goodsSummary: '可口脆嫩水果黄瓜',
goodsStock: 785,
goodsRetailPrice: 3.5,
goodsMarketPrice: 4.8,
goodsMainImage: 'xxxxx'
},
]
},
]
}
},
components: {
footerGuide,
ball
},
mounted() {
this.fixedTitle = this.categoryList[0].name;
this.$nextTick(() => {
// 初始化better-scroll
this.scrollInit();
// 获取某个分类下商品列表离顶部距离
this.getCategoryListHeight();
})
},
methods: {
toCommTap(url) {
this.$router.push(url);
},
changeMenu (index, name) {
this.flag = true;
this.currentIndex = index;
this.fixedTitle = name;
//【-32 标题高度】 根据自身调整,如果不需要写0即可。
this.rightList.scrollToElement(this.$refs.good[index], 1000, 0, -32);
},
chageTag(index, type) {
this.tagIndex = index;
this.type = type;
console.log('切换标签');
},
/**
* 初始化
*/
scrollInit() {
this.left = new BScroll(this.$refs.l_list, {
click: true,
probeType: 3,
})
this.rightList = new BScroll(this.$refs.r_list, {
probeType: 3, // 是否会截流scroll事件
scrollY: true, // 是否开启Y轴滚动方向
click: true, // 是否开启点击事件
useTransition: false, // 防止iphone微信滑动卡顿
bounce: true, // 是否启用回弹动画效果
momentumLimitDistance: 5 // 符合惯性拖动的最小拖动距离
})
this.rightList.on('scroll', (res) => {
this.scrollY = Math.abs(Math.round(res.y));
for (let i = 0; i < this.heightList.length; i++) {
if (this.scrollY > this.heightList[i] && this.scrollY < this.heightList[i + 1]) {
if (!this.flag) {
this.currentIndex = i;
}
// 当滚动到倒数第2个位置时左侧列表向上滚动一个距离
if (i === this.$refs.l_item.length - 2) {
this.left.scrollToElement(this.$refs.l_item[1], 1000, 0, 0)
}
// 当滚动到倒数第3个位置时左侧列表向上下滚动一个距离
if (i === 2) {
this.left.scrollToElement(this.$refs.l_item[0], 1000, 0, 0)
}
// 获取当前分类标题
this.fixedTitle = this.$refs.cname[i].innerText;
}
}
})
this.rightList.on("scrollEnd", pos => {
//结束时触发事件获取一次位置,因为使用了模式2,惯性滚动不触发事件
this.scrollY = Math.abs(Math.round(pos.y));
this.flag = false;
})
},
/**
* 获取商品列表高度
*/
getCategoryListHeight() {
this.$refs.good.forEach((el, index) => {
this.heightList.push(el.offsetHeight + this.heightList[index]);
})
},
addToShopCart(item) {
this.$refs.balls.addToCart(item);
},
}
}
</script>
<style lang="scss" scoped>
@import '../../assets/style/mixin';
.categoryWrap {
.search {
padding: 20px 0;
}
.search-bar {
@include wh(95%, 56px);
margin: 0px auto;
@include fcc;
.searchBox {
@include fcc;
@include bg($f5);
width: 100%;
height: 100%;
@include borderRadius(28px);
.icon-sousuo {
@include sc(28px, $fc9);
margin-right: 8px;
}
p {
@include sc(24px, #8f8f8f);
}
}
}
.fixeds {
position: fixed;
top: 96px;
bottom: 104px;
overflow: hidden;
}
aside{
left: 0;
@include bg($f5);
.left-menu {
li{
height: 110px;
width: 200px;
box-sizing: border-box;
@include bg($f5);
@include fcc;
position: relative;
.cname {
@include sc(28px, $fc);
}
}
.active{
@include bg;
&::before {
content: '';
@include ct;
left: 0;
@include wh(6px, 40px);
@include bg($main);
@include borderRadius(0 6px 6px 0);
}
.cname {
@include sc(32px, $main);
}
}
}
}
.right_list {
left: 200px;
right: 0;
flex: 1;
.bd {
&::after {
left: 20px;
}
}
}
.shortcut-bar {
@include fcb;
line-height: 70px;
padding-left: 20px;
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: 1;
@include bg;
.cname {
@include sc(20px, $fc9);
}
.tagList {
@include fc;
}
.tag-name {
@include sc(26px, $fc);
padding-right: 40px;
}
.active {
color: $main;
}
}
.listsWrap {
padding-top: 70px;
.goods-list {
overflow: hidden;
display: flex;
flex-wrap: wrap;
width: 100%;
flex-direction: row;
&:last-of-type {
padding-bottom: 100px;
}
.goods-li {
width: 100%;
}
.goods-item {
@include fc;
padding: 30px 30px 30px 20px;
@include bg($white);
.goods-thumb {
@include wh(160px, 160px);
img {
@include wh(100%, 100%);
}
}
.goods-content {
flex: 1;
padding: 0 0 0 20px;
min-width: 0;
.title {
font-size: 30px;
@include omit;
}
.subTit {
@include sc(20px, $fc9);
@include lineClamp;
}
.price {
@include sc(20px, $fc9);
@include fc(flex-end);
margin-top: 10px;
.memberPrice {
color: $orange;
margin-bottom: -6px;
span {
@include sc(36px, $orange);
font-weight: bold;
}
}
.retailPrice {
padding-left: 5px;
text-decoration: line-through;
}
}
}
.goods-desc {
@include fcb;
.addCard {
@include wh(54px, 54px);
bottom: 23px;
}
}
}
}
}
}
</style>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/ityufeng/vue-goods-category.git
[email protected]:ityufeng/vue-goods-category.git
ityufeng
vue-goods-category
vue-goods-category
master

搜索帮助