camera组件必须是页面根节点的直接子元素,不能嵌套在view、scroll-view或v-if块中,否则不渲染或报错;需用cover-view/cover-image覆盖交互层,拍照与录像api互斥且权限须分别申请。

camera 组件必须是页面根节点的直接子元素
微信小程序平台下,<camera></camera> 不能嵌套在 <view></view>、<scroll-view></scroll-view> 或 v-if 块里,否则不渲染或报错 “组件未定义”。这不是 bug,是原生限制 —— 小程序要求 camera 的 DOM 层级扁平。
实操建议:
-
<camera></camera>必须紧贴<template></template>下第一层<view></view>,例如:<view><camera></camera></view> - 需要控制宽高?用内联
style="width: 100%; height: 100vh;",别套容器 - 要动态显示/隐藏?用
v-if控制整个<camera></camera>节点,不用display: none - App 和 H5 端无此限制,但为跨平台一致,所有平台都按此结构写
拍照和录像必须用不同 API,不能共用 cameraContext
很多人调用 uni.createCameraContext() 后反复混用 takePhoto() 和 startRecord(),结果录像静音、回调不触发、再拍照失败 —— 因为微信小程序中这两个操作互斥,且 startRecord() 后必须先 stopRecord() 才能恢复拍照。
实操建议:
- 拍照统一用
uni.camera.takePhoto()(推荐,稳定性高,无需 context) - 录像用全局 API:
uni.startRecord({ maxDuration: 60 })+uni.stopRecord() - 不要用
cameraContext.startRecord(),它在部分平台已废弃或行为不一致 - H5 端不支持
uni.startRecord,需降级为getUserMedia+ MediaRecorder,App 端则走原生封装
相机和录音权限必须分开申请并实时校验
只申请 scope.camera,录像会静音或失败;只申请 scope.record,<camera></camera> 根本打不开。而且用户拒绝一次后,uni.authorize() 不会再弹窗,必须跳转设置页。
实操建议:
- 进入页面前,同时检查两个权限:
uni.getSetting()查authSetting['scope.camera']和authSetting['scope.record'] - 任一未授权,先
uni.authorize({ scope: 'scope.camera' }),成功后再立刻查scope.record并补申请 - 任意一个
fail,立即uni.openSetting()引导手动开启 - App 端不需要
scope.record(音频默认可用),但小程序必须显式处理,不能省略 - 权限状态缓存不可靠,每次进页面都应重新
getSetting
UI 布局与交互要适配微信视觉习惯
仿微信拍摄界面不是堆按钮,关键在动效节奏、按钮热区、遮罩层级和状态反馈。比如底部快门按钮长按时启动录像,松开自动停止;双击切换前后摄;预览图覆盖在 <camera></camera> 上需用 <cover-image></cover-image>(<image></image> 会被 camera 遮挡)。
实操建议:
- 功能按钮全用
<cover-view></cover-view>/<cover-image></cover-image>,避免被 camera 原生层裁剪 - 预览照片或视频时,用
v-else切换到<video></video>或<cover-image></cover-image>,并设z-index: 9800 - 录像倒计时用
setInterval+clearInterval控制,超时自动触发uni.stopRecord() - 闪光灯、缩放等高级功能需按平台判断:
uni.getSystemInfoSync().platform === 'ios'才启用双指缩放
startRecord 都不支持。这些细节没埋点日志,上线后用户一拍就黑屏,根本没法复现。











