Vue项目实现html5图片上传的示例代码

 更新时间:2022年1月12日 13:19  点击:998 作者:0.活在风浪里

选择图片 -> 预览图片 -> 裁剪图片 -> 上传图片

我会以事例贯穿图片接下来,就详细的介绍每个步骤具体实现。

图例

1.选择图片

选择图片有什么好讲的呢?不就一个 input[type=file] ,然后点击就可以了吗?确实是这样的,但是,我们想要做得更加的友好一些,比如需要过滤掉非图片文件, 或只允许从摄像头拍照获取图片等,还是需要进行一些简单配置的。

下面就先来看看最简单的选择文件: 

<input type="file" />

上面可以查看到非图片类型的文件,这并不是我们想要的结果,毕竟我们只想要图片类型。可以通过 accept 属性来实现,如下:

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

这样就可以过滤掉非图片类型了。但是图片的类型可能也太多了, 有些可能服务器不支持,所以,如果想保守一些,只允许 jpg 和 png 类型,可以写成这样:

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

或这样

<input type="file" accept=".jpg, .jpeg, .jpg">

OK, 过滤非图片的需求搞定了。但是有时候 ,产品还要求只能从摄像头采集图片,比如需要上传证件照,防止从网上随便找别人的证件上传,那capture 属性就可以派上用场了:

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

这时候,就不能从文件系统中选择照片了,只能从摄像头采集。到了这一步,可能觉得很完美了,但是还有个问题,可能有些变态产品要求默认打开前置摄像头采集图片,比如就是想要你的自拍照片。 capture 默认调用的是后置摄像头。默认启用前置摄像头可以设置 capture="user" ,如下:

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

好啦,关于选择图片的就讲么这么多了,有个注意的地方是,可能有些配置在兼容性上会有一些问题,所以需要在不同的机型上测试一下看看效果。

下面再来谈谈预览图片的实现。

2.预览图片

不使用图片预览,点击上传图片后无法查看 例如下图:我重新换了图片,图片路径变了,但图片没变

2.1添加图片预览代码 

图片变了可以预览查看

 源码1: 使用 URL.createObjectURL 预览

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        img {
            width: 300px;
            height: 200px;
        }
    </style>
</head>
 
<body>
    <form action="" method="get">
        <input id="inputFile" type="file" accept="image/*">
        <img src="./301571.jpg" id="previewImage" alt="图片预览" title="活在风浪里...">
    </form>
    <!-- 图片预览 -->
    <script>
        const $ = document.getElementById.bind(document);
        const $inputFile = $('inputFile');
        const $previewImage = $('previewImage');
        $inputFile.addEventListener('change', function() {
            const file = this.files[0];
            $previewImage.src = file ? URL.createObjectURL(file) : '';
        }, this);
    </script>
 
</body>
 
</html>

 源码2:使用 FileReader 预览

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        img {
            width: 300px;
            height: 200px;
        }
    </style>
</head>
 
<body>
    <form action="" method="get">
        <input id="inputFile" type="file" accept="image/*">
        <img src="./301571.jpg" id="previewImage" alt="图片预览">
    </form>
    <!-- 图片预览 -->
 
    <script>
        const $ = document.getElementById.bind(document);
        const $inputFile = $('inputFile');
        const $previewImage = $('previewImage');
        $inputFile.addEventListener('change', function() {
            const file = this.files[0];
            const reader = new FileReader();
            reader.addEventListener('load', function() {
                $previewImage.src = reader.result;
            }, false);
 
            if (file) {
                reader.readAsDataURL(file);
            }
        }, false)
    </script>
 
 
</body>
 
</html>

预览图片总结:

两种方法的对比

我个人更加倾向于使用 URL.createObjectURL() 。主要原先它的 API 简洁,同步读取,并且他返回的是一个 URL ,比 FileReaer 返回的base64 更加精简。兼容性上,两者都差不多,都是在 WD 的阶段。性能上的对比, 在 chrome 上, 选择了一张 2M 的图片, URL.createObjectURL() 用时是 0 , 而 FileReader 用时 20ms 左右。 0 感觉不太合理,虽然这个方法立刻就会返回一个 URL ,但是我猜测实际上这个 URL 指定的内容还没有生成好,应该是异步生成的,然后才渲染出来的。所以并没有很好的办法来对比他们的性能。

3.裁剪图片

关于图片的裁剪,很自然的会想到使用 canvas ,确实是要通过 canvas, 但是如果全部我们自己来实现,可能需要做比较多的工作,所以为了省力,我们可以站在巨人的肩膀上。比较优秀的图片裁剪库是cropperjs  , 该库可以对图片进行缩放、移动和旋转。随后会持续更新canvas,(我也在学..永远保持谦逊,人外人天外天,拒绝凡尔赛 )

cropperjs 的详细配置这里就不展开了 ,需要的可以自己去看文档就好。下面我们就以这个库为基础,实现一个裁剪人脸的例子:

 源码: 当然这个只是简单的写下,为了写博客在电脑操作小伙伴要自行查看下移动端兼容

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.js"></script>
    <style>
        .preview-image,
        .cropper-image {
            max-width: 100%;
        }
        
        .cropper {
            display: none;
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            background: #ccc;
            font-size: 0.27rem;
            text-align: center;
        }
        
        .inner {
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }
        
        .face-container {
            position: relative;
            width: 320px;
            height: 320px;
            margin: 50px auto;
        }
        
        .cropper-modal {
            background: url('https://ok.166.net/gameyw-misc/opd/squash/20191028/152551-m37snfsyu1.png') center no-repeat;
            background-size: 100% 100%;
            opacity: 1;
        }
        
        .cropper-bg {
            background: none;
        }
        
        .cropper-view-box {
            opacity: 0;
        }
        
        .tips {
            font-size: 16px;
        }
        
        .toolbar {
            display: flex;
            justify-content: center;
            margin: 50px 0;
        }
        
        .btn {
            width: 150px;
            line-height: 40px;
            font-size: 20px;
            text-align: center;
            color: #fff;
            background: #007fff;
        }
    </style>
 
 
 
</head>
 
<body>
    <form name="input" action="html_form_action.php" method="get">
        <input id="inputFile" type="file" accept="image/*">
        <img class="preview-image" id="previewImage" src="" alt="">
        <!-- cropper裁剪框 -->
        <div class="cropper" id="cropper">
            <div class="inner">
                <div class="face-container">
                    <img class="cropper-image" id="cropperImage">
                </div>
                <div class="tips">请将面部区域置于人脸框架内</div>
                <div class="toolbar">
                    <div class="btn" id="confirm">确认</div>
                </div>
            </div>
        </div>
    </form>
</body>
<script>
    const $ = document.getElementById.bind(document);
    const $cropper = $('cropper');
    const $inputFile = $('inputFile');
    const $previewImage = $('previewImage');
    const $cropperImage = $('cropperImage');
    const $confirmBtn = $('confirm')
    let cropperInstance = null;
 
    // 选择图片后,显示图片裁剪框
    $inputFile.addEventListener('change', function() {
        const file = this.files[0];
        if (!file) return;
        $cropperImage.src = URL.createObjectURL(file);
        showCropper();
    }, false);
 
    // 点击确认按钮,将裁剪好的图片放到 img 标签显示。
    $confirmBtn.addEventListener('click', function() {
        const url = cropperInstance.getCroppedCanvas().toDataURL("image/jpeg", 1.0);
        $cropper.style.display = 'none';
        $previewImage.src = url;
    }, false);
 
 
    function showCropper() {
        $cropper.style.display = 'block';
        cropperInstance && cropperInstance.destroy();
        cropperInstance = new Cropper($cropperImage, {
            viewMode: 1,
            aspectRatio: 1,
            autoCropArea: 1,
            dragMode: 'move',
            guides: false,
            highlight: false,
            cropBoxMovable: false,
            cropBoxResizable: false
        });
    }
</script>
</html>

4.上传

前面的操作已经完成了图片上传前的准备,包括选择图片、预览图片、编辑图片等,那接下来就可以上传图片了。上面的例子中,使用了 cropperInstance.getCroppedCanvas() 方法来获取到对应的 canvas 对象 。有了 canvas 对象就好办了,因为 canvas.toBlob() 方法可以取得相应的 Blob 对象,然后,我们就可以把这个 Blob 对象添加到 FromData 进行无刷新的提交了。大概的代码如下:

  change(e) {
      // 1.手写的input需要一个对象将本地图片转换为对应的格式来上传
      let formData = new FormData();
 
      //2. e.target.files就是选中的图片的一个
      formData.append("file", e.target.files[0]);
 
      // 3. 将formData这个对象传给修改头像的接口
      updateImg(formData).then((res) => {
        //4.此时已经传到修改头像接口了
        //4.1 传到修改头像的接口后 , 在更新接口中  再次更新头像属性
 
        update({ avatar: res.data.path });
 
        //存到本地 //info是本地存储点击头像获取的个人信息,在此页面初始调用本地存储数据,
    //这里赋值info对象,因为上面渲染头像用的是本地,所以(修改后端图片路径,重新调用后端更新接口后),
//还要重新赋值本地存储,才能后端变化.本地页面,因为是点击头像进入修改页,才存储的数据,不会随后端更新,
//所以还要重新赋值本地存储
        this.info.avatar = res.data.path;
        localStorage.setItem("userInfo-Avatar", JSON.stringify(this.info));
        this.show2 = false;
      });
    },

浪哥tips: 如果在移动端,有的手机会检测自动校正角度,导致有些角度不对可以使用 CSS 的 transfrom: rotate(-90deg) 顺时针旋转 90 度抵消掉这个角度就好。

到此这篇关于Vue项目实现html5图片上传的示例代码的文章就介绍到这了,更多相关Vue html5图片上传内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://blog.csdn.net/m0_57904695/article/details/122404448

[!--infotagslink--]

相关文章

  • vue中activated的用法

    这篇文章主要介绍了vue中activated的用法,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下...2021-01-03
  • 基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能

    这篇文章主要介绍了基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23
  • Antd-vue Table组件添加Click事件,实现点击某行数据教程

    这篇文章主要介绍了Antd-vue Table组件添加Click事件,实现点击某行数据教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-17
  • vue 实现动态路由的方法

    这篇文章主要介绍了vue 实现动态路由的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-06
  • Vue组件跨层级获取组件操作

    这篇文章主要介绍了Vue组件跨层级获取组件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-28
  • Vue基于localStorage存储信息代码实例

    这篇文章主要介绍了Vue基于localStorage存储信息代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-16
  • vue 监听 Treeselect 选择项的改变操作

    这篇文章主要介绍了vue 监听 Treeselect 选择项的改变操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
  • antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

    这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09
  • vue 获取到数据但却渲染不到页面上的解决方法

    这篇文章主要介绍了vue 获取到数据但却渲染不到页面上的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-19
  • vue项目多环境配置(.env)的实现

    最常见的多环境配置,就是开发环境配置,和生产环境配置,本文主要介绍了vue项目多环境配置的实现,感兴趣的可以了解一下...2021-07-20
  • vue项目页面嵌入代码块vue-prism-editor的实现

    这篇文章主要介绍了vue项目页面嵌入代码块vue-prism-editor的实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-30
  • vuejs element table 表格添加行,修改,单独删除行,批量删除行操作

    这篇文章主要介绍了vuejs element table 表格添加行,修改,单独删除行,批量删除行操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18
  • Vue 3.0中jsx语法的使用

    这篇文章主要介绍了Vue 3.0 中 jsx 语法使用,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下...2020-11-13
  • 解决vue的router组件component在import时不能使用变量问题

    这篇文章主要介绍了解决vue的router组件component在import时不能使用变量问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-27
  • vue Treeselect下拉树只能选择第N级元素实现代码

    这篇文章主要介绍了vue Treeselect下拉树只能选择第N级元素实现代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
  • vue treeselect获取当前选中项的label实例

    这篇文章主要介绍了vue treeselect获取当前选中项的label实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
  • vue实现同时设置多个倒计时

    这篇文章主要为大家详细介绍了vue实现同时设置多个倒计时,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-05-20
  • Ant design vue table 单击行选中 勾选checkbox教程

    这篇文章主要介绍了Ant design vue table 单击行选中 勾选checkbox教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-25
  • Vue中slot-scope的深入理解(适合初学者)

    这篇文章主要给大家介绍了关于Vue中slot-scope的深入理解,这个教程非常适合初学者,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-17
  • vue实现div单选多选功能

    这篇文章主要为大家详细介绍了vue实现div单选多选功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-07-16