设计商品的数据结构
在这里,首页数据是根据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啦