UNIAPP实战项目笔记13 请求接口渲染首页数据

请求接口渲染首页数据

改数据为接口获取模式

  • 接口数据使用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 返回字段

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

1.7 接口实例

{
	"code":"0",
	"data":{
		topBar:[
			{
				id: 1,
				name: '推荐'
			}
			....
		],
		data:[
			{
				type:"swiperList",
				data:[
					{
						imgUrl:'../../static/img/swiper1.png'
					}
				]
			}
		]
	},
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值