vue 实现调用摄像头进行拍照功能以及从图库中选择相片功能以及基于photoswipe的vue图片预览 组件
效果图
图一: 图二:
图三:
图四:
使用组件:
使用vue-photo-preview :https://github.com/826327700/vue-photo-preview
.ts
import photograph from "@/MobileApp/components/photograph";
@Component({
components: { photograph }
})
.vue
<photograph></photograph>
<photograph showAlbum="false"></photograph> // 使用拍照功能
<photograph showPhoto="false"></photograph> // 使用拍照以及选择相片功能
组件:
.vue
<template>
<div>
<div>
<div :style="{ height: picHeight-2 + 'px' ,width: picWidth-2 + 'px'}" ref="showPhoto" class="file" @click="showType">
<span class="icon iconfont icon-uploadphoto camera"></span>
</div>
<div class="showImgDiv" v-for="(item, index) in photoLists" :key="index" ref="showPhoto">
<img preview="0" ref="showImg" :style="{ height: picHeight + 'px' ,width: picWidth + 'px'}" :src="item">
<span :style="{ width: picWidth + 'px'}" class="dele" @click="deleImg(index)">
<span class="icon iconfont icon-delete deleIcon"></span>
</span>
</div>
</div>
<van-popup v-model="isShow" position="bottom" style="text-align: center;">
<div ref="cameraRemove" class="van-hairline--bottom" @click="close" showPhoto>
<input
cameraDisable
ref="inputCamera"
class="inputPhoto"
type="file"
accept="image/*"
capture="camera"
@change="cameraChange"
>
<span :style="{ color: fontColorCamera}">拍照</span>
</div>
<div ref="multipleRemove" class="van-hairline--bottom" @click="close" showAlbum>
<input
multipleDisable
ref="inputMultiple"
class="inputPhoto"
type="file"
accept="image/*"
multiple
@change="multipleChange"
>
<span :style="{ color: fontColorMultiple}">从相册中选择</span>
</div>
</van-popup>
</div>
</template>
<style scoped>
.dele {
height: 30px;
background-color: #fff;
opacity: 0.8;
text-align: center;
line-height: 30px;
position: absolute;
bottom: 0;
left: 0;
}
.deleIcon {
color: #3fcc8e;
}
.showImgDiv {
position: relative;
display: inline-block;
padding-right: 2px;
padding-top: 5px;
}
.van-hairline--bottom {
height: 60px;
line-height: 60px;
}
.vanRow {
background-color: #fff;
}
.camera {
color: #3fcc8e;
font-size: 26px;
}
.file {
position: relative;
border: 1px dashed #3fcc8e;
display: inline-block;
overflow: hidden;
line-height: 88px;
text-align: center;
margin-right: 5px;
margin-top: 5px;
}
.inputPhoto {
position: absolute;
font-size: 100px;
right: 0;
top: 0;
opacity: 0;
}
</style>
<script>
import Photograph from "./photograph.ts";
export default Photograph;
</script>
.ts
/**
* @module MobileApp\components\photograph
*/
import Vue from "vue";
import { Component, Prop, Watch, Emit } from "vue-property-decorator";
import { IndexObject } from "@/types";
import common from "@/MobileApp/utils/common";
@Component
export default class Photograph extends Vue {
[x: string]: any;
private isShow = false;
private photoLists = [];
private picWidth = 75;
private picHeight = 90;
@Prop({ default: "true" }) showAlbum!: string;
@Prop({ default: "true" }) showPhoto!: string;
mounted() {}
private close() {
this.isShow = false;
}
private showType() {
this.isShow = true;
this.$nextTick(function() {
let cameraRemove = this.$refs.cameraRemove as IndexObject;
let multipleRemove = this.$refs.multipleRemove as IndexObject;
if (!cameraRemove.parentNode || !multipleRemove.parentNode) {
return;
}
if (this.showAlbum === "false") {
multipleRemove.parentNode.removeChild(multipleRemove);
}
if (this.showPhoto === "false") {
cameraRemove.parentNode.removeChild(cameraRemove);
}
});
}
private cameraChange() {
let inputCameraFile = this.$refs.inputCamera as IndexObject;
let url;
if (inputCameraFile.files[0]) {
url = URL.createObjectURL(inputCameraFile.files[0]);
(this as any).photoLists.push(url);
}
this.$previewRefresh();
}
private multipleChange() {
let url;
let inputMultiple = this.$refs.inputMultiple as IndexObject;
if (inputMultiple.files) {
for (let file of inputMultiple.files) {
url = URL.createObjectURL(file);
(this as any).photoLists.push(url);
}
}
this.$previewRefresh();
}
private deleImg(index) {
common
.dialogConfirm("温馨提示", "请确认要删除此照片?")
.then(() => {
// on confirm
(this as any).photoLists.splice(index, 1);
})
.catch(() => {
// on cancel
});
}
}