设计商品的数据结构
在这里,首页数据是根据TabControl切换而得到的,而每次上拉加载都刷新一定数量的数据,所以根据三个切换按钮在里面又定义了三个对象,而每次上拉加载都定义为加一页(默认第一页),所以定义page用来存储当前页数信息,用list来存储到当前页加载到的商品数量
1 2 3 4 5
| goods: { 'pop': {page:0, list:[]}, 'new': {page:0, list:[]}, 'sell': {page:0, list:[]}, }
|
首页数据的请求和封装
ntework里的home.js同第一个网络请求的函数一样,再次定义另外一个,获得商品数据
1 2 3 4 5 6 7 8 9 10
| export function getHomeGoods(type,page) { return request({ url: '/api/h8/home/data', params: { type, page } }) }
|
在home.vue调用该函数,并将其封装成方法,因为我们在网络请求后会做进一步的处理,所以我们用同名的函数将其封装起来,并在create()中调用这些网络请求以及具体的实现方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| created() { this.getHomeMultidata() this.getHomeGoods('pop') this.getHomeGoods('new') this.getHomeGoods('sell') }, methods: { getHomeMultidata() { getHomeMultidata().then(res => { this.banners = res.data.banner.list this.recommends = res.data.recommend.list }) }, getHomeGoods(type) { const page = this.goods[type].page + 1 getHomeGoods(type, page).then(res => { this.goods[type].list.push(...res.data.list) this.goods[type].page ++ }) } }
|
商品展示
因为涉及到该项目的业务功能(好几个页面会用到该组件),所以在components中的content中新建goods文件夹,新建两个vue文件GoodsList以及GoodsListItem,一个用来描述单个商品的详细样式,另外一个用来展示整体商品的样式
GoodsList.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <template> <div class="goods-list"> <goods-list-item v-for="item in goods" :goods-item="item"></goods-list-item> </div> </template>
<script> import GoodsListItem from './GoodsListItem.vue' export default { name: 'GoodsList', props: { goods: { type: Array, default() { return [] } } }, components: { GoodsListItem } } </script>
<style scoped> .goods-list { display: flex; padding: 2px;
/* 包裹 */ flex-wrap: wrap; justify-content: space-around; } </style>
|
GoodsListItem.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| <template> <div class="goods-list-item"> <img :src="goodsItem.show.img" alt=""> <div class="goods-info"> <p>{{goodsItem.title}}</p> <span class="price">{{goodsItem.price}}</span> <span class="collect">{{goodsItem.cfav}}</span> </div> </div> </template>
<script> export default { name: 'GoodsListItem', props: { goodsItem: { type: Object, default() { return {} } } }, components: {
} } </script>
<style scoped> .goods-list-item { position: relative; padding-bottom: 40px; width: 48%; }
.goods-list-item img { width: 100%; border-radius: 5px; }
.goods-info { position: absolute; left: 0; right: 0; bottom: 5px; overflow: hidden; text-align: center; font-size: 12px; }
.goods-info p { overflow: hidden; /* 显示省略符号来代表被修剪的文本 */ text-overflow: ellipsis; /* 文本不换行 */ white-space: nowrap; margin-bottom: 3px; }
.goods-info .price { color: var(--color-high-text); margin-right: 20px; }
.goods-info .collect { position: relative; }
.goods-info .collect::before { content: ''; position: absolute; left: -15px; top: -1px; width: 14px; height: 14px; background: url("~assets/img/common/collect.svg") 0 0/14px 14px; } </style>
|
这里主要有几个css的新知识点(或者遗忘点)
1 2 3 4 5 6 7 8 9
| text-overflow: ellipsis;
white-space: nowrap;
flex-wrap: wrap;
justify-content: space-around;
|
tabcontrol切换商品类型
回到tabcontrol,我们需要通过点击事件来切换不同的商品展示,所以这里就要动态绑定点击事件,同时,为了触发父组件的goods信息改变,我们需要将该事件点击所对应的tab的索引传给父组件
动态绑定事件
1 2 3 4
| <div v-for="(item,index) in titles" class="tab-control-item" :class = "{active: index === currentIndex}" @click="itemchange(index)">
|
传出事件以及当前点击的索引
1 2 3 4 5 6
| methods: { itemchange(index) { this.currentIndex = index this.$emit('tabClick', index) } }
|
父组件接收点击事件
1
| <tab-control :titles="['流行', '新款', '精选']" class="tab" @tabClick="tabClick"></tab-control>
|
用一个变量获得当前请求的数据索引(默认首页)
1 2 3
| data () { currentType: 'pop' }
|
处理该事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| methods: { tabClick(index) { switch (index) { case 0: this.currentType = 'pop' break case 1: this.currentType = 'new' break case 2: this.currentType = 'sell' break } } }
|
再在computed中,动态改变当前请求的数据索引
1 2 3 4 5
| computed: { showGoods() { return this.goods[this.currentType].list } }
|
在标签,动态绑定数据
1
| <goods-list :goods="showGoods"></goods-list>
|
这样就OK啦