ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

uni-app购车车小程序源码解析:从工程结构到微信小程序上线实践

uni-app购车车小程序源码解析:从工程结构到微信小程序上线实践 简介一份基于uni-app框架开发的购车车小程序完整源码包面向想快速上手小程序跨平台开发、或需要汽车销售业务参考的开发者。项目采用Vue语法构建覆盖车辆展示、分类、购物车、个人中心等典型页面并通过uni-app统一接口适配微信、支付宝等多端适合作为课程设计、毕业设计或企业Demo的起点。资源共30个文件以png图标素材、vue页面组件、json配置和入口文件为主另含scss样式、js逻辑与ttf字体整体仅66KB但目录结构清晰保留了完整项目骨架。对于刚接触uni-app的开发者来说可直接导入HBuilderX运行调试。已有386人学习下载。读者可从中看到小程序的页面组织方式、组件化写法、tab栏配置和静态资源管理思路也能理解多端页面与生命周期管理方式便于在此基础上继续扩展预约试驾、在线购车等业务模块。1. 基于uni-app的购车车小程序源码不是拿来就能跑的先看这套工程很多人下载“基于uni-app开发购车车小程序源码.zip”后第一反应是解压扔进HBuilderX结果一堆红色报错。原因多半不是代码问题而是没搞清这个源码是 Vue 2 还是 Vue 3、用 CLI 初始化还是 HBuilderX 创建、依赖装了没有。购车车这类业务小程序通常包含车辆展示、报价计算、预约试驾、线索留资页面多、组件杂跨端需求明显用 uni-app 做工程化是最常见的选择。下面会从源码包结构讲起带你把它跑起来、改业务、处理微信小程序特有的坑最后落到上线前的检查项。适合拿到源码不知从哪下手的初学者也适合想把自己的项目从原生小程序迁移到 uni-app 的工程师。2. 先读懂 uni-app 购车车源码包的目录与配置再谈运行2.1 解压后的标准工程长什么样uni-app 项目不管叫什么名字核心目录和文件几乎是固定的。区别于原生小程序它多了 App.vue、main.js、manifest.json、pages.json 这些“编译器认识”的入口。购车车这种垂直业务源码包里的 pages 通常按业务模块分目录pages/index 首页、pages/cars 车型列表、pages/detail 车辆详情、pages/order 订单和预约、pages/user 个人中心。下面是一个典型项目解压后的目录用 tree 命令看# 先看整体结构 unzip 基于uni-app开发购车车小程序源码.zip -d gc_src cd gc_src tree -L 2 -I node_modules|dist|unpackage | head -60输出信息量很大package.json 提供了依赖和脚本命令manifest.json 是应用级配置pages.json 管理页面路由和导航栏App.vue 是全局生命周期和样式。不建议一上来就改代码先把这些文件过一遍。注意 tree 命令里-I用于排除 node_modules、dist、unpackage 目录如果不排除你看到的全是第三方编译产物没法判断业务代码。下面用表格收一下关键路径省得后面走弯路路径/文件在 uni-app 里的职责购车车项目里常见内容pages.json页面注册、tabBar、导航栏样式、页面级配置5 个 tabBar 页面、全局主题色manifest.json应用名称、appid、vue 版本、各端 SDK 配置mp-weixin.appid、h5.router.basemain.js创建 Vue 实例并挂载注册全局组件import App from ./AppApp.vue应用生命周期 onLaunch全局样式登录态检查、初始化地理位置pages/页面级 .vue 文件车辆列表、详情、报价、预约components/可复用组件车型卡片、价格组件、空状态static/静态图片、字体等原样打包logo、车辆图、iconfontuni.scssuni-app 内置样式变量品牌色、圆角、阴影变量store/状态管理如 pinia/vuex当前选择的城市、车型筛选状态表格的作用比单纯看代码更直观static 里的文件会原封不动进 distpages 里的会被编译成小程序页面 JS。如果你在 pages 里写了不规范的 import编译报错时优先检查这里。2.2 判断源码依赖的是 Vue 2 还是 Vue 3用一个命令拿到源码后的第一件事不是运行而是查 package.json。HBuilderX 的 Vue 2 项目在 Vue 3 编译器下会报 “Cannot find module dcloudio/uni-app”反过来 Vue 3 项目在 Vue 2 编译环境里也会出各种奇怪问题。我一般会先执行cd gc_src cat package.json | grep -E (vue|dcloudio/uni-app) npm ls vue --depth0 2/dev/null || echo vue not installed yet判断逻辑很简单如果 dependencies 里 vue 版本是 2.6.xdcloudio 相关包版本是 2.x那这是 Vue 2 版本。如果 vue 是 3.x而且有 dcloudio/uni-app 的 3.x 包那就是 Vue 3 版。如果 HBuilderX 项目通常可能没有 package.json直接看 manifest.json 里的vueVersion字段。注意 grep 命令里我用了双引号包住 vue避免把 dcloudio/uni-app 这类包含 vue 字段的包也带出来。npm ls vue是在本地已安装依赖时更精确的检测方式能直接告诉你依赖树是否完整。另外一个容易忽略的点完整源码包里的 uni_modules 目录。现在很多 uni-app 插件比如 uni-ui、easycom 组件都放在 uni_modules 下它自带独立编译机制。如果源码里有这个目录首次运行会自动加载 uni_modules 组件这时别手滑删掉。2.3 路由和导航栏的配置习惯pages.json 是购车车的门面购车车这类偏展示型的小程序页面层级不会很深但导航栏需求丰富。首页可能需要自定义搜索框详情页可能要隐藏原生导航栏改用沉浸式这时候得在 pages.json 里按页面覆盖。看一段典型配置{ pages: [ { path: pages/index/index, style: { navigationBarTitleText: 购车车, enablePullDownRefresh: true } }, { path: pages/cars/list, style: { navigationBarTitleText: 全部车型, navigationStyle: custom } } ], globalStyle: { navigationBarTextStyle: white, navigationBarTitleText: 购车车, navigationBarBackgroundColor: #121317, backgroundColor: #F5F6FA }, tabBar: { color: #9FA0A3, selectedColor: #3478F6, list: [ { pagePath: pages/index/index, text: 首页 }, { pagePath: pages/cars/list, text: 车型 }, { pagePath: pages/user/index, text: 我的 } ] } }navigationStyle设为 custom 后原生导航栏会消失整个页面从顶部开始渲染。此时你需要考虑状态栏高度和胶囊按钮位置后面 4.2 会专门讲怎么适配。先记住两个字段navigationBarTitleText控制标题文字navigationStyle控制导航栏是否原生。这段配置里只给首页开了下拉刷新全局没开避免每个页面都在无意义的 pull-down 事件里刷接口浪费流量也容易在调试时产生大量 loading 遮罩干扰。3. 用 HBuilderX 和 CLI 两条路把源码跑成微信小程序3.1 路径一HBuilderX 导入源码最省事的启动方式如果你的源码是用 HBuilderX 创建的标准 uni-app 工程最快的方式是打开 HBuilderX菜单栏「文件 - 导入 - 从本地目录导入」选择解压后的 gc_src 文件夹等待索引完成。然后确认两件事manifest.json 里「微信小程序配置」的 AppID 是否填写「运行 - 运行到小程序模拟器 - 微信开发者工具」是否已经配置了微信开发者工具的安装路径。这里有一个容易忽略的点HBuilderX 会把项目的编译缓存放在 unpackage 目录下。如果你的源码包是从队友那儿拷来的unpackage 目录里残留的是别人电脑上的编译信息最好先删掉这个目录再导入否则可能出现页面改动了模拟器里却是旧代码的情况。rm -rf gc_src/unpackage gc_src/dist # 然后重新在 HBuilderX 里运行强迫重新编译unpackage 目录和 dist 目录是同一类角色都是编译产物删了不会有任何问题。别担心删错Git 仓库里本就不该提交它们。3.2 路径二CLI 方式跑通适合 CI 和多人协作不少源码包也可能是通过命令行脚手架创建的目录里带了 package.json 和 vite.config.jsVue 3 项目常见。这时 HBuilderX 反而不是最好的选择因为编译器版本可能与项目依赖不一致。更稳妥的方式是用 npm 来管理npm install npm run dev:mp-weixin执行完 dev:mp-weixin 后产物会输出到 dist/dev/mp-weixin。打开微信开发者工具选择「导入项目」目录指向这个 dist/dev/mp-weixinAppID 填你自己申请的测试号或者使用测试号就能看到项目跑起来了。参数说明npm install会按 package.json 安装依赖如果源码里有 lock 文件package-lock.json装上后版本更稳定。npm run dev:mp-weixin会以 watch 模式监听源码改动每改一次都重新编译并刷新微信开发者工具调试阶段不要关掉这个进程。如果 package.json 里没有 dev:mp-weixin 脚本检查 scripts 字段常见的 uni-app 脚本还有 dev:h5、build:mp-weixin。没有的话先看是不是 dependencies 不全或者项目是基于 Vue 2 的 HBuilderX 工程而不是 CLI 工程。3.3 运行阶段最常见的 3 个报错运行过程里碰到问题不要慌按优先级查三个地方。第一个是 AppID 未配置微信开发者工具会提示「appid 不存在」第二个是基础库版本不匹配页面白屏或者提示 xxx 方法不存在第三个是编译器的 Vue 版本与 manifest.json 里的 vueVersion 不一致。现象可能原因处理方法模拟器里空白且报 Invalid appidmanifest.json 中 mp-weixin.appid 为空填入自己小程序的 appid或去微信公众平台申请测试号页面报 Cannot read properties of undefined (reading xxx)基础库版本太低不支持可选链/新 API在微信开发者工具「详情 - 本地设置 - 调试基础库」切到 2.30.0启动就报 uni is not defined编译器版本混乱小程序端运行时没有正确注入删除 node_modules 和锁文件重新 npm install或改用 HBuilderX 运行第四行是我额外补的因为这类问题在接手二手源码时太常见了。uni 这个全局对象在小程序端不是原生存在的它由 uni-app 运行时注入。如果你的代码里混入了外部的 uni-app 插件或者手动 import 了dcloudio/uni-app但没安装对应依赖就会触发这个报错。3.4 微信开发者工具里的几个项目级配置项目跑起来后建议先统一配置好「本地设置」。具体来说三个开关需要固定下来ES6 转 ES5 打开因为部分 Android 微信内置浏览器内核不支持完全 ES6上传代码时自动压缩混淆打开不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书关闭调试阶段先关掉域名校验否则接口请求全是request:fail url not in domain list。但在联调和上传体验版之前必须换成合法域名。提示这些配置只需要在微信开发者工具「详情 - 本地设置」里勾选。一旦切换成正式版微信后台会对 request、uploadFile 等接口做域名白名单校验开发阶段的任何绕过手段都会失效这是从源码跑通到联调之间最不容易绕过的一步。4. 购车车业务改造从车辆列表到动态标题再到 webview 通信4.1 车辆列表页的触底加载与筛选条件购车车小程序最核心的页面是车辆列表通常长这样顶部是品牌、价格筛选下面无限滚动加载车型数据。用 uni-app 写这种页面不需要额外引入第三方库原生 API 就够。下面是一个精简版的列表页脚本去掉了样式只保留逻辑template view classcar-list scroll-view scroll-y classlist-scroll scrolltolowerloadMore view v-foritem in cars :keyitem.id classcar-item tapgoDetail(item) text classname{{ item.name }}/text text classprice¥{{ item.price }}万/text /view /scroll-view /view /template script setup import { ref, onMounted } from vue const cars ref([]) const page ref(1) const pageSize 10 const finished ref(false) async function fetchCars() { try { const res await new Promise((resolve, reject) { uni.request({ url: https://api.example.com/cars, data: { page: page.value, pageSize }, method: GET, success: resolve, fail: reject }) }) const list (res.data res.data.list) || [] if (list.length) { cars.value cars.value.concat(list) const hasMore res.data.hasMore ! false finished.value !hasMore page.value 1 } else { finished.value true } } catch (e) { finished.value true } } function loadMore() { if (finished.value) return fetchCars() } function goDetail(item) { uni.navigateTo({ url: /pages/detail/index?id${item.id} }) } onMounted(fetchCars) /script逻辑核心是三个状态cars 存放已加载的车辆page 记录当前页码finished 标记是否还有更多。loadMore 由 scroll-view 的scrolltolower触发它的语义是滚动到底部比页面级的 onReachBottom 响应更及时因为 scroll-view 可以只让列表区域滚动导航栏和筛选条件保持悬浮。参数说明uni.request不是天然返回 Promise这里用new Promise包一层把 success 和 fail 对应到 resolve 和 reject这样可以用 async/await 写异步逻辑代码可读性更好。data.hasMore是后端字段约定换成 total 或 has_next 都行关键是字段语义要在接口文档里对齐。goDetail 用uni.navigateTo跳转详情页并把 id 拼在 query 里这是小程序页面间传参最轻量的方式不需要引入全局 store。这里的坑在于很多后端接口会把分页字段写成 pageNum 和 pageSize但这套代码里用了 page 和 pageSize。接手二手源码时最怕这种驼峰/短横线不一致调试时看 Network 面板确认实际发出的参数别只盯着前端页面。4.2 动态设置导航栏标题与顶部安全区适配车辆详情页往往需要根据车型名称动态修改小程序标题。原生小程序的navigationBarTitleText是在 pages.json 里静态配置的而 uni-app 的页面级配置可以这样覆盖// 详情页 script setup 中 import { onLoad } from dcloudio/uni-app onLoad((options) { const modelName options.name || decodeURIComponent(options.name || ) if (modelName) { uni.setNavigationBarTitle({ title: modelName }) } uni.setNavigationBarColor({ frontColor: #ffffff, backgroundColor: #121317 }) })注意setNavigationBarColor的 frontColor 只支持#ffffff和#000000两个值这是微信小程序的硬性限制。如果你在 Android 上设置了一个灰色最终会变成黑色或白色所以别在这个 API 上做太多品牌色幻想。上面说的 navigationStyle: custom 是沉浸式页面导航栏占位没有了需要自己算状态栏高度。一般做法是在 App.vue 的 onLaunch 里读取系统信息存到全局export default { onLaunch() { const { statusBarHeight, safeAreaInsets } uni.getSystemInfoSync() uni.$gStatusBarHeight statusBarHeight if (uni.getMenuButtonBoundingClientRect) { const menuButton uni.getMenuButtonBoundingClientRect() uni.$gNavBarHeight (menuButton.top - statusBarHeight) * 2 menuButton.height } } }用变量名$gStatusBarHeight是要把这两个值存起来后续页面通过uni.$gStatusBarHeight读取。常见做法是在自定义导航栏组件内部计算这里给出的是全局存储的最小实现。需要注意的是getMenuButtonBoundingClientRect 只在微信小程序端存在H5 端没有调它的必要所以代码里加了判断。4.3 webview 内嵌 H5 页面与小程序通信购车车优惠活动、车型参数详情页常常用 webview 直接内嵌 H5。微信小程序和 H5 的通信不是双向透明的需要借助 postMessage 和 uni.webview.js。uni-app 里加载 webview 很简单template web-view :srcwebUrl messageonMessage/web-view /template script setup import { ref } from vue const webUrl ref(https://h5.example.com/car-detail?id123) function onMessage(e) { console.log(来自 H5 的消息, e.detail.data) // e.detail.data 是数组里面是 H5 侧 postMessage 传来的参数 } /script关键点在于H5 侧必须引入 uni 的 webview 桥接脚本并在页面回跳或用户主动操作才能触发 message。直接用 window.parent.postMessage 是没有用的微信小程序和浏览器 iframe 的通信协议不同。H5 侧示例script srchttps://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.js/script script if (window.uni) { window.uni.postMessage({ data: { type: carQuery, id: 123 } }) } /script如果你收到的 message 一直为空先检查是不是 H5 页面在 onLoad 时立刻 postMessage。微信限制只有用户点击、页面后退等特定时机才会把消息传给小程序所以很多项目会做一个按钮来触发向小程序传数据而不是一进去就传。这一点也和常见问题“uni-app 微信小程序 webview 如何像 h5 通信通信”是同一套解法bridge 脚本加 message 通道。4.4 处理二手源码里常见的运行时白屏和类型错误好多人在这个阶段碰到 uncaught typeerror: cannot read properties of undefined (reading list) 这类错误第一反应是数据结构不对但实际上是编译器转译导致的问题。如果源码写的是const { list } response.data而 response.data 在失败时没有返回就会在解构处崩溃。兜底写法是const list response?.data?.list || []不要在源码里到处加问号关键接口做一次兜底就好。另一种常见原因是你把编译基础库切得太低比如 2.14.0 之前的版本对可选链的支持不完整导致使用了?.的代码在低版本微信上直接报错。建议至少切到 2.20.0 以上同时构建时开启降级。下面这个表可以帮你快速对照错误信息检查位置处理方式Cannot read properties of undefined接口返回结构加?.或 web-view 页面空白业务域名配置微信后台配置业务域名并下载校验文件setNavigationBarColor 不生效基础库版本升级基础库到 1.4.0 以上用黑/白两色5. 上线前必做的 5 个检查包体、分包、体验版、真机和域名白名单最后这一章直接给出一份可勾选的清单都是我接手这类购车车小程序时反复踩过的点。第一检查包体大小。微信小程序主包限制 2MB超过了就 upload 失败。用命令看编译产物du -sh dist/build/mp-weixin find dist/build/mp-weixin -name *.js -size 500k -exec ls -lh {} \;如果主包超了优先把车辆列表、详情页拆到分包里。在 pages.json 里加 subPackages 节点比如车辆的车型库、图片素材、活动页都丢进去保证启动页只有 index 和登录相关的页面。第二配置 manifest.json 中mp-weixin.lazyCodeLoading为requiredComponents同时开启optimization.subPackages让页面按需注入。这两个配置不是默认打开的但打开后首屏能少加载 30% 到 50% 的 JS体感变化非常明显。第三体验版之前必须测一遍真实登录和支付流程。购车车业务如果走微信支付要确认 requestPayment 的参数是从后端签名而来而不是前端写死。联调时打开微信开发者工具的「真机调试」而不是「模拟器」模拟器里的 wx.login 拿到的 code 很多时候和真机行为不一致。第四检查 request 和 uploadFile 的域名是否已经填到微信公众平台后台的「开发管理 - 开发设置 - 服务器域名」。开发时关掉校验没问题但上线后任何一个接口走的是 http 或 IP 地址都会在小程序里直接失败。建议直接在代码里用环境变量区分 dev / prod避免漏改。第五梳理 webview 的 businessDomain。如果你用了 4.3 里的 webview除了 request 合法域名还要在小程序后台把 H5 域名配置到业务域名里并且下载校验文件放到 H5 服务器根目录。这个环节经常被忽略导致 H5 页在真机预览时白屏但开发者工具里正常。最后提一个提升效率的技巧在每次提交代码后自动构建并推送预览二维码省得测试人员每次找你要体验版。脚本只需要两条命令uni build -p mp-weixin和 miniprogram-ci 的 upload 命令后者引入miniprogram-ci包即可。别让手工打包占用你的开发时间。本文还有配套的精品资源点击获取
返回列表