UNIAPP实战项目笔记14 修复可视区域高度问题 滑动不同板块展示不同数据

修复可视区域高度问题

  • 通过设置小程序和 iso 安卓APP 不同系统做兼容

app端会默认加入刘海屏高度,计算减去此高度即可

// 获取可视区域高度【兼容】
            getClientHeight(){
                const res = uni.getSystemInfoSync();
                console.log(res.platform,res.statusBarHeight);
                const system = res.platform;
                if ( system === 'iso') {
                    return 44 + res.statusBarHeight;
                }else if( system === 'android' ){
                    return 48 + res.statusBarHeight;
                } else{
                    return 0;
                }
            },

可以参看下面的index.vue 的整体代码

滑动不同板块展示不同数据

各组件设置为可传递数据参数

  • hot.vue

热门组件

<template>
    <view class="hot">
        <Commodity :dataList="dataList" itemW='250rpx' bigH="250rpx"></Commodity>
    </view>
</template>

<script>
    import Commodity from '../common/Commodity.vue'
    export default{
        props:{
            dataList:Array
        },
        data(){
            return {
                /*  */
            }
        },
        components:{
            Commodity
        }
    }
</script>

<style>
</style>
  • banner.vue

banner组件

<template>
    <view class="banner">
        <image class="banner-img" :src="dataList" mode=""></image>
    </view>
</template>

<script>
export default{
    props:{
        dataList:String
    }
}
</script>

<style lang="scss">
.banner{
    width: 100%;
    height: 300rpx;
}
.banner-img{
    width: 100%;
    height: 300rpx;
}
</style>
  • shop.vue

推荐店铺组件

<template>
    <view class="shop">
        <view class="shop-item" v-for="(item,index) in dataList" :key="index">
            <view class="shop-big">
               <image class="shop-big" :src="item.bigUrl" mode=""></image> 
            </view>
            <scroll-view class="scroll-content" scroll-x="true" >
                <view class="scroll-item">
                    <Commodity 
                    :dataList="item.data"
                    wrap='no-wrap'
                    itemW="200rpx"
                    bigH="200rpx"
                    nameSize="20rpx"
                    ></Commodity>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script>
import Commodity from '../common/Commodity.vue'
export default{
    props:{
        dataList:Array
    },
    data(){
        return{
            /* shopList:[
                {
                    id:1,
                    imgUrl:"../../static/logo.png",
                    name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                    pprice:"299",
                    oprice:"659",
                    discount:"5.2"
                },
                {
                    id:2,
                    imgUrl:"../../static/logo.png",
                    name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                    pprice:"299",
                    oprice:"659",
                    discount:"5.2"
                },{
                    id:3,
                    imgUrl:"../../static/logo.png",
                    name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                    pprice:"299",
                    oprice:"659",
                    discount:"5.2"
                },
                {
                    id:4,
                    imgUrl:"../../static/logo.png",
                    name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                    pprice:"299",
                    oprice:"659",
                    discount:"5.2"
                }
            ] */
        }
    },
    components:{
        Commodity
    }
}
</script>

<style lang="scss">
.shop-big{
    width: 100%;
    height: 350rpx;
}
.scroll-content{
    width: 100%;
    white-space: nowrap;
    height: 350rpx;
}
.scroll-item{
    display: inline-block;
    width: 300rpx;
    height: 300rpx;
}
</style>
  • icons.vue

宫格组件

<template>
    <!-- 宫格组件 -->
    <view class="icons">
        <view class="icons-item" v-for="(item,index) in dataList" :key="index">
            <image class="icons-img" :src="item.imgUrl" mode=""></image>
            <text class="icons-name f-color">{{item.name}}</text>
        </view>
        <!-- <view class="icons-item">
            <image class="icons-img" src="../../static/logo.png" mode=""></image>
            <text class="icons-name f-color">运动户外</text>
        </view>
        <view class="icons-item">
            <image class="icons-img" src="../../static/logo.png" mode=""></image>
            <text class="icons-name f-color">运动户外</text>
        </view>
        <view class="icons-item">
            <image class="icons-img" src="../../static/logo.png" mode=""></image>
            <text class="icons-name f-color">运动户外</text>
        </view>
        <view class="icons-item">
            <image class="icons-img" src="../../static/logo.png" mode=""></image>
            <text class="icons-name f-color">运动户外</text>
        </view>
        <view class="icons-item">
            <image class="icons-img" src="../../static/logo.png" mode=""></image>
            <text class="icons-name f-color">运动户外</text>
        </view>
        <view class="icons-item">
            <image class="icons-img" src="../../static/logo.png" mode=""></image>
            <text class="icons-name f-color">运动户外</text>
        </view>
        <view class="icons-item">
            <image class="icons-img" src="../../static/logo.png" mode=""></image>
            <text class="icons-name f-color">运动户外</text>
        </view> -->
    </view>
</template>

<script>
export default{
    props:{
        dataList:Array
    }
}

</script>

<style lang="scss">
.icons{
    display: flex;
    flex-wrap: wrap;
}
.icons-item{
    width: 25%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding-top: 20rpx;
}
.icons-img{
    width: 110rpx;
    height: 110rpx;
}
</style>
  • index.vue

首页页面

<template>
	<view class="content">
        <view class="index">
            
            <scroll-view scroll-x="true" :scroll-into-view="scrollIntoIndex" class="scroll-content" >
                <view
                :id="'top'+index"
                    class="scroll-item"
                    v-for="(item,index) in topBar"
                    :key="index"
                    @tap="changeTab(index)"
                >
                    <text :class="topBarIndex===index?'f-active-color':'f-color'">{{item.name}}</text>
                </view>
            </scroll-view>
            
            <swiper @change="onChangeTab" :current="topBarIndex" :style="'height:'+clentHeight+'px'">
                <swiper-item
                    v-for="(item,index) in newTopBar"
                    :key="index"
                >
                    <scroll-view scroll-y="true" :style="'height:'+clentHeight+'px;'">
                        <block v-if="item.data.length > 0">                            
                            <block v-for="(k,i) in item.data" :key="i">
                                <!-- 推荐 -->
                                <IndexSwiper v-if="k.type==='swiperList'" :dataList='k.data'></IndexSwiper>
                                <template v-if="k.type==='recommendList'">
                                    <Recommend :dataList='k.data'></Recommend>
                                    <Card cardTitle='猜你喜欢'></Card>
                                    <!-- 卡片要在下面显示,但是位置要放到上面 template 表示一个整体循环 -->
                                </template>
                                
                                <!-- 运动户外... -->
                                <Banner v-if="k.type==='bannerList'" :dataList='k.imgUrl'></Banner>
                                
                                <template v-if="k.type==='iconsList'">
                                    <Icons :dataList='k.data'></Icons>
                                    <Card cardTitle="热销商品"></Card>
                                </template>
                                
                                <template v-if="k.type==='hotList'">
                                    <Hot :dataList='k.data'></Hot>
                                    <Card cardTitle="推荐店铺"></Card>
                                </template>

                                <template v-if="k.type==='shopList'">
                                    <Shop :dataList='k.data'></Shop>
                                    <Card cardTitle="为您推荐"></Card>
                                </template>
                                
                                <CommodityList v-if="k.type==='commodityList'" :dataList='k.data'></CommodityList>
                                
                            
                            </block>
                        </block>
                        <view v-else>
                            暂无数据...
                        </view>
                    </scroll-view>
                    
                </swiper-item>
            </swiper>
            
            
            
            <!-- 推荐模板 -->
            <!-- <IndexSwiper></IndexSwiper>
            <Recommend></Recommend>
            <Card cardTitle='猜你喜欢'></Card>
            <CommodityList></CommodityList> -->
            
            <!-- 其他模板: 运动户外 美妆... -->
            <!-- <Card cardTitle='运动户外'></Card>
            <Banner></Banner>
            <Icons></Icons>
            <Card cardTitle='热销爆品'></Card>
            <Hot></Hot>
            <Card cardTitle='店铺推荐'></Card>
            <Shop></Shop>
            <Card cardTitle="为您推荐"></Card>
            <CommodityList></CommodityList>
            -->
        </view>
        
        <!-- <view class="f-active-color">
            文字
        </view>
        <view class="iconfont icon-xiaoxi"></view>
		<view class="text-area">
			<text class="title">{{title}}</text>
		</view> -->
	</view>
</template>

<script>
    import IndexSwiper from '@/components/index/indexSwiper.vue';//引入
    import Recommend from '@/components/index/Recommend.vue';//引入
    import Card from '@/components/common/Card.vue';//引入
    import CommodityList from '@/components/common/CommodityList.vue';//引入
    import Banner from '@/components/index/Banner.vue';//引入
    import Icons from '@/components/index/Icons.vue';//引入
    import Hot from '@/components/index/Hot.vue';//引入
    import Shop from '@/components/index/Shop.vue';//引入
	export default {
		data() {
			return {
                // 选中的索引
                topBarIndex:0,
                // 顶栏跟随的索引id值
                scrollIntoIndex:'top0',
                // 内容块的高度
                clentHeight:0,
                // 顶栏数据
                topBar:[],
                // 承载数据
                newTopBar:[],
				title: 'Hello'
			}
		},
        components:{
            IndexSwiper, //注册
            Recommend,
            Card,
            CommodityList,
            Banner,
            Icons,
            Hot,
            Shop
            
        },
		onLoad() {
            // 请求接口数据
            this.__init();
            
		},
        onReady() { // 初步渲染完后执行
            uni.getSystemInfo({
                success: (res) => {
                    // console.log(res);
                    // 可视区域高度 减去头部高度
                    this.clentHeight = res.windowHeight - uni.upx2px(80) - this.getClientHeight();
                }
            })
            /* let view = uni.createSelectorQuery().select(".home-data"); // 获取dom节点对象
            // 获取节点对象数据
            view.boundingClientRect(data=>{
                // 动态获取内容块的高度,动态渲染swiper高度
                // 不要去试图计算可视区域的高度,在ios下有bug
                this.clentHeight = 2000;
                // this.clentHeight = data.height;
            }).exec(); */
            // this.getClientHeight();
		},
		methods: {
            // 请求首页数据
            __init(){
                uni.request({
                    url:"http://127.0.0.1:3000/api/index_list/data",
                    success: (res) => {
                        // console.log(res.data.data);
                        let data = res.data.data;
                        this.topBar = data.topBar;
                        this.newTopBar = this.initData(data);
                    }
                })
            },
            // 添加数据
            initData(res){
                let arr = [];
                for (var i = 0; i < this.topBar.length; i++) {
                    let obj = {
                        data:[]
                    }
                    // 获取首次数据
                    if (i==0) {
                        obj.data = res.data
                    }
                    arr.push(obj)
                }
                return arr;
            },
            // 点击顶栏
            changeTab(index){
                if (this.topBarIndex === index) {
                    return;
                }
                this.topBarIndex = index
                this.scrollIntoIndex = 'top'+index
                this.addData();
            },
            // 对应滑动
            onChangeTab(e){
                this.changeTab(e.detail.current)
            },
            // 获取可视区域高度【兼容】
            getClientHeight(){
                const res = uni.getSystemInfoSync();
                console.log(res.platform,res.statusBarHeight);
                const system = res.platform;
                if ( system === 'iso') {
                    return 44 + res.statusBarHeight;
                }else if( system === 'android' ){
                    return 48 + res.statusBarHeight;
                } else{
                    return 0;
                }
            },
            // 对应显示不同数据
            addData(){
                // 拿到索引
                let index = this.topBarIndex;
                // 拿到id
                let id = this.topBar[index].id;
                // 请求不同的数据
                uni.request({
                    url:`http://127.0.0.1:3000/api/index_list/${id}/data/1`,
                    success: (res) => {
                        let data = res.data.data;
                        // console.log(data);
                        this.newTopBar[index].data = [...this.newTopBar[index].data,...data]
                    }
                })
            } 
		}
	}
</script>

<style>
.scroll-content{
    width: 100%;
    height: 80rpx;
    white-space: nowrap;
}
.scroll-item{
    display: inline-block;
    padding: 10rpx 30rpx;
    font-size: 32rpx;
}
.f-active-color{
    padding: 10rpx 0;
    border-bottom: 6rpx solid #49BDFB;
}
.index{
    width: 100%;
}
.content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.logo {
    height: 200rpx;
    width: 200rpx;
    margin-top: 200rpx;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 50rpx;
}

.text-area {
    display: flex;
    justify-content: center;
}

.title {
    font-size: 36rpx;
    color: #8f8f94;
}
</style>

自定义服务器接口

  • 服务器数据接口更改

index.js
保存后重启服务器哈

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

/* 运动户外 */
router.get('/api/index_list/2/data/1', function(req, res, next) {
  res.send({
      code:"0",
      data:[          
          {
            type:"bannerList",
            imgUrl:"../../static/img/b3.jpg",
          },
          {
              type:"iconsList",
              data:[
                  {imgUrl:"../../static/logo.png",name:"运动户外"},
                  {imgUrl:"../../static/logo.png",name:"运动户外"},
                  {imgUrl:"../../static/logo.png",name:"运动户外"},
                  {imgUrl:"../../static/logo.png",name:"运动户外"},
                  {imgUrl:"../../static/logo.png",name:"运动户外"},
                  {imgUrl:"../../static/logo.png",name:"运动户外"},
                  {imgUrl:"../../static/logo.png",name:"运动户外"},
                  {imgUrl:"../../static/logo.png",name:"运动户外"}
              ]
          },
          {
              type:"hotList",
              data:[
                  {
                      id:1,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
                  {
                      id:2,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },{
                      id:3,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  }
              ]
          },
          {
              type:"shopList",
              data:[
                  {
                      bigUrl:"../../static/img/b3.jpg",
                      data:[
                          {
                              id:1,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          },
                          {
                              id:2,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          },{
                              id:3,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          },
                          {
                              id:4,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          }
                      ]
                  }
              ],
          },
          {
              type:"commodityList",
              data:[
                  {
                      id:1,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
                  {
                      id:2,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },{
                      id:3,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
                  {
                      id:4,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
              ]
          },
          
      ]
  });
});

/* 服饰内衣 */
router.get('/api/index_list/3/data/1', function(req, res, next) {
  res.send({
      code:"0",
      data:[          
          {
            type:"bannerList",
            imgUrl:"../../static/img/b3.jpg",
          },
          {
              type:"iconsList",
              data:[
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"},
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"},
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"},
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"},
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"},
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"},
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"},
                  {imgUrl:"../../static/logo.png",name:"服饰内衣"}
              ]
          },
          {
              type:"hotList",
              data:[
                  {
                      id:1,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
                  {
                      id:2,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },{
                      id:3,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  }
              ]
          },
          {
              type:"shopList",
              data:[
                  {
                      bigUrl:"../../static/img/b3.jpg",
                      data:[
                          {
                              id:1,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          },
                          {
                              id:2,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          },{
                              id:3,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          },
                          {
                              id:4,
                              imgUrl:"../../static/logo.png",
                              name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                              pprice:"299",
                              oprice:"659",
                              discount:"5.2"
                          }
                      ]
                  }
              ],
          },
          {
              type:"commodityList",
              data:[
                  {
                      id:1,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
                  {
                      id:2,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },{
                      id:3,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
                  {
                      id:4,
                      imgUrl:"../../static/logo.png",
                      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
                      pprice:"299",
                      oprice:"659",
                      discount:"5.2"
                  },
              ]
          },
          
      ]
  });
});



/* 首页推荐数据 */
router.get('/api/index_list/data', function(req, res, next) {
  res.send({
	  "code":0,
	  "data":{
		  topBar:[
			  {id:1,name:'推荐'},
			  {id:2,name:'运动户外'},
			  {id:3,name:'服饰内衣'},
			  {id:4,name:'鞋靴箱包'},
			  {id:5,name:'美妆个护'},
			  {id:6,name:'家居数码'},
			  {id:7,name:'食品母婴'}
		  ],
		  data:[
			  {
				  type:"swiperList",
				  data:[
					  {imgUrl:'/static/img/b3.jpg'},
					  {imgUrl:'/static/img/b3.jpg'},
					  {imgUrl:'/static/img/b3.jpg'}
				  ]
			  },{
				  type:"recommendList",
				  data:[
					  {
						  bigUrl:"../../static/img/b3.jpg",
						  data:[
							  {imgUrl:'../../static/logo.png'},
							  {imgUrl:'../../static/logo.png'},
							  {imgUrl:'../../static/logo.png'}
						  ]
					  },{
						  bigUrl:"../../static/img/b3.jpg",
						  data:[
							  {imgUrl:'../../static/logo.png'},
							  {imgUrl:'../../static/logo.png'},
							  {imgUrl:'../../static/logo.png'}
						  ]
					  }
				  ]
			  },{
				  type:"commodityList",
				  data:[
					  {
					      id:1,
					      imgUrl:"../../static/logo.png",
					      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
					      pprice:"299",
					      oprice:"659",
					      discount:"5.2"
					  },
					  {
					      id:2,
					      imgUrl:"../../static/logo.png",
					      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
					      pprice:"299",
					      oprice:"659",
					      discount:"5.2"
					  },{
					      id:3,
					      imgUrl:"../../static/logo.png",
					      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
					      pprice:"299",
					      oprice:"659",
					      discount:"5.2"
					  },
					  {
					      id:4,
					      imgUrl:"../../static/logo.png",
					      name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
					      pprice:"299",
					      oprice:"659",
					      discount:"5.2"
					  },
				  ]
			  },
		  ]
	  }
  })
});



module.exports = router;

以下为接口文档

二、 首页分类数据
1.1 接口功能

获取首页分类数据

1.2 URL

地址 /api/index_list/栏目的 id/data/数量

1.3 支持格式

JSON

1.4 HTTP 请求方式

GET

1.5 请求参数

| 参数 | 必选 | 类型 | 说明 |

1.6 返回字段

返回字段 字段类型 说明
code string 返回结果状态 0:正常;1:错误
data object 首页数据

1.7 接口实例

{
	"code":"0",
	"data":{
		topBar:[
			{
				id: 1,
				name: '推荐'
			}
			....
		],
		data:[
			{
				type:"swiperList",
				data:[
					{
						imgUrl:'../../static/img/swiper1.png'
					}
				]
			}
		]
	},
}

你可能感兴趣的:(uni-app,uni-app,javascript,vue.js)