SaaS场快订首页的前端搭建【持续更新】
文章目录
- 一、创建页面
- 二、配置路由
- 三、写接口文件(api)
- 1.定位的接口函数(腾讯地图api)
- 实现代码:
- 2.获取场馆分类的数据
- 3.获取附近场馆列表的数据
- 四、开发首页页面
- 1.顶部区域
- 2.搜索框
- 3.场馆分类
- 4.附近场馆列表
- 五、难点介绍
- 1.实时定位功能的实现
- 思路:
- 核心逻辑:
- 1)优先获取精准定位:
- 2)缓存机制:
- 3)降级策略:
- 4)交互反馈:
- 实现代码:
- 2.场馆分类组件的实现
- 思路:
- 实现代码:
- 3.附近场馆列表组件的实现
- 思路:
- 实现代码:
- 4.分页加载
- 思路:
- 1)初始化状态
- 2)首屏数据加载
- 3)滚动监听触发
- 4)分页请求处理
- 5)边界状态管理
- 核心逻辑:
- 1)数据结构设计:
- 2)核心触发机制:
- 3)细节:
- 4)分页加载流程图
- 实现代码:
- 监听用户滑动到底部
- 请求下一页的数据:
- 5.提升用户体验
- 1)骨架屏:
- 2)回到顶部:
- 3)错误提示:
- 6.样式与交互设计
- 六、思路和建议
- 项目说明和其他介绍:
一、创建页面
在pages文件夹下创建index文件夹,下面添加index.vue页面。
二、配置路由
在pages.json中配置首页的信息
{ "path": "pages/index/index", "style": { // "navigationBarTitleText": "", "navigationBarTitleText": "体育馆预约系统", "enablePullDownRefresh": false, // 网站类型 "navigationStyle": "custom" } },
三、写接口文件(api)
本项目的首页需要写关于以下几个方面的接口函数
1.定位的接口函数(腾讯地图api)
这里我根据腾讯位置服务中提供的一些接口,编写地址的请求函数,主要是IP定位和逆地址解析。
官方文档:
IP定位API文档:
https://lbs.qq.com/service/webService/webServiceGuide/position/webServiceIp
逆地址解析API文档:
https://lbs.qq.com/service/webService/webServiceGuide/address/Gcoder
实现代码:
//IP定位 const IP = '111.206.145.41'; const API_KEY = '你的key'; export function getLocationByIP(a) { a.$jsonp("https://apis.map.qq.com/ws/geocoder/v1/ip", { key: API_KEY, output: 'jsonp', // ip: IP, //要把这个ip这一行注释掉 // location: '31.973929,119.756208',//可以通过uni.getLocation获取,谷歌浏览器会对定位请求清除,有时候定位准,有时候定位不准会出现初始地址甘肃省,但项目发布上https就行了,不准的时候用其他浏览器测试 // location: '33.67,119.28', get_poi: '0' }).then(resp => { let res = resp; console.log(JSON.stringify(resp)); let a = resp.result.ad_info; console.log(JSON.stringify(a)); }) }
//逆地址解析 export async function reverseGeocoding(that, latitude, longitude) { try { const resp = await that.$jsonp("https://apis.map.qq.com/ws/geocoder/v1", { key: API_KEY, output: 'jsonp', location: `${latitude},${longitude}`, get_poi: '0' }); return resp.result.formatted_addresses.recommend; // 明确返回 recommend } catch (error) { console.log("报错啦"); console.error('根据经纬度逆地址解析失败:', error); throw error; // 重新抛出错误 } }
2.获取场馆分类的数据
export function getVenueTypes(keyword) { return httpRequest.request({ url: '接口地址', method: 'GET', params: keyword }) }
3.获取附近场馆列表的数据
// 获取场馆列表 export function getVenueList(venueListReqDTO) { return httpRequest.request({ url: '接口地址', method: 'post', data: venueListReqDTO }) }
四、开发首页页面
1.顶部区域
实时定位,icon小图标
2.搜索框
3.场馆分类
场馆分类的组件(基础实现和改进版本)
基础版(使用u-scroll-list横向滚动列表):
改进版(使用swiper实现滑动翻页):
4.附近场馆列表
场馆列表的组件(该组件也可以在查询页面的场馆列表渲染时复用)
五、难点介绍
1.实时定位功能的实现
思路:
开发者需要在腾讯位置服务先注册一个账号,然后选择你想要的地图相关功能,为这个功能分配一定的额度,个人开发者每天都有一定量的免费的额度,自己使用是足够的了。下面是腾讯位置服务官网:
https://lbs.qq.com/location/
核心逻辑:
1)优先获取精准定位:
这个项目主要使用了IP定位和逆地址解析两个服务,或者为了更快获取经纬度信息,还可以使用uni.getLocation获取经纬度,这是uniapp的内置方法。成功获取经纬度后,通过腾讯位置服务提供的逆地址解析功能,把经纬度信息解析为具体的地址,并显示在页面顶部的定位栏中。
2)缓存机制:
定位信息这里,还采用了缓存机制,将定位结果(经纬度)
在哪里查看缓存呢?如下图所示,点击应用程序,再展开本地存储,就可以看到你的位置信息已经缓存起来了,这样可以在你接下来再来访问这个页面的时候不用重新定位了,毕竟定位也需要重复请求花费一定的时间和额度。
代码中还实现了基于用户名的隔离缓存策略(避免多账号冲突)
3)降级策略:
若用户拒绝定位权限,尝试通过 IP 定位获取大致位置。
4)交互反馈:
定位过程中显示“定位中…”,成功/失败后更新地址栏,点击地址栏可清空缓存重新定位。
实现代码:
async getLocation() { this.isLocating = true; // 开始定位,设置状态为定位中 try { const res = await new Promise((resolve, reject) => { uni.getLocation({ type: 'wgs84', success: (res) => { resolve(res); }, fail: (err) => { reject(err); } }); }); this.locationInfo = { latitude: res.latitude, longitude: res.longitude, }; console.log('当前位置的纬度:', res.latitude); console.log('当前位置的经度:', res.longitude); // 调用逆地址解析函数 try { const recommend = await reverseGeocoding(this, res.latitude, res.longitude); // 更新推荐地址 this.recommend = recommend; // 存储到缓存 const userName = uni.getStorageSync('curUser').userName; // console.log("userName:" + JSON.stringify(userName)); const cacheKey = `location_${userName}`; let location = { latitude: res.latitude, longitude: res.longitude, recommend: recommend }; console.log("location:" + JSON.stringify(location)); uni.setStorageSync(cacheKey, location); console.log("逆地址解析成功,缓存键:", cacheKey); } catch (error) { console.error('逆地址解析失败:', error); uni.showToast({ title: '逆地址解析失败', icon: 'none' }); } } catch (err) { console.error('获取位置失败,尝试通过 IP 获取', err); try { const location = await getLocation(); if (location) { this.locationInfo = { latitude: location.lat, longitude: location.lng }; console.log('通过 IP 获取的位置 - 纬度:', location.lat); console.log('通过 IP 获取的位置 - 经度:', location.lng); } else { uni.showToast({ title: '通过 IP 获取位置失败', icon: 'none' }); } } catch (ipErr) { console.error('通过 IP 获取位置失败', ipErr); // uni.showToast({ // title: '获取位置失败', // icon: 'none' // }); } } finally { this.isLocating = false; // 定位结束,无论成功与否,都设置状态为定位结束 } },
2.场馆分类组件的实现
思路:
可以使用u-scroll-list横向滚动列表:
https://uviewui.com/components/scrollList.html#api
改进版使用swiper:
https://uniapp.dcloud.net.cn/component/swiper.html
实现代码:
{{item.value}}
{{item.value}}
3.附近场馆列表组件的实现
思路:
1)将场馆列表单独封装成组件,通过props接收数据。
2)用户体验:通过图片懒加载、文字截断处理(省略号)、开放时间分开显示等美化组件的布局,提升用户体验。
实现代码:
- 项目说明和其他介绍: