请求接口渲染首页数据
改数据为接口获取模式
-
接口数据使用nodejs的express框架,搭建详情见上一个笔记
-
服务器的index.js 文件内容如下
将 swiper 和 commodityList组件需要的数据 封装到后端,方便前端请求数据
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/data', function(req, res, next) {
// res.render('index', { title: 'Express' });
// res.json({
// "a":1
// });
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;
- 前端 indexSwiper.vue 文件
文件中将原来的静态数据改为 动态获取使用时通过参数传递过来的dataList数据
此处也有一个bug 需要先将 动态获取高度的功能取消 改为2000 默认高度,后期再去修正为动态获取高度
<template>
<view class="swiperview">
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
<swiper-item v-for="(item,index) in dataList" :key="index">
<view class="swiper-item">
<image class="swiper-img" :src="item.imgUrl" mode=""></image>
</view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default{
props:{
dataList:Array
}
}
</script>
<style lang="scss">
/* 清楚swiper默认高度 */
swiper{
width: 750rpx;
height: 450rpx;
}
.swiper-img{
width: 100%;
}
</style>
- 前端 Recommend.vue 组件文件
将 组件中的静态数据转为动态 数据
<template>
<view class="recommend bg-color">
<view v-for="(item,index) in dataList" :key="index" class="recommend-item">
<image class="item-big" :src="item.bigUrl" mode=""></image>
<view class="item-small">
<block v-for="(k,i) in item.data" :key="i">
<image class="item-img" :src="k.imgUrl" mode=""></image>
</block>
</view>
</view>
</view>
</template>
<script>
export default{
props:{
dataList:Array
}
}
</script>
<style lang="scss">
.recommend{
padding: 20rpx;
}
.recommend-item{
display: flex;
flex-direction: column;
border-radius: 20rpx;
border: 2rpx solid #ccc;
overflow: hidden;
margin: 20rpx 0;
}
.item-big{
width: 100%;
height: 300rpx;
}
.item-small{
width: 100%;
height: 240rpx;
}
.item-img{
width: 33.33333%;
height: 240rpx;
}
</style>
- 前端 RecommodList.vue 组件文件
将 组件中的静态数据转为动态 数据
<template>
<view class="commodity-list">
<!-- 商品列表组件 -->
<!-- 向子组件发送数据 dateList 是参数名称 commodityList 为数据 -->
<Commodity :dataList='dataList'></Commodity>
</view>
</template>
<script>
import Commodity from './Commodity.vue'
export default {
props:{
dataList:Array
},
/* data(){
return{
commdityList:[ //示例数据
{
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>
</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"
>
<view class="home-data">
<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>
<CommodityList v-if="k.type==='commodityList'" :dataList='k.data'></CommodityList>
</block>
</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() { // 初步渲染完后执行
let view = uni.createSelectorQuery().select(".home-data"); // 获取dom节点对象
// 获取节点对象数据
view.boundingClientRect(data=>{
// 动态获取内容块的高度,动态渲染swiper高度
// 不要去试图计算可视区域的高度,在ios下有bug
this.clentHeight = 2000;
// this.clentHeight = data.height;
}).exec();
},
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
},
onChangeTab(e){
this.changeTab(e.detail.current)
}
}
}
</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>
后端的接口文档说明
一、 首页数据
1.1 接口功能
获取首页数据
1.2 URL
地址 /api/index_list/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'
}
]
}
]
},
}