尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

UniApp实战:美妆教程小程序从开发到上线的完整方案

发布时间:2026/9/24 20:34:53

资讯中心
01
ARTICLE

UniApp实战:美妆教程小程序从开发到上线的完整方案

UniApp实战:美妆教程小程序从开发到上线的完整方案
做个美妆教程小程序是我今年开春接到的一个比较完整的商业项目。甲方要的不是简单的内容展示而是一个集视频教程、图文专栏、社区晒妆、课程购买于一体的平台。技术栈当时锁死微信小程序 UniApp。花了两周时间搭完基础版又用了一个多月打磨细节、过审核整套体系已经稳定跑在线上。这篇文章把我从技术选型、目录搭建、核心模块实现到真机调试、审核上线的完整思路和踩坑记录写出来。如果你正打算用UniApp做内容社区类小程序或者单纯想看看美妆教程这类垂直平台有哪些技术细节这篇文章应该能帮你省下不少弯路。1. 美妆教程平台的技术选型为什么我放弃了原生小程序1.1 项目最初的需求边界做任何技术方案前我习惯把需求拆到不能再拆为止。这个平台的核心用户是爱化妆、想学化妆的年轻女性她们不仅在微信里找教程很可能也装在安卓App、iOS App甚至通过H5在公众号里看。甲方最开始只提“微信小程序”但我问了三句话以后要不要做App公众号文章里要不要嵌教程内容后台要不要用网页管理答案都是“要”。这就意味着如果直接用微信原生语法开发三个月后做App等于全部重写。用UniApp一套代码可以同时编译到微信小程序、App、H5后台管理页面也能顺手做成H5。这正是我选UniApp的根本原因——它的跨端能力对这个项目的长期演进是刚需。1.2 UniApp与原生小程序、Taro的取舍现在提到跨端框架很多人会拿UniApp和Taro比。Taro是React语法UniApp是Vue语法。我的团队更熟Vue且UniApp生态里的插件市场对小程序场景覆盖更全视频、富文本、分享、支付都有现成方案所以直接选UniApp。相比之下原生小程序的问题不在于写不了而在于业务逻辑、状态管理、组件复用都要从头造轮子项目一旦做大维护成本翻倍。再补充一个实际体验UniApp从vue2升级到vue3之后性能提升明显我们用的就是vue3版本。如果你现在起步建议直接npx degit dcloudio/uni-preset-vue#vite my-project创建项目vite编译速度比webpack快好几倍。1.3 美妆内容平台需要的核心能力清单美妆教程平台不是简单地把视频列表放出来它需要一套完整的内容闭环教程分类按肤质、部位、风格、难度划分支持多级筛选视频教程在线播放、清晰度切换、进度记忆图文教程分步骤展示支持图片、文字、产品链接专栏体系化妆师入驻、专栏订阅、付费解锁社区互动发布晒妆图、评论、点赞、收藏用户体系微信登录、会员权益、积分体系后台配套内容管理、数据统计、广告位配置这些能力用UniApp都能在现有组件和插件基础上二次开发不需要碰原生。如果某天某个页面性能扛不住UniApp还支持编写小程序原生代码混用逃生通道很通畅。2. 项目从0搭建目录结构、全局配置与主题设计2.1 vite工程化的目录规划我倾向于在一开始就把目录结构定得清晰一些免得后期大挪移。以下是我实际使用的结构你可以直接抄├── src │ ├── api # 接口请求统一封装 │ │ ├── modules │ │ │ ├── tutorial.js # 教程相关接口 │ │ │ ├── user.js # 用户相关接口 │ │ │ └── community.js # 社区相关接口 │ ├── components # 全局可复用组件 │ │ ├── tuiVideo # 视频播放器封装 │ │ ├── tuiNavBar # 自定义导航栏 │ │ └── tuiLoadMore # 列表加载更多 │ ├── pages │ │ ├── index # 首页 │ │ ├── tutorial # 教程列表与详情 │ │ ├── community # 社区 │ │ ├── user # 个人中心 │ │ └── webview # 内嵌网页 │ ├── store # Pinia状态管理 │ ├── static # 静态资源 │ ├── styles # 全局样式变量 │ ├── utils # 工具函数 │ └── uni_modules # uni-app插件api层刻意按业务模块划分避免一个api.js几千行。每个请求我都返回Promise方便在页面里await。store选用Pinia比vuex轻很多类型提示也更好。2.2 manifest.json里必须配好的几项微信小程序能正常运行manifest.json是最关键的入口。很多新手卡在“编译出来白屏”上十有八九是这里配置不对。我列几个重点appid必须填真实的小程序appid不能留测试号。测试号在调用登录、支付等能力时会直接报错。权限声明美妆教程需要上传图片、拍摄视频所以mp-weixin的permission里要配scope.writePhotosAlbum、scope.camera并写好中文描述。定位权限如果后续要做本地门店推荐需要声明requiredPrivateInfos里的getLocation微信2022年后收紧了这个。使用隐私协议在mp-weixin的__usePrivacyCheck__设为true同时在小程序管理后台配置《用户隐私保护指引》否则真机调试会弹窗提示隐私未声明。2.3 全局主题色与设计变量美妆平台天然适合柔美、偏女性的视觉风格。我在styles/variables.scss里统一管理颜色和字号$primary-color: #FF6B9D; $primary-light: #FFB3C7; $bg-page: #F8F7FC; $text-main: #333333; $text-sub: #999999; $radius-lg: 24rpx; $radius-md: 16rpx;用变量最大的好处是后期品牌方想换个主色改一行就能全局生效。另外rpx是微信小程序的响应式单位UniApp在App/H5端也会自动换算所以放心用rpx做内边距和字体大小不需要手写媒体查询。3. 教程内容体系视频、图文、课程购买的实现细节3.1 首页信息流分类导航与沉浸式推荐美妆用户的时间很碎片化首页必须让她三秒内看到想看的教程。我的实现思路是顶部搜索框 横向滚动分类栏 纵向视频卡片列表。搜索框在首页最显眼的位置。输入关键词后调用/api/tutorial/search后端用Elasticsearch做模糊匹配支持“眼影”“口红”“油皮”等词。搜索历史要存在本地storage下次进来直接展示。分类栏用scroll-view横向滚动一屏放六七个分类足矣。点击分类后首页下方列表切换数据。这里要注意别用页面跳转去承载分类切换太生硬直接在页面内通过switchTab或setData刷新列表数据体验更接近原生App。视频卡片我封装了tuiVideo组件内部使用uni-app的video标签。卡片在首页只展示封面和标题点击进入详情页才真正播放。这样能显著降低首页的内存开销避免多个视频同时加载导致小程序卡死。3.2 视频详情页播放器封装与进度记忆视频详情页是美妆教程的核心做不好会被用户秒退。我实现了这几个功能封面占位点击播放播放中记住进度退出后再次进入询问是否续播倍速播放0.5x-2.0x清晰度切换如果后端有多码率进度记忆的实现很简单在video的onTimeUpdate回调里每5秒把currentTime存到storagekey用tutorial_video_progress_${id}。首次播放时取出来判断是否大于10秒是则弹窗“上次看到3分12秒继续观看吗”。倍速播放用video标签的playbackRate属性uni-app直接支持。需要注意的是部分安卓机型在切换倍速后会出现音画不同步我遇到过一次最后是在切换后重新play一次解决。清晰度切换比较复杂需要后端提供多码率地址。我这边是先请求/api/tutorial/{id}/playinfo拿到{ sd, hd, fhd }三个地址点击清晰度后替换video的src。实测在微信小程序里切换清晰度会短暂黑屏这是正常现象只要在bindwaiting事件里显示loading提示即可。3.3 付费教程与虚拟支付限制微信小程序的边界美妆教程有一部分是付费专栏。这里必须提醒你一个微信小程序铁律虚拟商品在线课程、会员、解锁视频不能在小程序里直接使用微信支付。微信要求虚拟支付必须走虚拟支付2.0安卓可以用iOS不可用实际上苹果会有30%抽成微信小程序干脆禁止在iOS端做虚拟支付。我们最终的方案是iOS端付费课程直接隐藏购买按钮显示“请前往公众号或App购买”安卓端使用微信支付。这是在合规前提下的折中方案你也可以结合自己的业务申请虚拟支付能力但审核周期长、条件苛刻多数小团队都是先绕过。3.4 图文教程用mp-html解析富文本美妆图文教程通常包含步骤图、List文本、产品推荐卡片。后台编辑器输出HTML小程序端不能直接渲染。这里强烈推荐mp-html插件它支持富文本渲染、代码高亮、图片懒加载是对原生rich-text的完美替代。安装方式npm install mp-html页面中使用mp-html :contenttutorialContent linktaponLinkTap /我在图文教程中还嵌入了“产品信息卡片”通过自定义product-card标签解析。只需在mp-html的tag配置里注册自定义组件就能在富文本中渲染出商品卡片底部带一个“去购买”按钮跳转至淘宝/京东。这套方案比手写富文本编辑器高效得多。4. 社区互动模块帖子、评论、点赞与微信登录打通4.1 微信登录一键搞定用户体系用户在小程序里做任何互动都需要先登录。以前微信小程序可以直接通过uni.login拿到code传给后端换取openid。现在微信对隐私要求严格了uni.getUserProfile不能随意调用必须在用户点击按钮时触发。所以我的落地做法是页面内部任何需要用户身份的操作先检查本地storage里是否有token没有则弹出自定义登录弹窗弹窗里有一个“微信一键登录”按钮用户点击后const { code } await uni.login() const { openId, token } await api.userLogin({ code })这里secure: 后端通过code调用微信接口取openid并生成自己的token返回给前端。前端把token存在storage里后续请求带Authorization头。用户头像昵称不强制获取如果她是美妆达人再去个人中心引导完善资料这样比一上来就要授权更友好。4.2 帖子发布图片上传与压缩技巧社区晒妆的核心是发图。UniApp的uni.chooseImage可以选图但微信小程序默认上传的临时文件路径可能比较大不处理的话上传慢、后端压力大。我封装了compressImage方法async function compressImage(filePath) { const output await new Promise((resolve) { uni.compressImage({ src: filePath, quality: 70, success: resize resolve(resize.tempFilePath) }) }) return output }图片真正的缩放要在后端或云存储做小程序端压缩到质量70能大幅减少体积。另外多图上传务必用Promise.all并发而不是for循环一个个排着传速度能提升好几倍。4.3 评论与点赞的即时反馈为了互动体验流畅评论和点赞我都做了乐观更新。用户点“赞”后先在前端把数量1、图标变红再异步请求后端。如果请求失败就回滚。这种交互在弱网环境下特别重要美妆用户刷社区最烦转圈。要注意的是点赞按钮点击事件要节流防止用户连点导致重复请求。我写了个简单的throttle函数const throttle (fn, delay 500) { let last 0 return function (...args) { const now Date.now() if (now - last delay) { last now fn.apply(this, args) } } }4.4 微信订阅消息教程更新提醒订阅消息是内容平台召回用户的重要工具。用户关注某位化妆师后可以请求订阅一次“教程更新”通知。用uni.requestSubscribeMessage唤起订阅面板传模板iduni.requestSubscribeMessage({ tmplIds: [模板ID在微信后台申请], success(res) { if (res[模板ID] accept) console.log(订阅成功) } })这里有个经验一次性订阅只能发一次要在合适的时机引导再次订阅。比如用户看完教程后弹窗提示“关注Ta下次上新第一时间通知你”这个场景的订阅接受率远高于首页弹窗。5. 跨端适配与真机调试我在iOS和安卓上踩过的坑5.1 自定义导航栏顶部高度到底怎么算美妆教程页面对沉浸式体验要求很高默认导航栏的白底和黑字太生硬。我们用了自定义导航栏最常见的问题就是顶部安全区高度算不对导致标题被刘海屏遮住。统一计算公式如下写进工具函数export function getNavBarHeight() { const { statusBarHeight, platform } uni.getSystemInfoSync() const capsule uni.getMenuButtonBoundingClientRect() // 胶囊按钮位置 const capsuleTop capsule.top const capsuleHeight capsule.height const navBarHeight (capsuleTop - statusBarHeight) * 2 capsuleHeight return { statusBarHeight, navBarHeight, totalHeight: statusBarHeight navBarHeight } }原理是胶囊按钮垂直居中于导航栏用胶囊上间距×2加上胶囊高度就能反推导航栏的高度。不同机型都能自适应。拿到totalHeight后设为自定义导航栏的占位高度header里的内容用flex居中即可。5.2 iOS静音模式下视频无声的解决方案这个坑绝大多数人都会踩iOS用户把手机侧面静音键拨下来后视频的音量也变静音了。对看教程的人来说声音几乎不可或缺。默认情况下WXVideo在iOS支持静音键控制要让它忽略静音键继续发声需要设置uni.setInnerAudioOption({ obeyMuteSwitch: false, // iOS静音模式下仍播放 mixWithOther: true, // 不打断其他音频 success() {} })这段代码在播放器初始化后调用一次即可。实测在微信小程序iOS端有效App端也适用。如果你是做教学视频、音频课一定要加上否则大量iOS用户会反馈“没声音”。另外安卓机在资源紧张时会回收播放器导致切后台再回来视频黑屏。我通过在页面onHide时暂停播放、onShow时恢复播放记录时间来解决。5.3 web-view高度自适应与返回拦截社区里的部分活动页以及付费课程详情页我们用了web-view内嵌H5。最烦的就是高度web-view默认高度铺满屏幕但H5内部滚动条会和小程序页面一起滚很别扭。我的做法是H5端和web-view各司其职web-view页面内部使用iframe滚动小程序端不处理滚动。具体是让web-view高度始终等于可视区高度H5内部自己滚动。对用户来说这就是正常的网页体验。web-view返回拦截是另一个大坑。用户从web-view进入内嵌页点左上角返回默认是直接退出到上一个小程序页面而不是H5历史回退。解决办法是给web-view添加message监听并配合wx.miniProgram.navigateBack做交互。我在H5里封装了// H5端 function webviewBack() { const url window.location.href wx.miniProgram.postMessage({ data: { type: back, url } }) wx.miniProgram.navigateBack({ delta: 1 }) }小程序端用bindmessage接收消息如果是back类型就控制web-view的src回退。这里没有标准方案要根据你的业务来设计。重要的原则永远不要让用户被困在web-view里。5.4 底部导航切换闪烁问题用UniApp写tabBar页面有时候从A页切到B页底部导航会闪一下白条。这个问题的根源在于页面切换时新页面还没渲染完底部tabBar和内容区短暂分离。解决办法不要用uni.switchTab直接切换改用uni.reLaunch或延时跳转并给页面根元素加淡入动画。实测在switchTab前显式调用uni.hideTabBar()、动画结束再uni.showTabBar()也能缓解闪烁但不彻底。如果只是tab页面之间相互更新数据我建议用状态管理Pinia共享数据不要在新页面onShow里触发大量网络请求否则每次都重新渲染列表闪烁必然明显。5.5 视频下载、图片长按这些容易被忽略的边界美妆教程的视频内容版权很重要要防止被下载。微信小程序里视频默认不显示下载按钮但安卓端可以长按视频出现“保存视频”选项。我处理的方式给video标签加show-progress和show-fullscreen-btn属性同时设置controls为true但不开启enable-progress-gesture可疑。真正有效的做法是服务端限制播放域名、加密视频地址带签名和时间戳、禁止第三方播放器。前端防下载只能防君子防不住逆向但至少别把直链轻易暴露给用户。图片长按在小程序里也会触发微信默认菜单保存图片、识别二维码。如果你不希望用户保存教程里的步骤图可以在image组件上添加show-menu-by-longpress为false默认true实际默认是false需要设置才弹出菜单不想弹出就别设。如果要做个人作品建议保留长按保存的交互方便用户收集喜欢的妆容样式。6. 上线前必查隐私政策、审核规范和代码保护6.1 微信审核对美妆类内容的特殊要求美妆教程属于“美容美体”类目审核时容易踩这两条不得涉及医疗功效宣传。比如“祛斑”“美白针”“永久脱毛”这类词会被打回要改成“遮瑕”“提亮”“日常脱毛护理”。不得出现夸大承诺。教程里不能说“三天变白”“七天换脸”但这些是编辑文案会自然写出来的词。我专门加了内容审核关键词过滤在发布教程时自动拦截敏感词并替换为合规表述。另外平台涉及用户生成内容UGC必须有“举报”按钮和后台删帖能力审核人员会检查社区内容是否有风险。没举报入口的小程序大概率被打回。6.2 隐私政策弹窗与用户信息合规2023年起微信强制要求小程序配置用户隐私保护指引且在调用隐私接口前弹出隐私弹窗否则真机调试和审核都会失败。UniApp里推荐用uni.getPrivacySetting和uni.requirePrivacyAuthorize来主动触发隐私授权。需要先在小程序管理后台的“用户隐私保护指引”里声明你要收集的信息手机号、相册、位置等并关联对应的接口。我这边在App.vue的onLaunch里异步请求隐私状态如果用户未同意弹自定义隐私弹窗点击“同意并继续”后再调用uni.requirePrivacyAuthorize({ success() {} })不同意则返回首页并限制登录、发帖等功能。6.3 代码保护与反编译意识热度词里提到“小程序反编译”。作为开发者我强烈建议你不要去碰别人的源码但从保护自己作品的角度一定要知道微信小程序打包后的wxapkg包是可以被解密的里面包含所有前端代码、密钥、域名接口等信息。防范措施有几个不要把敏感的业务密钥写在前端必须放到后端或云函数对接口做签名校验防止被重放攻击在关键页面增加防调试检测但不推荐过激的对抗手段UniApp编译时开启混淆压缩插件如uni-hibuilder的自定义混淆这些不能彻底阻止逆向但能大幅提高门槛。真正的核心资产教程内容、用户数据、商业逻辑放在后端前端只做展示。6.4 埋点与性能监控上线后不能两眼一抹黑。我接入了微信小程序自带的统计能力同时在关键行为点埋自定义事件页面停留时长教程播放完成率收藏/分享/评论率支付转化率安卓埋点代码一开始就要写成公共方法不要在每个页面重复写。我在utils/track.js里暴露一个track(event, params)函数内部调用uni.report微信小程序专用数据可在这后面看。这样后续做ABTest也好扩展。性能监控方面重点看页面进入耗时用PerformanceObserver采样或者在小程序体验评分里定期自查。教程详情页的图片资源一定得走CDN压缩别让原图直接出否则首屏白屏概率极高。6.5 H5端跳转小程序、App打包的扩展思路这个项目虽然是微信小程序为主体但UniApp的跨端能力我也用上了官网H5部署了独立页面用户在浏览器中点“打开小程序”通过微信开放标签跳转App端则通过uni-app打包成安卓、iOS原生壳与小程序共用业务代码。H5跳小程序的方案在H5页面引入微信的jweixin模块使用wx.miniProgram.navigateTo({ url })。这个能力要求H5绑定在一个开放平台公众号下并且需要公众号与小程序关联。具体流程有点绕但按微信官方文档一步步配就行。App打包上架安卓应用市场华为、小米、OPPO、vivo时要注意增加隐私政策弹窗、备案信息以及各厂商要求的权限说明。尤其小米和华为对应用权限管得严没有隐私弹窗直接拒收。iOS的App Store要求虚拟商品必须走IAP推广服务商要在App内提供“恢复购买”功能这些都是额外工作量。如果你的主要用户就在微信里App版本可以晚点再做先把小程序打磨到极致。最后的经验补充从立项到上线这个美妆教程平台踩的最深的坑是视频播放在不同系统的兼容性iOS静音、安卓锁屏、web-view返回随便一个处理不好都会导致差评。建议你在开发时就找多个真机测不要只依赖开发工具小程序开发工具的Player环境和真机差异很大。另外社区类内容平台的审核压力不小提前准备关键词过滤和举报机制能显著缩短审核周期。还有一点小技巧美妆教程的封面图一定要用高质量人像图并且做统一的封面模板这在微信小程序的首页列表中非常影响点击率甚至可以掩盖一点技术瑕疵。技术之外对垂直内容平台来说“美”本身就是产品的一部分。如果你也在做类似的UniApp跨端项目或者在美妆、内容社区类小程序上有什么疑问欢迎在评论区交流。我看到了会回复。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。