You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue Native中使用expo-camera实现拍照并解决camera变量未定义报错

问题修复方案

你遇到的ReferenceError: Can't find variable: camera报错,是因为代码没有获取到Camera组件的实例,同时还存在几个隐性语法问题,按以下步骤修复即可:

  • 第一步:给模板中的Camera组件绑定ref属性,用于后续获取组件实例,同时删除模板中不必要的this.前缀
<!-- 替换原来的camera标签 -->
<camera ref="cameraRef" class="container" :type="type" />
  • 第二步:修复capturePic方法,通过ref获取Camera实例后再调用拍照方法,同时可以新增字段存储拍照结果用于展示
    首先在data中新增存储拍照地址的字段:
data: function() {
  return {
     hasCameraPermission: false,
     type: Camera.Constants.Type.back,
     capturedPhotoUri: null // 新增字段存储拍照结果地址
  };
},

修改拍照方法:

capturePic: async function() {
  const camera = this.$refs.cameraRef
  if(!camera) return
  const photo = await camera.takePictureAsync();
  this.capturedPhotoUri = photo.uri // 保存拍照地址用于后续展示
}
  • 第三步:修复mounted生命周期中权限赋值缺少this的问题
mounted: function() {
   Permissions.askAsync(Permissions.CAMERA)
     .then(status => {
         this.hasCameraPermission = status.status === "granted"
     }).catch((err)=>{
         console.log(err);
     });
},
  • 第四步:可选,新增拍照结果展示逻辑,在模板中添加图片组件展示拍好的照片
<!-- 拍照预览区域 -->
<image v-if="capturedPhotoUri" :source="{uri: capturedPhotoUri}" class="preview-img" />

补充说明:如果你的项目使用的是较新版本的Expo,expo-permissions库已经被弃用,你可以直接用expo-camera自带的权限申请方法替换原来的权限逻辑:

// 引入不需要修改,mounted里替换成如下代码
mounted: async function() {
  const { status } = await Camera.requestCameraPermissionsAsync()
  this.hasCameraPermission = status === 'granted'
}

完整修正后代码

<template>
  <view class="view-container">
    <!-- 权限判断:未授权时提示,授权后展示相机 -->
    <view v-if="!hasCameraPermission" class="permission-tip">
      <text>请授予相机使用权限</text>
    </view>
    <view v-else class="container">
       <text>Camera screen</text>
       <camera ref="cameraRef" class="container" :type="type" />
       <touchable-opacity 
         class="camera-touchable-opacity"
         :on-press="capturePic"
       >
         <text>点击拍照</text>
       </touchable-opacity>
       <!-- 拍照预览 -->
       <image v-if="capturedPhotoUri" :source="{uri: capturedPhotoUri}" class="preview-img" />
     </view>

     <view class="home-btn">
        <button title="Go to home screen" @press="goToHomeScreen"></button>
     </view>
  </view>
</template>

<script>
import * as Permissions from 'expo-permissions';
import { Camera } from 'expo-camera';

export default {
  props: {
    navigation: { type: Object }
  },
  data: function() {
    return {
       hasCameraPermission: false,
       type: Camera.Constants.Type.back,
       capturedPhotoUri: null
    };
  },
  mounted: function() {
     Permissions.askAsync(Permissions.CAMERA)
       .then(status => {
           this.hasCameraPermission = status.status === "granted"
       }).catch((err)=>{
           console.log(err);
       });
  },
  components: { Camera },
  methods: {
    goToHomeScreen() {
      this.navigation.navigate("Home");
    },
    capturePic: async function() {
      const camera = this.$refs.cameraRef
      if(!camera) return
      const photo = await camera.takePictureAsync();
      this.capturedPhotoUri = photo.uri
    }
  }
}
</script>

内容的提问来源于stack exchange,提问作者MZr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 18:36:00