Vue 移动端调用手机摄像头 上传照片

3,806 阅读2分钟

参考来源:www.cnblogs.com/conglvse/p/…

01 基础用法

<input type="file" accept="image/*" >

若响应慢问题,可将通配符 * 换成指定的图片类型,从而减少检验文件的次数。

<input type="file"  accept="image/png,image/jpeg,image/jpg" />

ios / Android 通用

02 样式更改

  • input标签的file无法用css直接更高样式
  • 需要将本标签隐藏
  • 再新写一个样式覆盖到原标签上,用事件冒泡来完成功能实现
//例子
<template>
    <div class="file-box">
        <input type="file" class="file-btn"/>
        上传文件
    </div>
<template>

<style>
    .file-box{
        display: inline-block;
        position: relative;
        padding: 3px 5px;
        overflow: hidden;
        color:#fff;
        background-color: #ccc;
    }
    .file-btn{
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        outline: none;
        background-color: transparent;
        filter:alpha(opacity=0);
        opacity: 0;
    }
</style>

详情:blog.csdn.net/hua_ban_yu/…

03文件保存/预览

将文件的flie属性保存
使用windows方法转成blob文档流
放入img标签的url中可保存/预览

html
 <li v-if="imgLen>=4 ? false : true">
    <input
        type="file"
        class="upload"
        @change="addImg"
        ref="inputer"
        multiple
        accept="image/png,image/jpeg,image/gif,image/jpg"
    />
    <a class="add">
        <i class="iconfont icon-plus"></i>
        <p>点击上传</p>
    </a>
</li>
<li v-for='(item, index) in imgs' :key="index" >
    <p class="img">
        <img :src="getObjectURL(item)">
        <a  class="close"
            @click="delImg(index)"
        >×</a>
    </p>
</li>

JS
data() {
        return {
            formData: new FormData(),
            imgs: {},//预览的图片合集
            imgLen: 0 ,//初始化图片数量
            fil:{},//每次上次的图片信息
        };
    },
methods: {
    // input改变后,将符合条件(不超过4张和大小不超过5m)的图片放入图片合集
    addImg() {
        let inputDOM = this.$refs.inputer;// 通过DOM取文件数据
        this.fil = inputDOM.files; //拿到最新一张图的信息
        let oldLen = this.imgLen;//已有图片数量
        let len = this.fil.length + oldLen;//加上最新图片数量
        if (len > 4) {//超出数量提示
            alert("最多可上传4张,您还可以上传" + (4 - oldLen) + "张");
            return false;
        }
        for (let i=0; i < this.fil.length; i++) {//多选时需要渲染渲染
            let size = Math.floor(this.fil[i].size);//获得图片大小
            if (size > 5*1024*1024) {//超出大小提示
                alert("请选择5M以内的图片!");
                return false;
            }
            this.imgLen++;
            this.$set(//存入图片的file到对象
                this.imgs,
                this.fil[i].name + "?" + new Date().getTime(),
                this.fil[i]
            );
        }
    },
    // 获取预览图地址并渲染预览图
    getObjectURL(file) {
        let url = null;
        if (window.createObjectURL != undefined) {// basic
            url = window.createObjectURL(file);//
        } else if (window.URL != undefined) {// mozilla(firefox)
            url = window.URL.createObjectURL(file);
        } else if (window.webkitURL != undefined) {// webkit or chrome
            url = window.webkitURL.createObjectURL(file) ;
        }
        return url;
    },
    //点击删除所选图片
    delImg(index) {
        this.$delete(this.imgs, index);//
        this.imgLen--;
    },

04文件上传

前端通过 new FormData()构造 blob流对象后,通过post方法传给接口保存,

后端可用 formData 的 formData.getAll() 等方法来解析后储存图片信息

 <h4 @click ='submit()'>提交文件</h4>
 
  submit() {
    for (let key in this.imgs) {
        let name = key.split("?")[0];
         this.formData.append("multipartFiles", this.imgs[key], name);
    }
     this.$http.post(
     "/opinion/feedback", this.formData, {
        headers: { "Content-Type": "multipart/form-data" }   
     }).then(res => {
        this.alertShow = true;
     });
   }