vue3+uniapp拍照增加取景框+返回上一页并触发事件

项目遇到拍照要增加取景框的场景,找了写资料,写一下心得。

需要用到camera,cover-view,cover-image

<template>
	<view class="camera">
		<camera device-position="back" flash="off" style="width: 100%; height: 90vh">
			<cover-view class="mask" style="" v-if="cardType === 'card_z'">
				<cover-image src="/static/img/idcard_front.png" class="co_img"></cover-image>
			</cover-view>
			<cover-view class="mask" v-else>
				<cover-image src="/static/img/idcard_back.png"></cover-image>
			</cover-view>
		</camera>
		<view class="flex_be_c" style="position: relative; bottom: 0; left: 0; padding: 40rpx">
			<view @tap="back">取消</view>
			<view class="take_photo" @tap="takeCameraPhoto"></view>
			<view @tap="selectAlbum">相册</view>
		</view>
	</view>
</template>

<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';

const cameraContext = ref({});
const cardType = ref();
onLoad((options) => {
	cardType.value = options.type; // 上一级页面传递过来的证件类型
	if(uni.createCameraContext){
		cameraContext.value = uni.createCameraContext();
	}else{
		uni.showToast({
			title:'微信版本过低,请升级版本',
			icon:'none'
		})
	}
});

const back = () => {
	uni.navigateBack();
};

// 拍照
const takeCameraPhoto = () => {
	cameraContext.value.takePhoto({
		quality:'high',
		success:(res) => {
			uni.$emit('isCamera',[cardType.value,res.tempImagePath,true])
			uni.navigateBack({
				delta:1
			})
		},
		fail:(err) => {}
	})
};

// 选择相册
const selectAlbum = () => {
	uni.chooseMedia({
		count: 1,
		sourceType: 'album',
		success: (res) => {
			console.log('53', res);
			uni.$emit('isCamera',[cardType.value,res.tempFiles[0].tempFilePath,true])
			uni.navigateBack({
				delta: 1
			});
		}
	});
};
</script>

<style lang="scss">
.camera {
	height: 100%;
	.take_photo {
		border-radius: 50%;
		padding: 50rpx;
		box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.4);
	}
	.mask {
		width: 170%;
		height: 42%;
		transform: rotate(90deg);
		position: relative;
		top: 400rpx;
		left: -260rpx;
		.co_img {
			width: 100%;
			height: 100%;
		}
	}
}
</style>

返回上一层的时候,有一个getCurrentPages()的api,但是只能在app上使用,小程序不支持,找了很久也没有其他方法,最后只能使用uni.$emit()和uni.$on()

因为要把获取的图片,传递给上一页上传回显,所以通过emit触发上一页的方法,把参数也传递过去

<template>
    <view class="flex_be">
			<view>
				<view class="flex_di" @tap="seletType" data-type="card_z" v-if="!cardZ">
					<image class="card_img" style="" src="/static/img/card_z.png"></image>
					<text class="card_label">请上传身份证正面</text>
					</view>
				<view class="flex_di" v-else>
					<image class="card_img" :data-url="baseUrl+cardZ" :src="baseUrl+cardZ" @tap="previewImg"></image>
					<text class="card_label" @tap="reset" data-type="card_z">重新上传</text>
				</view>
			</view>
			<view>
				<view class="flex_di" @tap="seletType" data-type="card_f" v-if="!cardF">
					<image class="card_img" src="/static/img/card_f.png"></image>
					<text class="card_label">请上传身份证反面</text>
				</view>
				<view class="flex_di" v-else>
					<image class="card_img" :data-url="baseUrl+cardF" :src="baseUrl+cardF" @tap="previewImg"></image>
					<text class="card_label" @tap="reset" data-type="card_f">重新上传</text>
				</view>	
			</view>
		</view>

</template>


<script setup>
import { ref } from 'vue';
import { onShow } from '@dcloudio/uni-app'

import { baseUrl } from '/config.js'; // 设置的url

onShow(() =>{
	uni.$on('isCamera',function(data){
		uploadImage(...data)
		uni.$off(['isCamera'])
	})
})

const active = ref(1);
const idcardArr = ref([])

// 选择方式
const seletType = (e) => {
	uni.showActionSheet({
		itemList:['拍个照','从相册中选择'],
		itemColor:'#',
		success:(res) => {
			if(res.tapIndex === 0){
				uni.navigateTo({url: '/pages/my/camera?type='+e.currentTarget.dataset.type});
			}else if(res.tapIndex === 1){
				uni.chooseMedia({
					count:1,
					sourceType:['album'],
					mediaType:'image',
					success:(resp) => {
						let filePath = resp.tempFiles[0].tempFilePath
						uploadImage(e.currentTarget.dataset.type,filePath,true)
					}
				})
			}
		}
	})	
};

// 上传图片
const cardZ = ref()
const cardF = ref()
const uploadImage = (type, filePath, immediate) => {
	if (immediate) {
		uni.uploadFile({
			url: baseUrl + '/system/file/upload',
			filePath: filePath,
			name:'file',
			formData:{},
			success:(res) => {
				if(res.statusCode === 200){
					let data = JSON.parse(res.data)
					switch(type){
						case 'card_z':
							idcardArr.value.push(baseUrl+data.data.url)
							cardZ.value = data.data.url
							break;
						case 'card_f':
							idcardArr.value.push(baseUrl+data.data.url)
							cardF.value = data.data.url
							break;
					}
				}
			}
		});
	}
};

// 重置图片
const reset = (e) => {
	let type = e.currentTarget.dataset.type
	if(type === 'card_z'){
		cardZ.value = ''
	}else{
		cardF.value = ''
	}
}

// 预览图片
const previewImg = (e) => {
	let {url} = e.currentTarget.dataset
	uni.previewImage({
		current:url,
		urls:idcardArr.value
	})
}
</script>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值