UNIAPP实战项目笔记17 request的封装

UNIAPP实战项目笔记17 request封装

  • request封装

将请求对象的属性和方法进行封装,方便后期上线。
此处仅封装了get请求


  • request.js
export default{
    common:{
        baseUrl:"http://127.0.0.1:3000/api",
        data:{},
        header:{
            "Content-Type":"application/json",
            "Content-Type":"application/x-www-form-urlencoded"
        },
        method:"GET",
        dataType:"json"
    },
    request( options={} ){
        
        uni.showLoading({
            title:"加载中"
        })
        
        options.url = this.common.baseUrl + options.url;
        options.data = options.data || this.common.data;
        options.header = options.header || this.common.header;
        options.method = options.method || this.common.method;
        options.dataType = options.dataType || this.common.dataType;
        return new Promise((res,rej)=>{
            uni.request({
                ...options,
                success: (result) => {
                    if(result.statusCode != 200){
                        return rej();
                    }
                    setTimeout(function(){
                        uni.hideLoading();
                    },1000)
                    let data = result.data.data;
                    res(data);
                }
            })
    
        }) 
    }
    
}

案例的图片

UNIAPP实战项目笔记17 request的封装_第1张图片

目录结构

目录结构
  • manifest.json 配置文件: appid、logo…

  • pages.json 配置文件: 导航、 tabbar、 路由

  • main.js vue初始化入口文件

  • App.vue 全局配置:样式、全局监视

  • static 静态资源:图片、字体图标

  • page 页面

    • index
      • index.vue
    • list
      • list.vue
    • my
      • my.vue
  • components 组件

    • index
      • Banner.vue
      • Icons.vue
    • common
      • commondity.vue
  • common 公共文件:全局css文件 || 全局js文件

    • api
      • request.js

index.vue 的代码内容
代码中的请求,都已经用新封装的renquest代替

<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 @scrolltolower="loadMore(index)" 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>
                        <view class="load-text f-color">
                            {{item.loadText}}
                        </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 $http from '@/common/api/request.js'
    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(){
                $http.request({
                    url:'/index_list/data'
                }).then((res)=>{
                    this.topBar = res.topBar;
                    this.newTopBar = this.initData(res);
                }).catch(()=>{
                    uni.showToast({
                        title:'请求失败',
                        icon:'none'
                    })
                })
            },
            // 添加数据
            initData(res){
                let arr = [];
                for (var i = 0; i < this.topBar.length; i++) {
                    let obj = {
                        data:[],
                        load:"first",
                        loadText:"上拉加载更多..."
                    }
                    // 获取首次数据
                    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
                
                // 每一次滑动 load赋值为first
                if(this.newTopBar[this.topBarIndex].load == 'first'){
                    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(callback){
                // 拿到索引
                let index = this.topBarIndex;
                // 拿到id
                let id = this.topBar[index].id;
                // 计算页码
                let page = Math.ceil(this.newTopBar[index].data.length/5) + 1;
                // console.log(page);
                // 请求不同的数据
                $http.request({
                    url:`/index_list/${id}/data/${page}`
                }).then((res)=>{
                    this.newTopBar[index].data = [...this.newTopBar[index].data,...res]
                }).catch(()=>{
                    uni.showToast({
                        title:'请求失败',
                        icon:'none'
                    })
                })
                // 请求结束后重新赋值
                this.newTopBar[index].load = 'last';
                
                if(typeof callback === 'function'){
                    callback();
                }
            },
            // 上拉加载更多
            loadMore(index){
                this.newTopBar[index].loadText = '加载中...';
                
                // 请求完数据,文字提示信息又换成【上拉加载更多...】
                this.addData(()=>{
                    this.newTopBar[index].loadText = '上拉加载更多...';
                })
            }
		}
	}
</script>

<style>

.load-text{
    border-top: 2rpx solid #636263;
    line-height: 60rpx;
    text-align: center;
}
.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>

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