1.编写准备
pages文件夹下存放着小程序所有的业务页面;
index文件夹就是一个页面,index.wxml是页面的结构文件,类似html。
index.wxss是页面的样式,其实就是css;index.js是页面的逻辑,数据请求与渲染都是都在这个页面完成。
logs文件夹存放着小程序开发日志,目前暂时用不到。
utils.js可以编写自己的JavaScript插件。
app.js处理全局的一些逻辑,比如定义全局变量存放获取的用户信息,这样每个页面都可以获取用户信息。
app.json 是全局配置文件,比如设置标题栏的背景色等。
app.wxss 存放页面的公共样式,如果多个页面需要用到同一样式,就可以写在这里。
项目按钮显示预览二维码,用于真机调试。必须真机调试测试代码
1.创建页面结构
上一节已经分析了默认的文件结构以及它们的功能,现在我们要创建ofo小程序所需要的页面。
1.删除pages下默认的index文件夹,logs/utils文件夹可选择性删除
2.在与pages同级目录下创建images文件夹,存放页面需要用到的图标,https://pan.baidu.com/s/1b7g8KQ
3.本小程序不需要在app.js里面编写内容,可以注释这里面的代码
4.在app.json里,删掉默认代码,编写如下代码(app.json文件里不能有任何注释,这里是为了描述页面功能更直观):
{ "pages":[ "pages/index/index", // 地图页 "pages/warn/index", // 车辆报障页 "pages/scanresult/index", // 扫码成功页 "pages/billing/index", // 开始计费页 "pages/my/index", // 账户页 "pages/wallet/index", // 钱包页 "pages/charge/index", // 充值页 "pages/logs/logs" // 日志页 ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#b9dd08", // 标题栏背景色 "navigationBarTitleText": "ofo 共享单车", // 标题栏文字 "navigationBarTextStyle":"black" // 标题栏文字样式 } }
5.app.wxss是通用样式,先添加几个通用样式,以后用得到:
/**app.wxss**/ .container{ background-color: #f2f2f2; height: 100vh; } .title{ background-color: #f2f2f2; padding: 30rpx 0 30rpx 50rpx; font-size: 28rpx; color: #000; } .tapbar{ display: flex; align-items: center; justify-content: space-between; background-color: #fff; padding: 40rpx; } .btn-charge{ width: 90%; background-color: #b9dd08; margin: 40rpx auto 30rpx; text-align: center; }
保存后,你的pages文件夹下就是这样的界面了(在app.json下创建路径会自动创建文件夹,贼方便)
2.编写地图首页 (index文件夹)
页面分析:
1.整页显示地图,宽高占手机窗口的100%;2.地图之上有五个按钮图标和多个黄色ofo标记:定位按钮,立即用车按钮,举报按钮,黄色头像按钮和位于地图中心的标记。
2.1 要在整页显示地图,我们可以在index.wxml引入地图组件:
<!--index.wxml--> <view class="container"> <map id="ofoMap" latitude="{{latitude}}" // 纬度 longitude="{{longitude}}" // 经度 scale="{{scale}}" // 缩放级别 show-location/> // 显示带有方向的小圆点 </view>{{...}} 里面是数据变量,由js里的data对象定义。
2.2 初始化数据,在index.js的data对象里添加如下代码:
//index.js Page({ data: { scale: 18, // 缩放级别,默认18,数值在0~18之间 latitude: 0, // 给个默认值 longitude: 0 // 给个默认值 }, onLoad:function(options){ // 页面初始化 options为页面跳转所带来的参数 }, onReady:function(){ // 页面渲染完成 }, onShow:function(){ // 页面显示 }, onHide:function(){ // 页面隐藏 }, onUnload:function(){ // 页面关闭 }这样我们的地图就默认中心位置为经度 0,纬度0。当然可能在开发者工具里显示不出来,莫慌!这不是我们想要的,我们想要的是我们自己的位置,所以得先获取我们当前所在位置的经纬度,在index.js里的onLoad方法里添加如下代码:
onLoad: function(options){ // 页面初始化 options为页面跳转所带来的参数 // 调用wx.getLocation系统API,获取并设置当前位置经纬度 wx.getLocation({ type: "gcj02", // 坐标系类型 // 获取经纬度成功回调 success: (res) => { // es6 箭头函数,可以解绑当前作用域的this指向,使得下面的this可以绑定到Page对象 this.setData({ // 为data对象里定义的经纬度默认值设置成获取到的真实经纬度,这样就可以在地图上显示我们的真实位置 longitude: res.longitude, latitude: res.latitude }) } }); }res是一个数据对象,它是由调用的对应API传过来的,如果你想知道res的具体值,可以在成功回调函数里打印,然后在控制台输出:console.log(res)。在调用一个陌生API的时候可以用这种方法查看返回的对象数据,对处理逻辑很有帮助。
我们在地图上显示了我们的真实位置,但没有移动到中心位置,wx.moveToLocation()函数可以把当前位置移动到地图中心。修改index.js:
//index.js var app = getApp() Page({ data: { scale: 18, latitude: 0, longitude: 0 },// 页面加载 onLoad: function(options){ // 1.页面初始化 options为页面跳转所带来的参数 // 2.调用wx.getLocation系统API, latitude: res.latitude }) } }); } // 页面显示 onShow: function(){ // 1.创建地图上下文,移动当前位置到地图中心 this.mapCtx = wx.createMapContext("ofoMap"); // 地图组件的id this.movetoPosition() },// 定位函数,移动位置到地图中心 movetoPosition: function(){ this.mapCtx.moveToLocation(); } })这样,页面一显示就在地图中心显示当前位置。
2.3 满屏显示地图,在index.wxss里编写样式:
/**index.wxss**/ .container{ position: relative; width: 100%; // 宽度占满设备 height: 100vh; // 高度占满设备 } #ofoMap{ position: absolute; left: 0; top: 0; right: 0; bottom: 0; width: 100%; height: 100%; z-index: 1; }保存刷新,整个屏幕就都显示地图了>_<
2.4 添加地图上的按钮
其实这里的按钮不是真正的按钮,它们属于地图上的控件属性,并且不随着地图移动。这里有一个坑:
地图组件属于微信原生组件,层级最高,任何元素都不能在地图之上显示,即无论设置多大z-index都无法显示。所以,要想在地图上添加按钮来满足需求,就要用到地图控件属性。更多地图控件属性说明看这里
要添加地图控件,先在地图组件里声明controls="...":
<!--index.wxml--> <view class="container"> <map id="ofoMap" latitude="{{latitude}}" // 纬度 longitude="{{longitude}}" // 经度 scale="{{scale}}" // 缩放级别 controls="{{controls}}" // 地图控件数组,多个控件存放在数组里 show-location/> // 显示带有方向的小圆点 </view>然后在index.js设置controls(代码注释还是挺多的)
//index.js var app = getApp() Page({ data: { scale: 18,获取并设置当前位置经纬度 ...已省略 // 3.设置地图控件的位置及大小,通过设备宽高定位 wx.getSystemInfo({ // 系统API,获取系统信息,比如设备宽高 success: (res) => { this.setData({ // 定义控件数组,可以在data对象初始化为[],也可以不初始化,取决于是否需要更好的阅读 controls: [{ id: 1, // 给控件定义唯一id iconPath: '/images/location.png', // 控件图标 position: { // 控件位置 left: 20, // 单位px top: res.windowHeight - 80, // 根据设备高度设置top值,可以做到在不同设备上效果一致 width: 50, // 控件宽度/px height: 50 // 控件高度/px }, clickable: true // 是否可点击,默认为true,可点击 }, { id: 2, iconPath: '/images/use.png', position: { left: res.windowWidth/2 - 45, top: res.windowHeight - 100, width: 90, height: 90 }, clickable: true }, { id: 3, iconPath: '/images/warn.png', position: { left: res.windowWidth - 70, top: res.windowHeight - 80, width: 50, height: 50 }, { id: 4, iconPath: '/images/marker.png', position: { left: res.windowWidth/2 - 11, top: res.windowHeight/2 - 45, width: 22, height: 45 }, clickable: false }, { id: 5, iconPath: '/images/avatar.png', position: { left: res.windowWidth - 68, top: res.windowHeight - 155, width: 45, clickable: true }] }) } }); } // 页面显示 onShow: function(){ ... },// 定位函数,移动位置到地图中心 movetoPosition: function(){ this.mapCtx.moveToLocation(); } })2.5 为地图控件绑定事件
现在地图上总共有四个图标可点击(地图中心的标记控件不需要点击),我们需要为每个控件绑定不同的事件以实现不同的功能:
1.点击定位控件,触发定位当前位置到地图中心,因为用户在拖动地图,有时需要查看当前所在位置。
2.点击立即用车控件,调用微信内置扫码功能。然后获取开锁密码。
3.点击举报按钮,前往维修报障页面。
4.点击用户头像按钮,前往登录页面进行登录,查看余额,充值等操作
为控件绑定事件,需要在地图控件进行声明:bindcontroltap
<!--index.wxml--> <view class="container"> <map id="ofoMap" latitude="{{latitude}}" // 纬度 longitude="{{longitude}}" // 经度 scale="{{scale}}" // 缩放级别 controls="{{controls}}" // 地图控件数组,多个控件存放在数组里 bindcontroltap="bindcontroltap" // 控件点击事件 show-location/> // 显示带有方向的小圆点 </view>注意: bindcontroltap事件会响应所有控件的点击,所以,我们需要根据控件id来区分控件,然后响应不同的事件。
在index.js添加bindcontroltap事件:
//index.js var app = getApp() Page({ data: { scale: 18,// 页面加载 onLoad: function(options){ // 1.获取定时器,用于判断是否已经在计费 this.timer = options.timer; // 2.调用wx.getLocation系统API,获取并设置当前位置经纬度 ...已省略 // 3.设置地图控件的位置及大小,通过设备宽高定位 ...已省略 } // 地图控件点击事件 bindcontroltap: function(e){ // 判断点击的是哪个控件 e.controlId代表控件的id,在页面加载时的第3步设置的id switch(e.controlId){ // 点击定位控件 case 1: this.movetoPosition(); break; // 点击立即用车,判断当前是否正在计费,此处只需要知道是调用扫码,后面会讲到this.timer是怎么来的 case 2: if(this.timer === "" || this.timer === undefined){ // 没有在计费就扫码 wx.scanCode({ success: (res) => { // 正在获取密码通知 wx.showLoading({ title: '正在获取密码', mask: true }) // 请求服务器获取密码和车号 wx.request({ url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/password', data: {}, method: 'GET', success: function(res){ // 请求密码成功隐藏等待框 wx.hideLoading(); // 携带密码和车号跳转到密码页 wx.redirectTo({ url: '../scanresult/index?password=' + res.data.data.password + '&number=' + res.data.data.number, success: function(res){ wx.showToast({ title: '获取密码成功', duration: 1000 }) } }) } }) } }) // 当前已经在计费就回退到计费页 }else{ wx.navigateBack({ delta: 1 }) } break; // 点击保障控件,跳转到报障页 case 3: wx.navigateTo({ url: '../warn/index' }); break; // 点击头像控件,跳转到个人中心 case 5: wx.navigateTo({ url: '../my/index' }); break; default: break; } },// 页面显示 onShow: function(){ ...已省略 },// 定位函数,移动位置到地图中心 movetoPosition: function(){ this.mapCtx.moveToLocation(); } })这里用到的API:扫码API: wx.scanCode({})显示加载框: wx.showLoading()隐藏加载框: wx.hideLoading()显示提示框: wx.showToast()隐藏提示框: wx.hideToast()向服务器发送请求:wx.request({})关闭当前页面,跳转到指定页面: wx.redirectTo({})保留当前页面,跳转到指定页面: wx.navigateTo({})回退到指定页面: wx.naivgateBack({})
2.6 在地图上添加单车标记makers和位置连线,还是在地图组件里先声明:
<!--index.wxml--> <view class="container"> <map id="ofoMap" latitude="{{latitude}}" // 纬度 longitude="{{longitude}}" // 经度 scale="{{scale}}" // 缩放级别 controls="{{controls}}" // 地图控件数组,多个控件存放在数组里 bindcontroltap="bindcontroltap" // 控件点击事件 polyline="{{polyline}}" // 位置连线 markers="{{markers}}" // 标记数组 bindmarkertap="bindmarkertap" // 标记点击事件 show-location/> // 显示带有方向的小圆点 </view>然后在index.js里定义:
//index.js var app = getApp() Page({ data: { scale: 18,获取并设置当前位置经纬度 ...已省略 // 3.设置地图控件的位置及大小,通过设备宽高定位 ...已省略 // 4.请求服务器,显示附近的单车,用marker标记 wx.request({ url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/biyclePosition', data: {}, method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT // header: {}, // 设置请求的 header success: (res) => { this.setData({ markers: res.data.data }) } }) } // 地图控件点击事件 bindcontroltap: function(e){ ...已省略 },// 地图标记点击事件,连接用户位置和点击的单车位置 bindmarkertap: function(e){ let _markers = this.data.markers; // 拿到标记数组 let markerId = e.markerId; // 获取点击的标记id let currMaker = _markers[markerId]; // 通过id,获取当前点击的标记 this.setData({ polyline: [{ points: [{ // 连线起点 longitude: this.data.longitude, latitude: this.data.latitude }, { // 连线终点(当前点击的标记) longitude: currMaker.longitude, latitude: currMaker.latitude }], color:"#FF0000DD", width: 1, dottedLine: true }], scale: 18 }) },// 定位函数,移动位置到地图中心 movetoPosition: function(){ this.mapCtx.moveToLocation(); } })2.7 用户拖动地图事件
我们已经为地图控件和标记响应了不同的事件,现在如果用户拖动地图,我们需要在拖动附件显示单车,在地图组件声明地图拖动事件:
<!--index.wxml--> <view class="container"> <map id="ofoMap" latitude="{{latitude}}" // 纬度 longitude="{{longitude}}" // 经度 scale="{{scale}}" // 缩放级别 controls="{{controls}}" // 地图控件数组,多个控件存放在数组里 bindcontroltap="bindcontroltap" // 控件点击事件 polyline="{{polyline}}" // 位置连线 markers="{{markers}}" // 标记数组 bindmarkertap="bindmarkertap" // 标记点击事件 bindregionchange="bindregionchange" // 拖动地图事件 show-location/> // 显示带有方向的小圆点 </view>在index.js里实现这个事件方法:
//index.js var app = getApp() Page({ data: { scale: 18, latitude: 0, longitude: 0 },// 页面加载 onLoad: function(options){ // 1.获取定时器,用于判断是否已经在计费 this.timer = options.timer; // 2.调用wx.getLocation系统API,获取并设置当前位置经纬度 ...已省略 // 3.设置地图控件的位置及大小,通过设备宽高定位 ...已省略 // 4.请求服务器,显示附近的单车,用marker标记 ...已省略 } // 地图控件点击事件 bindcontroltap: function(e){ ...已省略 },// 地图视野改变事件 bindregionchange: function(e){ // 拖动地图,获取附件单车位置 if(e.type == "begin"){ wx.request({ url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/biyclePosition', data: {}, method: 'GET', success: (res) => { this.setData({ _markers: res.data.data }) } }) // 停止拖动,显示单车位置 }else if(e.type == "end"){ this.setData({ markers: this.data._markers }) } },// 地图标记点击事件,连接用户位置和点击的单车位置 bindmarkertap: function(e){ ...已省略 },// 页面显示 onShow: function(){ ...已省略 },// 定位函数,移动位置到地图中心 movetoPosition: function(){ this.mapCtx.moveToLocation(); } })
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。