st779779

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

从0开始 UNI-APP开发(仿饿了么)

项目介绍及工具下载

1-工具下载

uniapp官方文档

https://uniapp.dcloud.net.cn/

hbuilder x工具下载

https://hx.dcloud.net.cn/Tutorial/install/windows

微信开小程序发工具下载:

https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

2-项目介绍

用uni-app仿照饿了么ui来做一款外卖小程序 从中学习uni-app的使用

3-前置知识

需要有 vue 微信小程序 html JavaScript css 基础知识学起来更轻松

4-项目预览

5-课程链接及课件下载

课程链接: https://www.luffycity.com/actual-course/573/detail

https://www.php.cn/course/1348.html#kcdg

课件下载 https://hcdn2.luffycity.com/media/course_related/573.txt

第1章uniapp框架基础与饿了么首页布局

创建空白项目

image-20230812215640342

image-20230812220026729

默认模板框架目录

image-20230812223328769

查看和预览效果

image-20230812225814073

tree /f


│  App.vue
│  index.html
│  main.js
│  manifest.json
│  pages.json
│  uni.promisify.adaptor.js
│  uni.scss
│
├─pages
│  └─index
│          index.vue
│
└─static
        logo.png

App.vue

<script>
	//管理应用的生命周期
	export default {
		onLaunch: function() {
			//检查网络状况 检查版本更新
			console.log('App Launch')
		},
		//后台进入前台时候触发
		onShow: function() {
			console.log('App Show')
		},
		// 由前台转到后台
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

<style>
	/*每个页面公共css */
</style>

pages.json 文件pages数组中第一项表示应用启动页

"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
            "path" : "pages/tabbar/index/index",
            "style" :                                                                                    
            {
                "navigationBarTitleText": "",
                "enablePullDownRefresh": false
            }
            
        }
      .....
    ],

目标样式

image-20230812225050536
目标1 下面的用tabbar来做 目标2 上面的部分需要注意的地方 最上面的状态栏和胶囊高度 不同的型号机型是不同的 所有要做成动态的 上面的部分是通用的要做成组件
https://uniapp.dcloud.net.cn/collocation/pages.html#tabbar https://uniapp.dcloud.net.cn/component/vue-component.html#component

目标1 -底部效果

1-在 pages 右键 新建目录 tabbar image-20230812230412900
会在pages.json文件中自动注册
2-在刚新建tabbar目录下面新建三个页面
分别对应为 我的 首页订单 三个功能
index order my
image-20230812230705168 image-20230812230831103 image-20230812231322968

3-在pages.json文件中使用tabbar 并将 pages/tabbar/index/index 设置为启动页

"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    {
        "path" : "pages/tabbar/index/index",
        "style" :                                                                                    
        {
            "navigationBarTitleText": "",
            "enablePullDownRefresh": false
        }

    }
    ,{
        "path" : "pages/tabbar/order/order",
        "style" :                                                                                    
        {
            "navigationBarTitleText": "",
            "enablePullDownRefresh": false
        }

    }
    ,{
        "path" : "pages/tabbar/my/my",
        "style" :                                                                                    
        {
            "navigationBarTitleText": "",
            "enablePullDownRefresh": false
        }

    }
],
"tabBar": {
    //文字颜色
	"color": "#7A7E83",
    //选中的时候颜色
	"selectedColor": "#3cc51f",
    //边框样式
	"borderStyle": "black",
    //背景颜色
	"backgroundColor": "#ffffff",
    //这里面设置不同的页面路径和 icon图片
	"list": [{
        //路径
		"pagePath": "pages/tabbar/index/index",
        //icon路径
		"iconPath": "static/tabbar/index.png",
        //选中时候的icon
		"selectedIconPath": "static/tabbar/index-active.png",
        //名称
		"text": "首页"
	}, {
        "pagePath": "pages/tabbar/my/my",
        "iconPath": "static/tabbar/my.png",
        "selectedIconPath": "static/tabbar/my-active.png",
        "text": "我的"
    },{
        "pagePath": "pages/tabbar/order/order",
        "iconPath": "static/tabbar/order.png",
        "selectedIconPath": "static/tabbar/order-active.png",
        "text": "订单"
    }]
}

image-20230812232947555

目标2 -顶部效果

默认的标题是居中 我们想让它在左边 就用定义导航来做

通过观察 顶部为通用的部分 不同的页面都会用到 我们用组件来做

设置自定义导航

pages.json文件中设置 沉浸式导航栏 设置后原来的导航就会消失

//全局设置
"globalStyle": {
	"navigationBarTextStyle": "black",
	"navigationBarTitleText": "饿了么",
	"navigationBarBackgroundColor": "#fff",
	//下拉刷新的时候的设置
	"backgroundColor": "#666",
	
	//设置该选项
	"navigationStyle": "custom"
},

1-在项目中创建 components 目录

2-在目录下面新建组件 - 这样创建后的可以直接在页面中调用

新建组件 新建一个navbar的组件
image-20230812234405635 image-20230812234452692

3-编写代码 在navbar文件里面

钩子函数 created 组件生命周期 在实例创建完成后被立即调用 设置变量和样式

最上面的状态栏和胶囊高度 不同的型号机型是不同的 所有要做成动态的 简单的设置好框架 并在index文件中引用

https://uniapp.dcloud.net.cn/tutorial/page.html#componentlifecycle

<template>
	<view>
		<!-- 状态栏 -->
		<view  class="navbar-fixed" ></view>
		<!-- 导航栏 -->
		<view>
           <text>饿了么</text>
    	</view>
	</view>
</template>

<script>
	export default {
		name:"navbar",
		data() {
			return {
                //在这里定义变量 
				//以phone9为准 375px
				//状态栏高度
				statusBarHeight: 20,
				//胶囊高度
				navBarHeight: 45,
				//屏幕宽带
				windowWidth: 375,
			};
		},
        //钩子函数
		created() {
			
		}
	}
</script>

<style lang="scss">
    .navbar-fixed {
        position: fixed;
        z-index: 99;
        background-color: #f8f8f8;}
</style>

index文件引用 和 my order文件中引用

我们得到胶囊的高度和状态栏的高高度 和屏幕宽度 在navbar文件中编写

//获取手机信息
uni.getSystemInfoAsync();
//获取胶囊信息
uni.getMenuButtonBoundingClientRect();
<template>
	<view  class="navbar-fixed" >
		<!-- 状态栏 -->
		<view :style="{height:statusBarHeight+'px'}"></view>
		<!-- 导航栏 -->
		<view class="title" :style="{height:navBarHeight+'px',width:windowWidth+'px',paddingLeft:pad*2+'px'}">
			<text>饿了么</text>
		</view>
	</view>
</template>


<script>
	export default {
		name:"navbar",
		data() {
			return {
				//以phone9为准 375px
				//状态栏高度
				statusBarHeight: 20,
				//导航栏高度
				navBarHeight: 45,
				//屏幕宽带
				windowWidth: 375,
                //距离左边的宽度
				pad:0
			};
		},
        //----------------------新增内容--------------------------
		created() {
			// 在组件被调用的时候获取手机信息
            //从而获取到状态栏高度和屏幕宽度
            // 在小程序开发工具中发现 info是一个 Promise 对象
			const info =uni.getSystemInfoAsync();
			info.then(ret=>{
				console.log( ret);
				//从而进行动态的赋值
				//状态栏高度
				this.statusBarHeight=ret.statusBarHeight;
				//屏幕宽度
				this.windowWidth= ret.windowWidth;
                
           
                //获取胶囊的信息
				const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
				console.log(menuButtonInfo);
                
                	//导航栏的高度  = 胶囊的底部 减去 状态栏的高度 加 胶囊的顶部 减去 状态栏的高度
				this.navBarHeight= (menuButtonInfo.bottom - ret.statusBarHeight) + (menuButtonInfo.top - ret.statusBarHeight);
                // 宽度 -胶囊右边 
				this.pad = ret.windowWidth-menuButtonInfo.right;
				
			});
            
            
	
		}
	}
</script>

<style lang="scss">
	    .navbar-fixed {
	        position: fixed;
	        z-index: 99;
	        background-color: #f6f6f6;
			.title{
				background-color: red;
				// 垂直方向居中
				display: flex;
				align-items: center;
			}
			
		}
</style>

flex不占位置 在index文件中添加 查看现象

<template>
	<view>
		<navbar></navbar>
		<!-- 添加----------------- -->
		<view v-for="(item,index) in 100" :key="index">
			{{ item }}
		</view>
		<!-- 添加----------------- -->
	</view>
</template>

需要增加一个空的盒子在占位

在 navbar文件中修改添加字部分代码

<template>
	<view>

		<view class="navbar-fixed">
			<!-- 状态栏 -->
			<view :style="{height:statusBarHeight+'px'}"></view>
			<!-- 导航栏 -->
			<view class="title" :style="{height:navBarHeight+'px',width:windowWidth+'px',paddingLeft:pad*2+'px'}">
				<text>饿了么</text>
			</view>
		</view>
		
		<!-- -----添加内容------------ -->
		<!-- 空盒子的高度 = 状态栏高度 +导航栏高度 -->
		<view :style="{height:statusBarHeight+navBarHeight+'px'}"></view>
		
	</view>
</template>
问题现象 解决后
image-20230814122622749 image-20230814123145031

不同的导航栏背景颜色是不一样的 我们可以给组件传入不同的值来识别 来实现组件的复用

在 navbar 文件中 添加一下内容

<template>
	<view>
		<view class="navbar-fixed" :class="{change:isBgColor,normal:isBsColor}">
		...
		</view>
		...
	</view>
</template>

<script>
	export default {
		...,
		props: {
			isBgColor: {
				type: Boolean,
				default: false
			},
			isBsColor: {
				type: Boolean,
				default: false
			}
		}
        ...
	}
</script>

<style lang="scss">
	.navbar-fixed {
		position: fixed;
		z-index: 99;
		background-color: #f6f6f6;
		
		//渐变导航栏背景色   & 表示继承
		&.change {
			background: linear-gradient(100deg, blue, yellow);
		}

		.title {
			background-color: red;
			// 垂直方向居中
			display: flex;
			align-items: center;
		}

	}
</style>

在index文件 通过传值来设置不同的样式

<template>
	<view>
		<!-- 添加----------------- -->
		<navbar :isBgColor="true"></navbar>
		<!-- 添加----------------- -->
		<view v-for="(item,index) in 100" :key="index">
			{{ item }}
		</view>

	</view>
</template>
<template>
	<view>

		<view class="navbar-fixed" :class="{change:isBgColor,normal:isBsColor}">
			<!-- 状态栏 -->
			<view :style="{height:statusBarHeight+'px'}"></view>
			<!-- 导航栏 -->
			<view class="title" :style="{height:navBarHeight+'px',width:windowWidth+'px',paddingLeft:pad*2+'px'}">
				<text>饿了么</text>
			</view>
		</view>

		<!-- -----添加内容------------ -->
		<!-- 空盒子的高度 = 状态栏高度 +导航栏高度 -->
		<view :style="{height:statusBarHeight+navBarHeight+'px'}"></view>

	</view>
</template>

<script>
	export default {
		name: "navbar",
		data() {
			return {
				//以phone9为准 375px
				//状态栏高度
				statusBarHeight: 20,
				//导航栏高度
				navBarHeight: 45,
				//屏幕宽带
				windowWidth: 375,
				//距离左边的宽度
				pad: 0
			};
		},
		props: {
			isBgColor: {
				type: Boolean,
				default: false
			},
			isBsColor: {
				type: Boolean,
				default: false
			}
		},
		created() {
			// 在组件被调用的时候获取手机信息
			//从而获取到状态栏高度和屏幕宽度
			const info = uni.getSystemInfo();
			console.log(info);
			info.then(ret => {
				console.log(ret);
				//从而进行动态的赋值
				//状态栏高度
				this.statusBarHeight = ret.statusBarHeight;
				//屏幕宽度
				this.windowWidth = ret.windowWidth;

				//获取胶囊的位子
				const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
				console.log(menuButtonInfo);
				//导航栏的高度  = 胶囊的底部 减去 状态栏的高度 加 胶囊的顶部 减去 状态栏的高度
				this.navBarHeight = (menuButtonInfo.bottom - ret.statusBarHeight) + (menuButtonInfo.top - ret
					.statusBarHeight)
				// 宽度 -胶囊右边 
				this.pad = ret.windowWidth - menuButtonInfo.right;
			});
		}
	}
</script>

<style lang="scss">
	.navbar-fixed {
		position: fixed;
		z-index: 99;
		background-color: #f6f6f6;

		//渐变导航栏背景色   & 表示继承
		&.change {
			background: linear-gradient(72deg,#fce38a,#f38181);
		}

		.title {
			//background-color: red;
			// 垂直方向居中
			display: flex;
			align-items: center;
		}

	}
</style>

章节小结


创建初始模板 链接微信小程序开发工具查看预览 框架文件的目录 组件的生命周期函数 钩子函数

使用tabbar

自定义组件功能 来做复用导航栏 创建compontens 文件夹 创建组件

制作导航栏自适应高度

第2章promise网络请求与mescroll-body分页处理

目标 --完成首页和订单页

首页 订单页

饿了么 文字 有居中 居左 黑色 白色 之分 代码如下

<template>
	<view>

		<view class="navbar-fixed" :class="{change:isBgColor,normal:isBsColor}">
			<!-- 状态栏 -->
			<view :style="{height:statusBarHeight+'px'}"></view>
			<!-- 导航栏 绑定class  blackContenter 黑色居中  blackLeft  黑色居左-->
			<view class="title" :style="{height:navBarHeight+'px',width:windowWidth+'px',paddingLeft:pad*2+'px'}" :class="{blackContenter:isBlackCententer,blackLeft:isBlackLeft}">
				<text>饿了么</text>
			</view>
		</view>

		<!-- -----添加内容------------ -->
		<!-- 空盒子的高度 = 状态栏高度 +导航栏高度 -->
		<view :style="{height:statusBarHeight+navBarHeight+'px'}"></view>

	</view>
</template>

<script>
	export default {
		....
		props: {
			//渐变背景颜色
			isBgColor: {
				type: Boolean,
				default: false
			},
			//默认背景颜色
			isBsColor: {
				type: Boolean,
				default: false
			},
            //添加的内容---------
			//是否为黑色居中
			isBlackCententer: {
				type: Boolean,
				default: false
			},
            //添加的内容---------
			//是否为黑色居左
			isBlackLeft: {
				type: Boolean,
				default: false
			}
		}
		...
	}
</script>

<style lang="scss">
	.navbar-fixed {
		position: fixed;
		z-index: 99;
		background-color: #f6f6f6;
		//渐变导航栏背景色   & 表示继承
		&.change {
			background: linear-gradient(72deg,#fce38a,#f38181);
		}
		.title {
			//background-color: red;
			display: flex;
			// 垂直方向居中
			align-items: center;
			box-sizing: border-box;
            /默认颜色改为白色
			color: #f6f6f6;
			&.blackContenter{
				//水平居中
				justify-content:center;
				//黑色
				color:black;
			}
			&.blackLeft{
				//水平方向居左
				justify-content:space-between;
				color: black;
			}
		}

	}
</style>

在其他页面引入的时候传值 来改变样式

<template>
	<view>
		<navbar :isBgColor="true" :isBlackCententer="true" ></navbar>
		<!-- 或者  -->
		<navbar :isBgColor="true" :isBlackLeft="true" ></navbar>
	</view>
</template>

阿里巴巴图标矢量库使用

https://www.iconfont.cn/

image-20230814144617809

image-20230814144706535 image-20230814144729605

image-20230814145005309

@font-face {
  font-family: "iconfont"; /* Project id 2799536 */
  src: url('https://at.alicdn.com/t/font_2799536_hjz3qdbx65e.eot?t=1638274927473'); /* IE9 */
  src: url('https://at.alicdn.com/t/font_2799536_hjz3qdbx65e.eot?t=1638274927473#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('https://at.alicdn.com/t/font_2799536_hjz3qdbx65e.woff2?t=1638274927473') format('woff2'),
       url('https://at.alicdn.com/t/font_2799536_hjz3qdbx65e.woff?t=1638274927473') format('woff'),
       url('https://at.alicdn.com/t/font_2799536_hjz3qdbx65e.ttf?t=1638274927473') format('truetype'),
       url('https://at.alicdn.com/t/font_2799536_hjz3qdbx65e.svg?t=1638274927473#iconfont') format('svg');
} 

//这里是手动添加的代码 匹配到 chloe- 开头的类就添加下面的代码进入  不用再引入 .iconfont 来显示效果了
[class*="chloe-"]
{
	font-family: "iconfont" !important;
	font-size: 16px;
	font-style: normal;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale; 
}
 


.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}


.chloe-location1:before {
  content: "\e651";
}

.chloe-icon_follow:before {
  content: "\e692";
}

.chloe-location:before {
  content: "\e790";
}

.chloe-right-arrow:before {
  content: "\e629";
}

.chloe-search1:before {
  content: "\e67d";
}

.chloe-location_light:before {
  content: "\e7f3";
}

.chloe-favor:before {
  content: "\e619";
}

.chloe-back:before {
  content: "\e697";
}

.chloe-more:before {
  content: "\e6ad";
}

.chloe-search:before {
  content: "\e7b3";
}

创建common\iconfont\iconfont.css目录

将上面这段代码放入 css文件中


在app.vue文件中引入公共样式

<style>
	/*每个页面公共css */
	/* 引入对应页面使用绝对定位 */
	@import url("/common/iconfont/iconfont.css");
	page{
		background-color: #f8f8f8;
	}
	
</style>

image-20230814151501301

游客模式受限

https://blog.csdn.net/Daears/article/details/127529603

位置信息 小程序开发工具里面无法获取的话 可以使用一下方式来查看

image-20230814160201401

1-顶部位置选择代码实现

index文件中代码

定义变量 location 绑定 getLocation 函数来获取定位信息并修改 location=当前位置

uni.chooseLocation函数在小程序开发工具中无法获取位置信息 可使用上面的方式来实现

<template>
	<view>
		<navbar :isBgColor="true" :isBlackCententer="true"></navbar>

		<view class="container">
			<view class="box">

				<!-- 定位盒子 -->
				<view class="location-box">
					<!-- 点击后进入位置选择页面  绑定点击事件-->
					<view class="address-box" @click="getLocation">
						<!-- 位置图片 -->
						<i class="chloe-location "></i>
						<!-- 位置信息 使用一个变量 -->
						<text>{{ location }}</text>
						<!-- 图标 -->
						<i class="chloe-right-arrow "></i>
					</view>
					<view class="adText">
						<text>美食果蔬医药30分钟送达</text>
					</view>
				</view>


			</view>
		</view>

	</view>
</template>

<script>
	export default {
		data() {
			return {
				location: "请选择您的位置",
			};
		},
		onShow() {
			// console.log('index onshow');
		},
		// 爱methods里面添加绑定的事件
		methods: {
			getLocation() {
				//console.log('123456');
				uni.chooseLocation({
                    //这里要使用箭头函数 要不然无法修改 this.location 会改变this的指向
					success: (res)=> {
						console.log(res.name);
						this.location = res.name
					}
				});
			}
		}
	}
</script>

<style lang="scss">
	.container {
		background: linear-gradient(72deg, #fce38a, #f38181);

		.box {
			background: #f8f8f8;
			border-top-left-radius: 50rpx;
			border-top-right-radius: 50rpx;
			padding: 10rpx 20rpx;


		}

		.location-box {
			display: flex;
			flex-direction: row;
			color: #333333;
			justify-content: space-between;
			align-items: center;


			.address-box {
				display: flex;
				flex-direction: row;
				align-items: center;
				justify-content: center;

				text {
					flex: 1;
					flex-wrap: nowrap;
					overflow: hidden;
					display: -webkit-box;
					-webkit-box-orient: vertical;
					-webkit-line-clamp: 1;
					text-overflow: ellipsis;
					font-size: 28rpx;
					margin-left: 2px;
					margin-right: 4px;
					font-weight: 900;
				}

				.chloe-right-arrow,
				.chloe-location {
					line-height: 0.88;
				}

				.chloe-right-arrow {
					font-size: 18rpx;
					color: #a2a2a2;
					margin-right: 14px;
				}
			}

			.adText {
				font-size: 22rpx;
				color: #a2a2a2;
				flex-shrink: 0;

			}
		}


	}
</style>

2-搜索框实现

image-20230814162526616

uni.scss 文件中添加

/* 颜色变量 */
$base-color:#00aaff;
$color-light:#00d5ff;

index 文件中添加 **搜索框盒子 ** **热搜榜 **内容并修改css样式 和 添加 hotList变量数据

 
<template>
	<view>
		<navbar :isBgColor="true" :isBlackCententer="true"></navbar>

		<view class="container">
			<view class="box">

				<!-- 定位盒子 -->
                <!-- *****  -->
				<!-- 搜索框盒子 -->
				<view class="search-box">
					<view class="ctn">
						<view class="chloe-search-box">
							<view class="chloe-search-text">
								<uni-icons type="search" size="22" color="#666666" />
								<text>鲜果大咖水果捞 20减12</text>
							</view>
							<view>
								<button class="search-txt">搜索</button>
							</view>
						</view>
					</view>
				</view>

				<!-- 热搜榜 -->
				<view class="hot-box">
					<view class="item" v-for="(item,index) in hotList" :key="index">
						{{item}}
					</view>
				</view>


			</view>
		</view>

	</view>
</template>

<script>
	export default {
		data() {
			return {
				location: "请选择您的位置",
				hotList: [
					'酸奶水果捞',
					'鸭血粉丝汤',
					'炒米线',
					'红烧排骨',
					'减脂餐'
				],
			};
		}
   
	}
</script>

<style lang="scss">
	.container {
		background: linear-gradient(72deg, #fce38a, #f38181);

		.box {
			background: #f8f8f8;
			border-top-left-radius: 50rpx;
			border-top-right-radius: 50rpx;
			padding: 10rpx 20rpx;


		}

		.location-box {
			display: flex;
			flex-direction: row;
			color: #333333;
			justify-content: space-between;
			align-items: center;


			.address-box {
				display: flex;
				flex-direction: row;
				align-items: center;
				justify-content: center;

				text {
					flex: 1;
					flex-wrap: nowrap;
					overflow: hidden;
					display: -webkit-box;
					-webkit-box-orient: vertical;
					-webkit-line-clamp: 1;
					text-overflow: ellipsis;
					font-size: 28rpx;
					margin-left: 2px;
					margin-right: 4px;
					font-weight: 900;
				}

				.chloe-right-arrow,
				.chloe-location {
					line-height: 0.88;
				}

				.chloe-right-arrow {
					font-size: 18rpx;
					color: #a2a2a2;
					margin-right: 14px;
				}
			}

			.adText {
				font-size: 22rpx;
				color: #a2a2a2;
				flex-shrink: 0;

			}
		}


		.search-box {
			position: sticky;
			z-index: 2;

			.ctn {
				background: #f8f8f8;
				padding-top: 20px;

				.chloe-search-box {
					border-radius: 40px;
					border: 1px solid $base-color;
					display: flex;
					flex-direction: row;
					justify-content: space-between;
					align-items: center;
					color: #a2a2a2;
					font-size: 26rpx;

					.chloe-search-text {
						padding-left: 10px;

						text {
							margin-left: 2px;
							margin-right: 4px;
						}
					}

					.search-txt {
						border-radius: 40px;
						color: #FFFFFF;
						font-size: 14px;
						width: 65px;
						background-color: $base-color;


					}
				}
			}
		}

.hot-box {
			display: flex;
			flex-direction: row;
			flex-wrap: wrap;
			padding: 10px 0;
			justify-content: flex-start;

			.item {
				margin-right: 12px;
				background-color: rgba(207, 210, 221, 0.2);
				// background-color: #EEEEEE;
				color: #666666;
				font-size: 20rpx;
				border-radius: 20px;

				padding: 2px 6px;
				// margin-bottom: 8px;
			}

			.item:last-child {
				margin-right: 0;
			}
		}

	}
</style>

封装自己的promise网络请求

创建文件目录 api/api.js

代码

// 封装自己的promise网络请求 Promise ES6 是异步编程的一种解决方案 
//Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。resolve reject
//设置url  没有的话会后端的自己用数据库搭一个
const  BASE_URL = 'https://wechat.ouyangke.net/';
//export 为导出
export  const myRequest = (options) => {
	// 这里用到了解构赋值
	const {
		url,
		method,
		data,
		timeout
	} = options

	return new Promise((resolve, reject) => {
		uni.request({
			url: BASE_URL + url,
			method: method || 'get',
			data: data || {},
			timeout: timeout || 5000,
			//使用箭头函数 解决this指向问题
			success: (res) => {
				if (res.statusCode !== 200) {
					uni.showToast({
						title: '请求数据失败',
						duration: 1000,
						icon: 'none'
					})
				}
				resolve(res);
			},
			fail: (err)=> {
				uni.showToast({
					title: '请求接口失败',
					duration: 1000,
					icon: 'none'
				});
				reject(err);
			}
		})
	})
}

在 main.js文件中引入 让全局可以使用

import App from './App'
//---------------添加代码
import {myRequest} from './api/api.js';

// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
//---------------添加代码  
Vue.prototype.$myRequest =  myRequest

请求返回的数据格式

image-20230814172400199

3-轮播的实现 和请求数据

inde文件里面的代码

<template>
	<view>
		<navbar :isBgColor="true" :isBlackCententer="true"></navbar>
		<view class="container">
			<view class="box">
				<!-- .... -->
				<!-- 菜单盒子 -->
				<view class="menu-box">
					<view class="item-box" v-for="menu in menuList" :key="menu.id">
						<view class="image-area" :class="{smail:menu.small == 0}">
							<image :src="menu.img"></image>
						</view>
						<view class="tit">
							{{menu.name}}
						</view>
					</view>

				</view>

				<!-- 轮播 -->
				<view class="banner-box">
					<swiper circular :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000"
						class="swiper-box">
						<swiper-item v-for="(item,index) in swiperList" :key="index">

							<view class="swiper-item">
								<image :src="item.src" mode=""></image>
							</view>

						</swiper-item>

					</swiper>
				</view>

			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				//banner列表
				swiperList: [{
						src: '/static/img/index/banner/1.jpg'
					},
					{
						src: '/static/img/index/banner/2.jpg'
					},
					{
						src: '/static/img/index/banner/3.jpg'
					}
				],
				location: "请选择您的位置",
                //热搜列表
				hotList: [
					'酸奶水果捞',
					'鸭血粉丝汤',
					'炒米线',
					'红烧排骨',
					'减脂餐'
				],
                //商户列表
				menuList: [],
			};
		},
		onLoad() {
			//加载商铺类目信息
			this.getmenuList();
		},
		onShow() {
			// console.log('index onshow');
		},
		// 爱methods里面添加绑定的事件
		methods: {
			getLocation() {
				//console.log('123456');
				uni.chooseLocation({
					success: (res) => {
						console.log(res.name);
						this.location = res.name
					}
				});
			},
			//获取商铺信息的方法
			async getmenuList() {
				const res = await this.$myRequest({
					url: 'getmenuList'
				})
				const {
					data
				} = res
				console.log(data);
				this.menuList = data;

			}
		}
	}
</script>

<style lang="scss">
	.container {
		//添加部分样式
		//商户按钮样式
		.menu-box {
			display: flex;
			flex-direction: row;
			justify-content: space-between;
			margin-top: 12px;
			flex-wrap: wrap;

			.item-box {
				flex: 20%;
				display: flex;
				flex-direction: column;
				justify-content: center;
				align-items: center;
				padding: 5px 0;

				.image-area {
					width: 40px;
					height: 40px;


					&.small {
						width: 25px;
						height: 25px;
					}

					image {
						flex-shrink: 0;
						width: 100%;
						height: 100%;
					}
				}


				.tit {
					display: flex;
					justify-content: center;
					align-items: center;
					font-size: 12px;
					margin-top: 6px;
					color: #333333;
					padding: 2px 0;
					white-space: nowrap;
					overflow: hidden;
					text-overflow: ellipsis;
				}

				.active {
					color: #ffffff;
					background-color: #999999;
					border-radius: 60px;
				}
			}
		}
		
		// banner样式
		.banner-box {
			padding: 24rpx;

			.swiper-box {
				height: 165rpx;
			}

			.swiper-item {

				display: flex;
				justify-content: center;
				align-content: center;
				height: 100%;

				image {
					border-radius: 10px;
					width: 100%;
					height: 100%;
					flex-shrink: 0;

				}
			}
		}
	}
</style>

4-实现mescroll-body分页处理

官方文档 https://www.mescroll.com/uni.html

下载安装 下单文件里面有官方的案例

image-20230815183317448 image-20230815183330807
image-20230815183455315

image-20230815183859052

解压后这个文件夹 移动到这个文件夹
image-20230815183925622 image-20230815184100019

商户信息

image-20230815193118857

章节小结


通过传入对应的 对象 赋值 来改变样式

uni.chooseLocation 来获取位置信息 模拟器中无法获取位置信息解决方案

promise 封装自己的函数对象 引入到全局使用 使用封装的请求来获取信息 swiper 轮播组件

posted on 2023-10-14 00:59  xirang熙攘  阅读(342)  评论(0编辑  收藏  举报