修复可视区域高度问题
- 通过设置小程序和 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'
}
]
}
]
},
}