尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

UniApp实战:微信小程序旅行指南开发全记录

UniApp实战:微信小程序旅行指南开发全记录 最近在帮学弟改一个毕业设计课题题目就是“基于微信小程序的南昌旅行指南的设计与实现”。他选型的时候纠结了很久最后在原生小程序和UniApp之间选了UniApp。这个选择其实挺典型——现在很多做微信小程序毕设、课设甚至个人外包项目的人都会在原生和跨端框架之间犹豫。我刚好完整跟了一遍这个项目的开发、调试、打包和上架准备流程踩了不少坑也优化掉了很多常规文档里不会写的细节。这篇博客就把整个项目的设计思路、技术选型、核心功能实现过程以及开发中遇到的典型问题和排查方法都梳理一遍。不管是正在做类似旅行类小程序毕设的同学还是想用UniApp做微信小程序但不太确定怎么落地的开发者都可以直接参考这份实战记录。文章里涉及的代码、配置和排查思路都是我实际跑通、验证过的东西不是网上那种复制粘贴的Demo。1. 项目整体设计与思路拆解1.1 为什么选UniApp而不是原生微信小程序先回答一个很多人都会纠结的问题既然最终发布目标就是微信小程序为什么不直接写原生我当时的判断标准其实很现实UniApp用的是Vue语法如果你已经熟悉Vue开发效率会比原生WXML高不少尤其是页面结构和组件化的组织方式。它编译到微信小程序之后本质上还是生成了一套完整的微信小程序代码最终上传、审核、发布的流程和原生没有任何区别。这意味着项目后续如果想扩展一个H5版本或者App版本同一套代码还能继续用不用推倒重来。另一个实际原因是生态组件。微信原生开发很多UI交互需要自己写或者引第三方库而UniApp这边有uni-ui和很多现成插件比如后续要用的轮播图、地图定位、下拉刷新等很多都是开箱即用。对于毕业设计这种时间紧、又要体现完整度的场景这个优势比较明显。但要注意UniApp并不是“零成本”的。它有自己的语法约束比如生命周期钩子、路由跳转用uni.navigateTo而不是wx.navigateTo条件编译也有自己的一套规则。好在我们只需要针对微信小程序一个平台开发条件编译这块基本用不上复杂度和风险都会小很多。如果你未来要同时适配多个平台那再额外花时间处理平台差异单平台开发的话选UniApp是划算的。1.2 南昌旅行指南的核心功能模块拆解做旅行指南类小程序第一件事不是写代码而是想清楚用户打开这个小程序到底要干什么。我梳理下来南昌旅行这个主题可以拆成四个核心场景景区景点浏览、美食推荐、游玩路线规划、以及旅游过程中的导航和实用信息查询。围绕这四个场景项目最终确定了五个主要功能模块首页负责品牌展示和内容聚合包括顶部焦点图轮播、热门景点入口、实时天气信息展示、以及最新的活动推荐。景点模块以列表形式展示南昌各地的景点支持关键词搜索和分类筛选点击进入详情页后可以看到图文介绍、开放时间、门票信息、位置地图和用户评价。美食推荐按“南昌本地特色”“老字号”“网红打卡”等分类展示餐厅和美食详情里包含人均消费、推荐菜、营业时间以及一键导航。路线规划提供“一日游”“两日游”“亲子游”等模板化路线每条路线会把景点、餐饮、交通连接起来用户一键保存到“我的行程”里。个人中心包含用户登录、收藏列表、浏览足迹、行程管理、意见反馈等基础功能登录用微信一键授权省去手机号注册的繁琐流程。这五个模块听起来内容很多但因为数据初期用静态JSON承载前端页面都能独立跑起来所以开发可以分阶段推进。完整度上它已经把旅行类App里最常见的信息流、搜索、详情、收藏、导航都覆盖到了作为毕业设计的选题规模和深度都够。1.3 数据来源与存储方案选型旅行指南类应用和电商类不一样它的数据更新频率很低景点信息、开放时间、美食介绍这些内容基本是半静态的。所以在数据层我没有一开始就上服务器和数据库而是分了两步走。第一步是项目开发和演示阶段数据直接放在前端静态JSON文件里。每个景点、每个美食店、每条路线都是一个独立的数据对象包含名称、图片、简介、坐标、标签、开放时间等字段。前端通过uni.request或直接import引入渲染到页面上。这么做的好处是项目可以完全脱离后端独立运行不管答辩演示还是本地测试都非常方便。第二步是功能增强阶段引入uniCloud云开发。云开发的核心价值在于两点一是把静态数据换成云数据库数据让前端通过云函数读取这样数据就不是写死的代码而是真正存在“服务器”上二是用户收藏、浏览足迹这些个性化数据可以存到云数据库的user集合里真正做到跨设备同步。最终我采用的是“静态JSON为主uniCloud云存储为辅”的混合方案。这个方案对毕设场景特别友好——答辩的时候你可以展示完整的业务流程但又不需要自己买服务器、配域名、搞备案成本几乎为零。1.4 页面架构与tabBar导航设计小程序的页面层级不宜过深尤其旅行类应用用户通常是“打开就找景点点进去看详情”路径越短越好。我用的是经典的底部tabBar加二级详情页结构入口页面路径功能定位首页pages/index/index焦点图、热门景点、天气、活动入口景点pages/attraction/list景点列表、搜索、筛选路线pages/route/list路线模板、行程预览我的pages/mine/mine登录、收藏、足迹、设置tabBar需要在pages.json里配置图标用iconfont生成的PNG图片选中和不选中两个状态都要准备。这里有个配置坑tabBar页面路径必须严格对应pages数组里注册过的路径而且tabBar页面不能通过uni.navigateTo跳转否则会报错。首页跳详情、列表跳详情这些二级页面都放在pages/attraction/detail、pages/food/detail这类非tabBar路径下。2. 核心细节与实操要点解析2.1 manifest.json配置与微信小程序适配很多新手在HBuilderX里创建完项目什么都不改就直接运行结果在微信开发者工具里打开白屏或者样式全乱。这通常就是manifest.json没配置好。manifest.json是UniApp项目的全局配置文件它同时管理应用名称、图标、权限声明、SDK配置等。针对微信小程序端最关键的是mp-weixin节点下的appid配置。这里有一个很典型的错误有人把wx小程序的AppID填成了touristappid或者直接留空导致HBuilderX运行到微信开发者工具时提示“不是开发者”或者“无权限”。正确的是先在微信公众平台注册一个小程序账号拿到正式AppID然后填到manifest.json的mp-weixin.appid字段里{ mp-weixin: { appid: 你的小程序AppID, setting: { urlCheck: false, es6: true, minified: true }, usingComponents: true, permission: { scope.userLocation: { desc: 获取你的位置信息用于导航到景点 } }, requiredPrivateInfos: [getLocation, chooseLocation] } }这里requiredPrivateInfos是后来微信新加的隐私声明要求。如果你在小程序里用了uni.getLocation获取用户定位除了要在permission里声明用途说明还要在微信公众平台后台“开发管理-接口设置”里申请对应的隐私接口权限否则在真机上调用时会直接报错拒绝。这个坑不少人在答辩前才发现临时提交审核又要等几天特别耽误事。还有一个容易被忽略的配置vueVersion。如果项目创建时选的是Vue2manifest.json里对应的是vueVersion: 2如果你在代码里写了Vue3的组合式API运行时会直接报Cannot read property xxx of undefined之类的错误排查起来很容易懵。所以创建项目时先想好用Vue2还是Vue3我建议毕设项目选Vue2因为网上UniAppVue2的资料最多踩坑后好查答案。2.2 页面导航与路由参数获取旅行指南小程序里最常用的跳转就是从列表页到详情页。比如景点列表点一项跳转到景点详情页同时要带上这个景点的ID。UniApp里跳转和原生微信小程序很类似// 列表页跳转详情页 uni.navigateTo({ url: /pages/attraction/detail?id item.id }); // 详情页接收参数 onLoad(options) { if (options.id) { this.attractionId options.id; this.loadDetail(options.id); } }看起来简单但实际开发里会碰到一个很经典的坑如果详情页是通过onLoad拿参数那把这个详情页作为tabBar页面时onLoad只会触发一次。比如你从景点A进详情返回后再从景点B进详情页面是同一个实例onLoad不会再次执行导致页面显示的仍是景点A的内容。解决方式有两种一种是用onShow配合options重新加载数据另一种是不要在tabBar里放详情页详情页一律走子页面路径。正规的做法是第二种也是我在项目里采用的方式。tabBar页面只保留四个主页面详情页都是独立子页面这样每次进入都会走onLoad数据自然就刷新了。2.3 地图导航功能uni.openLocation与高德地图接入旅行指南最核心的价值之一就是导航。用户看到景点详情页后最直接的需求是“我要怎么去”。开发初期我直接用uni.openLocation打开内置地图这是UniApp内置的API只要传入经纬度和地名就可以唤起微信内置地图再点击“导航”按钮跳到腾讯地图或其他导航应用实现成本非常低openMap(location) { uni.openLocation({ latitude: location.latitude, longitude: location.longitude, name: location.name, address: location.address, scale: 18 }); }这个方案的好处是不需要额外引入SDK也不需要地图Key演示时只要保证微信开发者工具有调试基础库权限就行。但缺点是内置地图的UI和品牌样式不能自定义如果你想要更丰富的效果比如标记点、路线图层、周边POI展示那就需要引入高德地图微信小程序SDK。高德的接入流程是在高德开放平台注册开发者账号创建“微信小程序”类型应用拿到Key然后在项目中引入高德微信小程序SDK。SDK初始化时需要传入Key和securityJsCode这个安全码在高德控制台的安全设置里生成。我实际跑下来高德的文档对微信小程序的描述不太友好容易漏掉安全码配置但配好后marker展示、路线规划等功能都比原生体验好很多。2.4 视频播放场景实现限制单视频与自动暂停旅游类小程序很喜欢在景点详情页放视频比如航拍视频、宣传片。但小程序里的video组件在列表页面中存在一个老问题如果不做控制多个视频同时加载会抢占解码资源导致卡顿还可能互相串声音。所以我在“视频攻略”板块实现了两个核心逻辑同一时间只允许一个视频播放视频滑出可视区域自动暂停。第一个逻辑很直接监听每个video的play事件当新视频开始播放时调用其他视频的pauseContext.stop()停掉它们onVideoPlay(index) { this.currentVideoIndex index; let oldVideo this.videoContexts[this.preVideoIndex]; if (oldVideo) { oldVideo.stop(); } this.preVideoIndex index; }第二个逻辑需要用到uni.createIntersectionObserver它用来观察视频组件是否还在可视区域内onShow() { this.videoObserver uni.createIntersectionObserver(this); this.videoObserver.relativeToViewport().observe(.video-item, (res) { if (res.intersectionRatio 0 this.currentVideoIndex ! -1) { this.videoContexts[this.currentVideoIndex].pause(); } }); }这里要注意的是IntersectionObserver在小程序端的兼容性还过得去但真机上偶尔会监听不到尤其是视频外层的容器有transform动画或者overflow属性时。我实测的解决办法是把观察目标尽量贴近video本身不要监听太外层的大容器。还有一个细节是onHide时要把正在播放的视频主动暂停避免用户切走页面后视频还在后台播放这个就是体验细节了。2.5 分享功能与onShareAppMessage被全局覆盖的问题分享是微信小程序天然的裂变能力旅行指南这种内容型应用很适合“分享给朋友看”。实现分享只需要在页面里定义onShareAppMessage方法onShareAppMessage() { return { title: 南昌旅行指南 - this.currentAttraction.name, path: /pages/attraction/detail?id this.currentAttraction.id, imageUrl: this.currentAttraction.cover }; }但我们开发中遇到一个问题为了方便把onShareAppMessage封装到了全局混入里结果子页面的分享配置被全局方法覆盖导致每个页面分享出去都是同样的标题和路径。原因是Vue.mixin会在组件自身的生命周期方法之前执行而页面如果自己没有定义onShareAppMessage就会直接使用全局默认配置。解决方式是不要在全局混入里写死分享内容而是把全局混入的方法设计成读取当前页面实例上的属性// 全局混入 onShareAppMessage() { let page this.$scope; if (page page.getShareInfo) { return page.getShareInfo(); } return { title: 南昌旅行指南, path: /pages/index/index }; }这样每个页面只需要实现自己的getShareInfo方法返回个性化的分享内容既保留了全局兜底又实现了页面级配置。另外要注意onShareAppMessage不能在onLoad里动态赋值必须定义在页面配置的methods或直接写在页面顶层否则不生效。3. 实操过程与核心环节实现3.1 环境准备HBuilderX 微信开发者工具联调开发环境这块我用的是HBuilderX作为主编辑器微信开发者工具作为预览和调试工具。第一步是下载安装HBuilderX安装好后在“工具-插件安装”里装好uni-app相关依赖。然后创建项目时选“uni-app默认模板”项目名称就叫nanchang-travel。框架选择Vue2。第二步是准备微信开发者工具。打开微信开发者工具用管理员账号扫码登录然后在“设置-安全设置”里开启“服务端口”。这一步很关键因为HBuilderX是通过这个端口把编译后的代码自动推送到微信开发者工具里打开的。如果服务端口没开HBuilderX里的“运行到小程序模拟器”点了没反应这也是网上被问烂了的一个问题。确保端口开启后在HBuilderX里选择“运行—运行到小程序模拟器—微信开发者工具”等待编译完成微信开发者工具会自动打开项目。这个时候如果出现的是微信登录的二维码界面而不是项目页面一般是AppID没配好回到manifest.json检查mp-weixin.appid。还有一个我实际遇到的坑HBuilderX和微信开发者工具的版本匹配问题。HBuilderX如果版本过旧生成的编译产物可能在微信开发者工具新版里直接报SyntaxError。所以两个工具尽量都保持最新稳定版尤其是HBuilderX它的更新频率不高但每次更新都会修复编译层面的兼容问题。3.2 首页和景点列表页落地过程首页的布局思路是“从上往下层次分明”。顶部是一个搜索框用作全站景点和美食搜索入口。下面是焦点图轮播用uni-swiper实现每张图对应一个热门景点点击跳转对应详情页。再往下是两个横向列表“热门景点”和“今日美食”用横向滑动方式排列每个卡片包含封面图、名称、评分和人流量状态。首页的数据来源开发初期我直接放在/static/data/attractions.json里。页面加载时用uni.request读取本地文件在微信开发者工具里可能会受限所以我直接用import方式引入import attractionsData from /static/data/attractions.json; export default { data() { return { attractions: attractionsData.list } } }景区列表页用scroll-view实现下拉刷新和上拉加载分页。这里要注意微信小程序的页面级enablePullDownRefresh需要配合pages.json里的配置在对应页面的style节点下设置enablePullDownRefresh: true。如果你只写了onPullDownRefresh生命周期方法而没开页面配置下拉刷新是不会有反应的。列表页的搜索功能我用的是前端本地过滤因为数据量不大。搜索框用uni-search-bar输入关键字后对标题、标签、简介做includes匹配实时更新列表。如果有两项体验优化一定要做一是搜索结果的最近几项做个高亮处理二是搜索过程中防抖避免每输入一个字就重新渲染整个列表。3.3 景点详情页与自定义导航栏适配详情页是整个项目的门面信息密度最高。我的结构是这样的顶部是视频区或图片轮播区往下依次是景点名称、评分、开放时间和门票信息卡片再到简介和图文详情最后是“一键导航”和“收藏”两个悬浮按钮。自定义导航栏这个事情一开始我用的默认导航栏但默认导航栏样式比较死板不能做到沉浸式效果。后来改成自定义导航栏在pages.json对应页面设置navigationStyle: custom然后在页面里自己写一个导航栏组件。这里就会碰到热搜词里提到的“微信小程序顶部导航栏高度”问题。导航栏高度不是固定的它由状态栏高度和导航栏自身高度组成。状态栏高度可以通过uni.getSystemInfoSync().statusBarHeight获取而导航栏自身高度在iPhone X以上带刘海的机型会更高。我封装了一个工具函数getNavBarHeight() { const systemInfo uni.getSystemInfoSync(); const statusBarHeight systemInfo.statusBarHeight || 44; // 微信小程序胶囊按钮位置可以动态计算 const capsule uni.getMenuButtonBoundingClientRect(); const navBarHeight capsule.top ? (capsule.bottom - capsule.top) (capsule.top - statusBarHeight) * 2 : 44; return { statusBarHeight, navBarHeight }; }这个函数利用了uni.getMenuButtonBoundingClientRect拿到胶囊按钮的位置用胶囊按钮的top减状态栏高度来估算导航栏额外高度。真机适配效果比写死44像素要准得多。如果你偷懒写死一个高度在iPhone SE、iPhone X和安卓全面屏上会分别出现内容顶出安全区、胶囊按钮压标题等视觉问题。3.4 个人中心登录、收藏与足迹个人中心页面承载的功能逻辑比较多。登录用的是uni.login配合uni.getUserProfile在用户点击“微信登录”按钮时触发拿到用户头像和昵称后写入本地和云数据库。这里绕不开一个改动微信官方已经收紧getUserProfile不能在小程序加载时自动弹授权框必须用户主动点击登录按钮才能调用否则接口直接失败。所以个人中心的登录按钮要做得显眼并配上引导文案比如“登录后同步收藏和足迹”。收藏和足迹的数据结构很简单收藏存的是景点ID数组足迹存的是浏览记录对象数组。开发初期直接存uni.setStorageSync(favorites, favorites)后面为了演示云开发能力改成在登录后调用云函数同步云数据库。这里有一个“同步冲突”的细节本地存储是即时的但云同步是异步的切换账号时容易出现旧账号数据覆盖新账号。我的处理方式是登录时先拉取云端数据以云端为主合并本地数据再重新写回两端。另外合规方面一定要做“隐私政策同意弹窗”。现在的应用审核很看重这一点如果用户不同意隐私政策就不能再调用任何隐私接口。我在“我的”页面设置了一个“用户协议和隐私政策”入口首次启动时强制弹窗如果用户拒绝就直接退出小程序。这个逻辑代码如下if (!uni.getStorageSync(hasAgreedProtocol)) { uni.showModal({ title: 用户协议和隐私政策, content: 在使用本小程序前请仔细阅读《用户协议》和《隐私政策》, confirmText: 同意并继续, cancelText: 不同意, success: (res) { if (res.confirm) { uni.setStorageSync(hasAgreedProtocol, true); // 继续初始化 } else { uni.exitMiniProgram(); // 用户不同意则退出小程序 } } }); }3.5 echarts图表与数据可视化扩展旅行指南里我额外加了一个数据可视化页面用来展示各景区的热度排行、月度游客分布和美食口味偏好分析。这里用到的是echarts在小程序端的适配库echarts-for-weixin再结合UniApp的renderjs在H5端运行。不过如果只是面向微信小程序直接用echarts官方提供的小程序组件会更快。实现方式很简单先在插件市场导入echarts组件然后在一个空的view组件上初始化图表import * as echarts from /components/echarts/echarts.js; onReady() { this.chart echarts.init(this.$refs.hotChart); this.chart.setOption({ tooltip: {}, xAxis: { data: this.attractionNames }, yAxis: {}, series: [{ type: bar, data: this.attractionScores }] }); }这里要注意的是echarts的初始化时机必须在页面渲染完成后也就是onReady里调用init如果你在onLoad里调用此时节点还没渲染完成会报“Component is not found”的错误。另外图表所在页面如果用了自定义导航栏图表容器的宽度要用uni.getSystemInfoSync().windowWidth计算不要写死像素值否则在iPad或平板尺寸的模拟器上会错位。3.6 尾部导航、弹窗与软键盘交互优化旅行指南里有个“行程预览”弹窗点击路线卡片后弹出一个半屏弹层展示路线包含的景点和预计时长。这里有一个非常常见的bug弹层弹出后底层的页面背景仍然可以滚动体验很差。我在页面根节点上动态绑定一个no-scroll类弹层打开时openRoutePreview() { this.showRoutePreview true; // 禁止底层滚动 uni.pageScrollTo({ scrollTop: 0, duration: 0 }); document.body.style.overflow hidden; // H5端有效 }但微信小程序端没有document.body所以更通用的方式是给弹层加一个全屏遮罩并且让遮罩层捕获点击事件。在结构上把弹层和遮罩放在页面根节点的同层遮罩用position: fixed覆盖全屏这样底层滚动事件基本会被遮罩拦截。另外还可以在底层添加catchtouchmovenoop的空方法来阻止默认滚动这个方法虽然保守但非常有效view classroute-mask catchtouchmovenoop v-ifshowRoutePreview/view还有一个排序功能里遇到的通用问题在列表页点击搜索框时微信小程序的软键盘会弹起并遮挡下方的查询按钮。很多人在热搜里搜“uni-app 微信小程序 手机软键盘会遮挡住查询内容”原因就是页面没有给输入框预留键盘弹出后的空间。解决办法是在输入框所在的输入容器上监听focus和blur事件focus时把整个输入区向上偏移或者用adjust-position属性控制不过在某些安卓真机上adjust-position的效果不太稳定这时就需要配合uni.onKeyboardHeightChange动态调整页面布局位置。3.7 打包发布与上架准备项目开发完成后要真机预览或上传代码。先做真机预览在HBuilderX里选择“运行—运行到手机或模拟器”微信开发者工具扫码后在真机上打开。真机预览和模拟器最大的差异是权限判断和网络请求比如本地localhost接口在真机上是访问不到的必须替换成局域网或HTTPS接口。对于只用静态JSON的项目这个问题不存在但一旦接入了uniCloud云函数需要注意云函数的url化域名要配置到小程序后台的request合法域名里。上传发布前要在HBuilderX里“发行—小程序-微信”生成生产编译产物。这一步会校验manifest.json里的AppID是否有效并且生成分包配置。微信小程序主包大小限制是2MB如果打包后超过大小限制就需要做分包处理。分包配置在pages.json里把非核心页面放到subPackages节点下{ subPackages: [ { root: pages/food, pages: [detail] }, { root: pages/route, pages: [detail] } ] }我实测发现旅行指南类项目最容易撑大主包的其实是图片资源。如果图片没有压缩几张几兆的大图就会把2MB主包挤爆。解决办法是把图片放到服务器或对象存储上通过URL引用而不是打包进小程序。如果一定要打包进去图片要压缩到100KB以内格式优先用WebP。上传到微信公众平台后在“版本管理”里提交审核审核通过后再提交发布。安卓应用市场那边同理需要准备软著、隐私政策说明等材料不过那是上架App的阶段这部分和微信小程序已经关系不大了。4. 常见问题与排查技巧实录4.1 高频问题速查表这几个问题都是我在实际开发以及帮网友看代码时高频遇到的整理成一个速查表方便对照排查问题现象可能原因排查与解决HBuilderX运行到微信开发者工具没反应微信开发者工具服务端口未开启打开微信开发者工具设置-安全设置-开启服务端口提示“不是开发者”manifest.json里AppID为空或错误填入微信公众平台的小程序正式AppID小程序顶部导航栏高度不对使用了navigationStyle: custom但未动态计算用uni.getSystemInfoSync().statusBarHeight胶囊位置动态计算分享出去的title不生效onShareAppMessage被全局混入覆盖全局混入中读取页面实例的getShareInfo方法真机上uni.getLocation报错未在微信后台申请隐私接口权限在微信公众平台-开发管理-接口设置里申请getLocation权限弹窗出现后背景还能滚动遮罩层没有拦截滚动事件给遮罩添加catchtouchmovenoop视频组件播放串音没有控制单视频播放监听play事件调用其他播放实例的stop()方法页面突然白屏或JS报错工具版本过旧或包体过大更新HBuilderX和微信开发者工具压缩图片并做分包4.2 几个值得记录的排查过程有一个排查印象很深模拟器里视频可以正常播放但真机上点击视频没有反应。起初我以为是小程序基础库版本问题后来发现是video组件的src用了本地静态路径。微信小程序真机环境下本地视频资源的加载是有大小限制的超过一定体积会自动失败。解决办法是把视频资源放到腾讯云COS或uniCloud存储上用HTTPS链接作为src。顺带说一句视频封面poster属性也建议用网络链接本地链接在部分安卓机型上会显示黑屏。另一个比较隐蔽的是软键盘遮挡问题。搜索框在页面顶部点击后软键盘弹起在部分安卓手机上整个页面会被键盘顶上去但键盘收回后页面没恢复到原位导致布局错乱。处理方式是监听onKeyboardHeightChange在键盘高度不为0时记录当前滚动位置键盘收起时强制uni.pageScrollTo回到记录的位置。这个方案的兼容性比单纯依赖adjust-position好很多。还有一个和swiper嵌套video相关的坑。景点详情页的顶部图片轮播如果某一帧是视频在iOS上点击全屏播放后返回轮播图经常错位或黑屏。这是swiper组件和原生视频组件层级冲突导致的。建议不要在swiper里直接放video而是改造为“多图轮播第一帧视频入口”的方案点击视频按钮再跳转到一个单独的短视频播放页播放这样既避免了原生组件层级问题产品逻辑上也更清爽。4.3 开发过程中的避坑心得第一数据字段的命名规范一定要提前想好。景点数据里的坐标字段我一开始用的是lat和lng后来接高德地图时发现高德的标准字段是latitude和longitude结果写了一个适配层才解决。这种字段命名不统一的问题在项目后期非常耗费精力建议最初就按第三方SDK的标准字段来建数据模型。第二多用条件编译处理多端差异。虽然项目主要面向微信小程序但你在H5端调试时可能发现布局正常到了小程序端却乱了。原因很可能是你在H5端用了某些DOM操作或浏览器专有API。UniApp通过#ifdef MP-WEIXIN和#ifndef MP-WEIXIN做条件编译能在不同平台输出不同代码。我的经验是遇到平台差异第一时间想到条件编译而不是强行写一套兼容代码这样最后代码会干净很多。第三微信小程序版本的更新迭代比较快基础库、API行为可能随时调整。如果开发过程中发现某些之前正常的API突然失效了先去查一下是不是基础库版本变了更新到最新版调试基础库再试。这个习惯能帮你省掉大量不必要的“玄学排错”时间。结尾的话这个项目从需求梳理到功能落地再到打包发布准备整个过程走下来我最大的感受是UniApp解决了很多跨端重复开发的问题但微信小程序本身的设计规范和原生组件特性仍然是绕不开的核心。做旅行指南这类信息展示型小程序真正的功夫不在框架语法而在于数据组织是否清晰、页面跳转逻辑是否顺滑、以及对各种真机适配细节是否足够重视。如果你接下来也要做类似的项目我的建议是先花两天时间把页面结构和数据结构定下来不要急着写页面。数据结构清晰了页面写起来会非常快数据结构混乱后面每加一个功能都要返工。另外开发过程中随手记录自己的踩坑日志答辩或者写项目文档时这些真实的问题和解决方案就是最好的素材。最后再分享一个小技巧旅行类小程序的“收藏”功能不要只做收藏列表可以把收藏的景点自动生成一条推荐路线。这个功能实现起来难度不大但答辩时展示效果特别好因为它是从用户行为推导出了个性化内容比单纯的收藏列表更有说服力。
返回列表