从0开始 UNI-APP开发(仿饿了么)
项目介绍及工具下载
1-工具下载
uniapp官方文档
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框架基础与饿了么首页布局
创建空白项目
默认模板框架目录
查看和预览效果
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
}
}
.....
],
目标样式
![]() |
![]() |
![]() |
---|---|---|
目标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 | ![]() |
||
---|---|---|---|
会在pages.json文件中自动注册 | |||
2-在刚新建tabbar目录下面新建三个页面 分别对应为 我的 首页 和订单 三个功能 index order my |
![]() |
![]() |
![]() |
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": "订单"
}]
}
目标2 -顶部效果
默认的标题是居中 我们想让它在左边 就用定义导航来做
通过观察 顶部为通用的部分 不同的页面都会用到 我们用组件来做
设置自定义导航
pages.json文件中设置 沉浸式导航栏 设置后原来的导航就会消失
//全局设置
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "饿了么",
"navigationBarBackgroundColor": "#fff",
//下拉刷新的时候的设置
"backgroundColor": "#666",
//设置该选项
"navigationStyle": "custom"
},
1-在项目中创建 components 目录
2-在目录下面新建组件 - 这样创建后的可以直接在页面中调用
新建组件 | 新建一个navbar的组件 |
---|---|
![]() |
![]() |
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>
问题现象 | 解决后 |
---|---|
![]() |
![]() |
不同的导航栏背景颜色是不一样的 我们可以给组件传入不同的值来识别 来实现组件的复用
在 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>
navbar文件最终代码
<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>
阿里巴巴图标矢量库使用
![]() |
![]() |
@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>
游客模式受限
https://blog.csdn.net/Daears/article/details/127529603
位置信息 小程序开发工具里面无法获取的话 可以使用一下方式来查看
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-搜索框实现
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
请求返回的数据格式
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
下载安装 下单文件里面有官方的案例
![]() |
![]() |

解压后这个文件夹 | 移动到这个文件夹 |
---|---|
![]() |
![]() |
商户信息
章节小结
通过传入对应的 对象 赋值 来改变样式
uni.chooseLocation 来获取位置信息 模拟器中无法获取位置信息解决方案
promise 封装自己的函数对象 引入到全局使用 使用封装的请求来获取信息 swiper 轮播组件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!