news 2026/9/15 23:19:56

VibeCoding实战:从零到提审通过,AI辅助开发旅行小程序全记录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VibeCoding实战:从零到提审通过,AI辅助开发旅行小程序全记录

最近三周我基本都泡在电脑前,用VibeCoding的方式从零搓了一个旅行小程序出来。所谓VibeCoding,说白了就是让AI帮你写代码、你负责把需求和边界讲清楚——写需求描述像点菜,AI是后厨,我是那个一边试菜一边让后厨改口的品菜师傅。整个过程从项目初始化到提审通过,我自己手写的核心代码加起来可能不到三百行,但来回沟通和验证的成本一点不比手写少。这门手艺听起来很省事,真正落地起来该踩的坑一个都不会少。

这篇文章记录的就是一次完整的VibeCoding旅行小程序实战:为什么选旅行这个题材、技术栈怎么定、核心功能怎么落地、发布前有哪些流程坑,以及最后几个让我印象深刻的翻车现场。如果你也在考虑用AI快速做一个小程序,或者已经试过让AI写代码但被它那种“一本正经胡说八道”折磨过,这篇应该对你有用。

1. 项目思路:为什么选旅行小程序来玩VibeCoding

1.1 什么是VibeCoding,它解决的到底是什么问题

VibeCoding不是某个工具的专属名词,而是一种开发方式——开发者用自然语言向AI描述需求,AI生成代码,开发者负责审查、运行、反馈、迭代。它和传统开发最大的区别是:以前写代码是“从0到1把每个字符敲出来”,现在写代码是“把需求讲清楚,让AI把骨架和样板代码生成出来,你再补血补肉”。

它解决的核心痛点是重复劳动。比如你要在小程序里做一个列表页,传统方式要写Page、写WXML、写样式、写请求、写Loading态、写空数据态。用VibeCoding,这个过程可以压缩成几轮对话和几轮微调。我实测下来,像列表加载、表单校验、通用弹窗这类结构固定的代码,AI生成的质量非常高,拿到就能跑。

但它不解决所有问题。越是不明确的需求,AI写出来的越“虚”。比如你说“做一个顺眼的目的地卡片”,它可以给你十种样式,最后你反而要花更多时间在审美决策上。所以在VibeCoding里边,真正考验人的不是打字速度,而是需求拆解能力、代码审查能力和边界情况补充能力。这三点缺一个,AI就会把你带进坑里。

1.2 旅行小程序这个题材好在哪里

旅行类小程序在个人项目、面试作品、全栈练手里都很合适。它天然包含用户登录、内容列表、地图导航、搜索、表单、分享、收藏、个人中心这些模块,几乎把微信小程序最常见的开放能力全部覆盖了一遍。做完一个旅行小程序,你对整个小程序生态的理解会比照着文档敲十遍demo要深得多。

我做的这个项目规划了四个核心页面:首页(目的地推荐)、地图页(附近景点和路线)、清单页(旅行物品和行程安排)、个人中心(收藏和设置)。这四个页面覆盖了授权登录、列表渲染、地图SDK接入、表单交互、云数据库读写这些关键能力,每一块都能在真实场景中找到对应需求。而且旅行这个场景用户有天然代入感,做完之后你身边的人真的会去用,不像做一个计算器demo只能自嗨。

另外从VibeCoding的角度看,旅行场景的交互复杂度也合适。它不像电商那样要搞购物车、订单、支付状态机,也不像社交那样要处理实时消息。它属于“功能丰富但每个点都不深”的典型场景,正是AI生成代码成功率最高、出问题最好排查的类型。

2. 技术选型:uniapp + 云开发 + 高德地图,这套组合稳在哪

2.1 框架选择:为什么不用原生而是uniapp

先说结论:个人开发和快速原型场景,uniapp是比原生微信小程序更省事的选择。原生小程序要学WXML、WXSS、Page生命周期那套,而uniapp用的是Vue语法,对前段转过来的开发者更友好,未来如果要出H5、App版本,一套代码能复用。

还有一个很实际的原因:AI对Vue语法的训练语料远比WXML原生语法充足。同样是让AI生成一个带滚动加载的列表页,用uniapp的Vue写法生成出来的代码基本能用,用原生小程序语法有时候会生成过时的API或错误的模板结构。VibeCoding模式下,选一个AI更“熟悉”的框架,等于从一开始就降低沟通成本。

维度原生微信小程序uniapp
上手门槛需要熟悉WXML/WXSS熟悉Vue即可
跨端能力仅微信端微信、H5、App等
AI生成成功率中等,偶尔用过时API高,Vue语料丰富
组件生态官方组件uni-ui、uView等
调试链路开发者工具HBuilderX + 开发者工具联动

开发环境我用的是HBuilderX + 微信开发者工具双开。HBuilderX里写完代码,点编译就能自动在微信开发者工具里刷新预览。这套链路熟练之后非常流畅,需要调试样式直接在开发者工具里看,需要改逻辑就回到HBuilderX改完重新编译,往返成本很低。

2.2 后端不用服务器:微信云开发

旅行小程序的后端我用了微信云开发,没买服务器、没配域名、没搞HTTPS证书。以前写后端要先搭Node环境、配数据库、处理登录鉴权,光环境搭建就能劝退一半新手。云开发把云函数、云数据库、云存储都内建好了,和微信登录体系天然打通,省掉了很多中间环节。

我建了这几个集合:users(用户)、destinations(目的地)、categories(分类)、favorites(收藏)、checklists(旅行清单)、routes(路线)。每个集合的字段一开始就可以让AI根据需求生成,但数据权限一定要自己检查,这个后面会讲。

云函数获取目的地列表可以这样写:

// 云函数 getDestinations/index.js const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, context) => { const { category = '', page = 0, pageSize = 10 } = event const where = {} if (category) where.category = category try { const res = await db.collection('destinations') .where(where) .skip(page * pageSize) .limit(pageSize) .orderBy('heat', 'desc') .get() return { code: 0, data: res.data } } catch (e) { return { code: -1, message: e.message } } }

前端调用就很简单:

const res = await wx.cloud.callFunction({ name: 'getDestinations', data: { category: 'beach', page: 0 } }) this.destinations = res.result.data

为什么我坚持走云函数而不是前端直连数据库?因为直接在小程序端用wx.cloud.database()读取,权限配置比较粗,而且每个集合的安全规则一旦写错,用户就可能读到不该读的数据。云函数相当于加了一层自己的权限控制,代码都在服务端,前端只拿到最终结果,安全性和可控性都更好。

2.3 地图能力选型:高德地图小程序SDK

旅行小程序离不开地图。微信自带的wx.getLocationwx.openLocation只能提供定位和导航跳转,但搜索POI、逆地理编码、周边推荐这些能力需要第三方地图SDK。我选的是高德微信小程序SDK,原因无他,文档清晰、示例多、AI训练语料充足。

接入流程是:在高德开放平台注册开发者,创建应用,绑定小程序的AppID,拿到Key,然后在项目中引入amap-wx.js,初始化后调用接口。

const amap = new AMapWX({ key: '你的高德Key' }) amap.getPoiAround({ query: '景点', location: `${latitude},${longitude}`, success(res) { console.log(res.markers) }, fail(err) { console.error(err) } })

这里有个常见的坑:调试时经常报USERKEY_PLAT_NOMATCHKEY无效,绝大多数原因是高德后台绑定的AppID和你当前编译的小程序AppID不一致。注意高德后台填的是小程序的AppID,不是HBuilderX里的AppID,这两个东西长得一样但不一样,不要填错。还有Key的配额,个人开发者的免费配额对小流量项目完全够用,但如果在开发环境反复刷新页面触发大量请求,有可能会短暂限流。

3. 核心功能模块落地:从登录到地图导航

3.1 用户授权与登录链路

以前做小程序登录,大家习惯用wx.getUserProfile拿头像昵称,现在这条路基本堵死了。微信改成了“头像昵称填写能力”,必须让用户主动点击按钮,用open-type="chooseAvatar"选头像,用昵称输入框填名字。uniapp里写法如下:

<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> 点击选择头像 </button> <input type="nickname" placeholder="请输入昵称" v-model="nickname" />

后端登录用云开发就太简单了,云函数里可以直接拿cloud.getWXContext().OPENID,不需要自己维护登录态。

// 云函数 login/index.js const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) exports.main = async () => { const wxContext = cloud.getWXContext() return { openid: wxContext.OPENID } }

用户授权登录这里我有一个心得:不要把登录流程卡在首页。如果用户一进小程序就被要求授权、填昵称、选头像,流失率会很高。正确做法是静默获取openid,把用户数据先落库,等用户真的想收藏或查看个人中心时,才引导他去完善头像昵称。VibeCoding生成代码时特别容易默认“进来就弹登录”,这个逻辑一定要跟AI反复强调。

3.2 首页与目的地列表:数据从哪来

首页是整个小程序的门面,我把它做成了目的地推荐流。数据来自云数据库的destinations集合,每个文档包含以下字段:

  • name:目的地名称
  • city:所在城市
  • category:beach / mountain / city / food
  • cover:封面图fileID(云存储)
  • heat:热度数字,排序用
  • tags:标签数组,比如“适合亲子”“网红打卡”

列表不是一次性拉所有数据,而是分页加载。每一页10条,通过skiplimit配合,下拉到底部就加载下一页。这个分页逻辑在原生开发里要写不少代码,但VibeCoding模式下直接让它生成,再检查一下边界情况就行。

有一个细节必须自己处理:AI生成的列表经常没有加载状态、空数据状态和错误状态。真实用户看到白屏第一反应是“坏了吧”,有骨架屏或loading至少让人知道在加载。我后来让AI补了三件事:进入页面先弹Loading、加载失败后显示“加载失败,点击重试”、数据为空显示插画占位。这三个状态加上之后,整个页面才像是一个能上线的产品。

3.3 地图与路线导航:让用户真正“走起来”

地图页是旅行小程序的核心体验。用户打开地图页,我请求定位权限,拿到当前经纬度之后,调用高德的getPoiAround搜索周边景点。点击某一个景点,弹出一个半屏底部面板,展示景点名称、地址、距离、评分和简介。再点“去这里”,直接调起微信内置地图导航:

wx.openLocation({ latitude: 22.541, longitude: 113.970, name: '大梅沙海滨公园', address: '盐梅路', scale: 18 })

为什么用wx.openLocation而不是自己内嵌一个地图页?因为在微信生态里,原生地图的性能和交互都比任何第三方地图组件靠谱,而且调起内置地图后用户可以一键发送位置给朋友,这个天然分享能力是自己画地图替代不了的。

这里有个定位权限的问题。小程序对位置权限很敏感,如果没有在app.json里声明requiredPrivateInfoswx.getLocation会直接报错。同时在小程序后台的“用户隐私保护指引”里也要补上“位置信息”这一项,否则审核会被驳回。这个准备工作要提前做,不要等写完代码才想起来。

3.4 页面体验细节:动态标题、导航栏适配、加载页

VibeCoding生成的东西往往“功能能跑,细节稀碎”,所以页面体验这一块我是自己手动补的。

第一是动态设置标题。比如用户从首页点进“三亚七日游攻略”,导航栏标题不能一直叫“首页”,要根据页面内容动态变化。uniapp里一行代码:

uni.setNavigationBarTitle({ title: '三亚七日游攻略' })

注意调用时机:不要放在onLoad里同步设置,而是等数据请求完成后拿到目的地名称再设置,否则数据还没回来,标题已经被设置成默认值了。

第二是顶部导航栏高度适配。不同的手机状态栏高度不一样,尤其现在手机都带挖孔、灵动岛,自定义导航栏时胶囊按钮的位置每台机器都不同。可以用这个方式动态计算:

const menuButton = wx.getMenuButtonBoundingClientRect() const statusBarHeight = wx.getWindowInfo().statusBarHeight const navBarHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.height

这个公式的原理是胶囊按钮中心一般和标题中心对齐,所以导航栏高度等于胶囊顶距减去状态栏高度、乘以两倍、再加胶囊本身高度。实测在iPhone和主流安卓机上表现稳定。AI第一次生成的自定义导航栏全是写死的44px,我让它在不同机型上测了一遍之后就老老实实改成动态计算了。

第三是修改启动加载页。小程序冷启动时看到的那个主题色页面不是普通页面,而是app.jsonwindow配置的背景色。我把默认的白色改成了暖色调,和旅行主题呼应。如果在启动过程出现白屏闪烁,通常是因为主包太大或者首个页面的数据请求太慢,不是简单的背景色问题,可以从分包和预加载两个方向优化。

3.5 清单页里的表单和拖拽交互

清单页我做了两个核心能力:旅行物品勾选和行程安排排序。旅行物品勾选用了一个单选交互,但没用原生radio组件,而是直接用view模拟:点击后将一个圆形图标切换到选中态,样式上更贴合整体UI,也避开了原生radio在不同机型上样式不一致的问题。这个小功能AI一次就生成对了,因为逻辑足够简单直接。

行程安排排序是另一个故事。微信小程序没有官方提供的可排序列表API,要实现长按拖拽滚动,常见的方案是用movable-area包住被拖拽的项,或者在HBuilderX里引入vant组件库使用拖拽排序组件。我当时让AI用movable-area手写了一个简版,能实现目标但是手感一般,真机上拖动会有轻微掉帧。如果后续有朋友做类似功能,建议直接上vant的拖拽排序,性能和动画流畅度都比自己手写好得多。

4. 开发到发布的完整链路:备案、调试、提审

4.1 准备工作:AppID、开发工具、备案

开发前准备工作绕不过去,而且坑比想象中多。首先是注册小程序账号,地址在微信公众平台,注册时会让你选择主体类型,个人开发就选个人,填身份证信息和手机号就行。注册完成之后拿到AppID,在HBuilderX的uniapp项目manifest.json里,把微信小程序配置项里的AppID填进去。

接下来是开发工具的安装:微信开发者工具是必须的,HBuilderX负责写代码,微信开发者工具负责模拟器调试和真机预览。

然后是一个很多人忽略的环节:小程序备案。现在小程序上线前都要先完成备案,不备案给不了发布权限。备案的时候有一项“备注信息”,很多人不知道怎么填。我当时填的是“为旅行用户提供目的地介绍、路线规划和小程序内工具服务”,没有堆太多功能词,也没写“旅游业务”这种可能触发前置审批的字眼。经验是:备注要贴近你实际提供的服务,但避开需要额外资质的词,比如“旅行社”“OTA”这种,免得被要求补充材料。

4.2 真机调试与体验版

开发调试的时候,模拟器只能验证基础逻辑,很多问题必须真机才能暴露。微信开发者工具里右上角的“预览”会生成一个二维码,用管理员微信扫就能在手机上打开开发版小程序。真机调试模式还能在PC端看日志和网络请求,排查定位问题非常有用。

做了一定功能后,就要上“体验版”了。在小程序后台的“版本管理”页上传代码,把某个版本设为体验版,生成体验版二维码。这里有一个特别常见的报错:“登录用户不是该小程序的开发者”。我第一次遇到的时候愣了半天,代码完全没问题,后来才发现是因为换了一台手机扫码,那个微信号没有加入体验成员列表。解决办法是小程序后台的“成员管理 - 体验成员”里,把测试微信号加进去。审核人员的微信号不需要你加体验成员,这个放心。

体验版测试阶段我建议拉上两三个朋友一起搞,让他们用不同品牌的手机测,最好有iPhone、有小米、有一台华为或荣耀。很多兼容性问题都是在这种“朋友随手点几下”的场景里暴露的,比你一个人埋头模拟器高效十倍。

4.3 提审与发布

提审是小程序上线前的最后一道关卡,也是最容易被驳回的环节。我整理了一下旅行类小程序最常见的驳回点:

第一个是隐私协议。现在微信对“用户隐私保护指引”的审核很严格,如果你的小程序需要位置权限、需要用户上传头像昵称,就一定要在小程序后台的“设置 - 服务内容声明 - 用户隐私保护指引”里明确列出收集哪些信息,用途是什么。我见过太多小程序因为只声明了“收集用户信息”这几个字却被驳回的,一定要具体到“用于展示用户头像和昵称”、“用于获取当前位置以提供周边景点推荐”。

第二个是类目选择。个人主体的小程序类目限制比较多,旅行类内容通常归在“旅游 - 旅游攻略”或“生活服务”类目下,提交时选错类目会被直接拒掉。个人主体做旅行内容没太大商业风险,但如果你加了商城或售卖功能,个体会非常受限,极大概率会被要求用企业主体重新注册。

第三个是内容版权。旅行小程序里我放了照片和景点简介,AI帮我写的文案还好,但图片如果来自网上,审核时被投诉侵权就会出问题。后来我全部换成了自己拍的图和无版权图源,避免踩雷。

提审入口在小程序后台“版本管理”里,提交之后一般一两小时到一两天内出结果。被驳回后不需要慌,后台会写明驳回原因,按原因改完重新提交就行。我第一次提交被驳回,原因是隐私协议不完整,改完之后第二次就过了。

5. 常见问题与避坑实录

5.1 高频问题速查表

把这次开发过程中遇到的高频问题整理了一下,基本覆盖了VibeCoding新手会碰到的绝大部分坑:

问题原因解决办法
云函数调用超时默认超时时间3秒,复杂查询处理不完在小程序后台云开发控制台把超时时间调长,或优化查询逻辑
动态标题设置无效页面json里设置了custom导航栏样式,或调用时机太早检查页面配置,改成单次navbar样式,在数据返回后再setTitle
获取定位一直失败没有声明requiredPrivateInfos或用户隐私协议里没写入位置信息app.json加声明,后台隐私指引补位置信息
登录用户不是该小程序的开发者扫码的微信号没有加入体验成员列表后台成员管理里添加体验成员
鸿蒙系统播放视频黑屏但有声音视频编码格式不兼容,H.265在部分鸿蒙机型上播不了服务端把视频转成H.264编码
地图Key报USERKEY_PLAT_NOMATCH高德后台绑定的AppID和当前编译的小程序AppID不一致核对高德应用配置,重新绑定

5.2 印象最深的三个坑

第一个坑是云数据库权限。开发阶段为了方便,我把集合权限设置成了“所有用户可读写”。这在开发环境没问题,但上线前忘了收,等于任意用户都能通过数据库API修改所有人的收藏数据。这种低级错误一旦出事就不是功能问题,而是安全问题。上线前一定要把权限收缩,通常只保留“仅创建者可读写”加上云函数内部管理接口,前端业务数据全部走云函数。

第二个坑是AI生成的“表面正确”错误。VibeCoding有个特点:AI生成的代码看起来完全合理,但运行起来才发现边界情况全漏。比如列表分页,它只处理了“加载更多”,没处理“没有更多”之后还在继续请求的情况,导致用户在最后一页反复拉到底部就发一次无效请求。这类问题代码层面非常隐蔽,只能通过大量手动点击去发现。

第三个坑是图片资源路径。AI生成的代码里图片用的是相对路径/static/images/xx.png,但我在HBuilderX里实际放文件是放在src/static目录下,编译之后路径就对不上了。折腾了半天,最后统一用云存储的fileID来管理封面图,把图片从静态资源全部切到了云存储,反而一劳永逸。这也算是一个经验:旅行小程序的图片内容多,直接在云存储建一个covers目录,上传后用fileID引用,比打静态包更灵活。

5.3 扩展方向:让这个旅行小程序更好用

上线稳定之后,我又试着加了一些扩展功能,这里记录几个可行的方向。

旅行清单导出Excel。清单页可以加一个“导出清单”按钮,在云函数里用node-xlsx生成一个Excel文件,再通过云存储返回临时链接给用户下载。这个功能对用户很实用,实现也不复杂,唯一要注意的是云函数的内存大小和超时时间,数据量大了以后,生成文件的过程很容易超时。

微信跳转链接做回流。微信提供了URL Scheme拉起小程序的能力,典型链接是weixin://dl/business。这个适合在短信、邮件、公众号文章、外部网页里做用户回流,生成方式有两种:一种是小程序后台“工具”里手动生成,另一种是通过接口动态生成。需要注意两点:第一,生成时path要拼完整的参数,否则拉起来之后进不了指定页面;第二,实测在微信聊天窗口里直接点这个链接是点不开的,需要复制到短信或浏览器再唤醒,所以使用场景要想清楚。

多人协同编辑行程。云开发有实时数据推送能力,天然适合做多人协同场景。几个人在同一趟旅行里可以共同维护一份行程清单,有人新增了景点,其他人手机上实时出现。这个功能如果自己搭WebSocket会很痛苦,但云开发可以省去大部分连接管理的工作,是性价比很高的增强方向。

写在最后

三周做下来,我的真实体会是:VibeCoding不是银弹,它更像在训练一个精力旺盛但偶尔粗心的实习生。你仍然是那个要对代码负责的人,甚至要比以前更懂边界、更懂安全、更懂怎么描述需求。如果你也想试,建议从旅行清单、打卡地图这种小而完整的场景入手,把闭环跑通再扩展。一上来就追求大而全的电商系统,你会被AI生成的订单状态机逼疯。先让一个功能能跑,再让一套流程能发,这个节奏最稳。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 23:19:37

基于Django与ECharts的考研院校推荐系统:爬虫、可视化与算法实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 23:16:23

爱普生L8058与L8168对比:ICC校色文件安装验证全指南

最近被问得最多的两台打印机&#xff0c;一个是爱普生L8058&#xff0c;一个是L8168。问的人基本都带着同一个问题&#xff1a;差价摆在那里&#xff0c;贵的到底值不值&#xff1f;我自己的答案是&#xff1a;如果只打彩色A4照片&#xff0c;L8058完全够用&#xff1b;如果你经…

作者头像 李华
网站建设 2026/9/15 23:15:09

从等任务到主动侦察:测试新人摆脱学生思维的进阶指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 23:14:16

游戏评测网站有哪些

游戏评测网站有哪些&#xff1f;找客观评价看这几个入口 游戏评测网站有哪些&#xff0c;随着近年来多款高宣发 3A 商业大作在发售时出现口碑崩盘、优化翻车&#xff0c;很多玩家越来越不敢轻易盲目预购。然而在信息获取上&#xff0c;玩家又经常被“先发评测特权被厂商绑架”、…

作者头像 李华
网站建设 2026/9/15 23:10:05

HTML网页制作入门:从零构建你的第一个页面

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 23:06:47

2T增益单元:破解AI芯片内存墙的高密度片上存储方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华