我们知道图片上传有form表单、ajax上传。本文主要讲解ajax上传,目前仅支持pc,后续会补充移动端,如果你遇到了图片批量上传的场景,笔者的思路及实现方法希望可以对你有些帮助,话不多说,前端代码如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>图片上传示例</title><style>.img-list,.img-list .title{display: flex;justify-content: center;align-items: center}.img-list .title,.img-list .list{min-height: 200px;max-height: 600px;}.img-list .list li{display: inline-block;position:relative;}.img-list .list li img{width:400px;}.hide{display: none !important;}</style>
</head><body><div class="img-list"><div class="title">还没有添加</div><ul class="list">//展示图片</ul></div>//这里需要注意的是multiple属性,如果需要多选,你就得加上它<input name="image" type="file" id="upload" multiple="multiple">
</body>
<scriptsrc="https://code.jquery.com/jquery-3.3.1.min.js"integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="crossorigin="anonymous"></script>
<script>//图片上传我这里用的change事件触发,upload_fun函数是上传图片的核心,为什么我不使用匿名函数?后面会提到//我使用的jquery的缓存id属性为0,这个0代表上传了的图片数量,也代表upload_fun函数执行了几次。默认0为1次。$('#upload').data('id', 0).change(upload_fun);function upload_fun() {//假设我上传了一张图片,触发change事件后var $this = $('#upload'); var file = $this[0]; //获得dom对象var imgSum = file.files.length; //图片数量,就是你选择了的图片数量。var uploadSum = $this.data('id'); //上传了的图片数量 也代表函数执行了几次,之前有提到,默认为0。var formFile = new FormData(); //FormData是异步上传的前提,不懂请百度。formFile.append('image', file.files[uploadSum]);//这里是把文件存到FormData中,uploadSum是0,也就是第一张图片,1就是第二张,依次类推。$.ajax({url: "{:url('carousel/uploadImage')}", //请求路径没什么可说的type: "POST",data: formFile, //注意参数contentType: false,processData: false,dataType: 'json',success: function (data) {uploadSum++; //如果上传成功,上传了的数量就+1$this.data('id', uploadSum); //将缓存更新//获取到后端地址后,赋给img标签并插入dom$('.img- list').children('.title').addClass('hide').siblings('.list').removeClass('hide').append('<li><img src="' + data.path + '"></li>');//判断上传了的图片数量 是否小于 选择了的图片数量if (uploadSum < imgSum) {//如果小于就递归调用该方法,这下你知道我在change中为什么不用匿名函数了吧。upload_fun();//这里调用后upload_fun函数中formFile.append('image', file.files[uploadSum])中的uploadSum就会变为1,也就是第二张图片。相信到这里你已经明白了,我是把你选择的一组图片,一张一张上传到服务器,这样可以减轻服务器并发的压力,也不降低了出错的几率。当然如果你上传一张就执行一次。} else {//当图片都上传完成后,上传了的图片数量归0,input值也清空。$this.data('id', 0).val('');}},error: function (error) {
//错误你来处理吧。console.log(error);}})}
</script></html>
由于时间仓促,目前代码还不完善,仅仅是提供了一些思路,后续会加上加载条等等,下面是后端代码。
<?php
namespace app\admin\controller;use think\Controller;class Carousel extends Controller
{public function index(){return $this->fetch();}//轮播图片上传public function uploadImage(){$file = request()->file('image');//获取上传图片// 移动到框架应用根目录/public/uploads/ 目录下if ($file) {$info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');if ($info) {$img = $info->getSaveName();//获取名称$imgpath = DS . 'uploads' . DS . $img;$path = str_replace(DS, "/", $imgpath);//数据库存储路径$save = model('Carousel')->save(['path' => $path]);return ['status' => 1, 'path' => $path];} else {$message = '图片上传失败';return ['status' => 0, 'message' => $message];}} else {$message = '图片上传失败';return ['status' => 0, 'message' => $message];}}
}
如果您发现了问题,或者代码有什么不足之处,请您不吝赐教。