LayUI中的内置模块之 图片/文件上传 layui.upload

前言

最近在准备找工作的事项,但是作为一个后台也是需要了解一些前端框架的。就目前的来说有大火的VUE,但是VUE还是存在一定的学习成本,所以决定先从对后台友好的LayUI开始入手先做一些小项目练练手,后面会考虑使用VUE+ElementUI做一个大型一点的SAAS系统。查阅资料后得到如下文章,作为学习记录使用。

图片/文件上传 - layui.upload

上传模块自 layui 2.0 的版本开始,进行了全面重写,这使得它不再那么单一,它所包含的不仅是更为强劲的功能,还有灵活的 UI。任何元素都可以作为上传组件来调用,譬如按钮、图片、普通的 DIV 等等,而不再是一个单调的 file 文件域。
模块加载名称:upload

快速使用

一切从小试牛刀开始。通常情况下,我们上传文件是借助 type=“file” 的 input 标签来完成的,但非常遗憾的是,它不能很好地与其它表单元素并存,所以我们常常要单独为它做一个业务层面的“异步上传”,即先让图片上传,再和其它表单一起提交保存。下面是一个小示例:
在这里插入图片描述

这原本只是一个普通的 button,正是 upload 模块赋予了它“文件选择”的特殊技能。当然,你还可以随意定制它的样式,而不是只局限于按钮。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>upload模块快速使用</title>
  <link rel="stylesheet" href="/static/build/layui.css" media="all">
</head>
<body>
 
<button type="button" class="layui-btn" id="test1">
  <i class="layui-icon">&#xe67c;</i>上传图片
</button>
 
<script src="/static/build/layui.js"></script>
<script>
layui.use('upload', function(){
  var upload = layui.upload;
   
  //执行实例
  var uploadInst = upload.render({
    elem: '#test1' //绑定元素
    ,url: '/upload/' //上传接口
    ,done: function(res){
      //上传完毕回调
    }
    ,error: function(){
      //请求异常回调
    }
  });
});
</script>
</body>
</html>
核心方法与基础参数选项

使用 upload 模块必须与 upload.render(options) 方法打交道,其中的 options即为基础参数,它是一个对象。

var upload = layui.upload; //得到 upload 对象
 
//创建一个上传组件
upload.render({
  elem: '#id'
  ,url: ''
  ,done: function(res, index, upload){ //上传后的回调
  
  } 
  //,accept: 'file' //允许上传的文件类型
  //,size: 50 //最大允许上传的文件大小
  //,……
})

从 layui 2.1.0 开始,允许你直接在元素上设定基础参数,如:

【HTML】
<button class="layui-btn test" lay-data="{url: '/a/'}">上传图片</button>
<button class="layui-btn test" lay-data="{url: '/b/', accept: 'file'}">上传文件</button>
 
【JS】
upload.render({
  elem: '.test'
  ,done: function(res, index, upload){
    //获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
    var item = this.item;
  }
})

更多支持的参数详见下表,合理的配置它们,应对各式各样的业务需求。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上传接口

设定一个 URL 地址给 url 参数,用来告诉 upload 模块的服务端上传接口。像你平时使用Ajax一样。如:

upload.render({
  elem: '#id'
  ,url: '/api/upload/' //必填项
  ,method: ''  //可选项。HTTP类型,默认post
  ,data: {} //可选项。额外的参数,如:{id: 123, abc: 'xxx'}
});

该接口返回的相应信息(response)必须是一个标准的 JSON 格式,如:

{
  "code": 0
  ,"msg": ""
  ,"data": {
    "src": "http://cdn.layui.com/123.jpg"
  }
}   

注意1:你不一定非得按照上述格式返回,只要是合法的 JSON 字符即可。其响应信息会转化成JS对象传递给 done 回调。
注意2:如果上传后,出现文件下载框(一般为ie下),那么你需要在服务端对response的header设置 Content-Type: text/html

选择文件的回调

在文件被选择后触发,该回调会在 before 回调之前。一般用于非自动上传(即 auto: false )的场景,比如预览图片等。

upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,auto: false //选择文件后不自动上传
  ,bindAction: '#testListAction' //指向一个按钮触发上传
  ,choose: function(obj){
    //将每次选择的文件追加到文件队列
    var files = obj.pushFile();
    
    //预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
    obj.preview(function(index, file, result){
      console.log(index); //得到文件索引
      console.log(file); //得到文件对象
      console.log(result); //得到文件base64编码,比如图片
      
      //obj.resetFile(index, file, '123.jpg'); //重命名文件名,layui 2.3.0 开始新增
      
      //这里还可以做一些 append 文件列表 DOM 的操作
      
      //obj.upload(index, file); //对上传失败的单个文件重新上传,一般在某个事件中使用
      //delete files[index]; //删除列表中对应的文件,一般在某个事件中使用
    });
  }
});   

事实上这是一个非常实用的存在,可轻松应对复杂的列表文件上传管理。具体可移步到 示例 页面,里面有一个文件列表的小例子。

文件上传前的回调

在 choose 回调之后、done/error 回调之前触发。返回的参数完全类似 choose 回调。一般用于上传完毕前的loading、图片预览等。

upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,before: function(obj){ //obj参数包含的信息,跟 choose回调完全一致,可参见上文。
    layer.load(); //上传loading
  }
  ,done: function(res, index, upload){
    layer.closeAll('loading'); //关闭loading
  }
  ,error: function(index, upload){
    layer.closeAll('loading'); //关闭loading
  }
});  
上传接口请求成功的回调

在上传接口请求完毕后触发,但文件不一定是上传成功的,只是接口的响应状态正常(200)。回调返回三个参数,分别为:服务端响应信息、当前文件的索引、重新上传的方法

upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,done: function(res, index, upload){
    //假设code=0代表上传成功
    if(res.code == 0){
      //do something (比如将res返回的图片链接保存到表单的隐藏域)
    }
    
    //获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
    var item = this.item;
    
    //文件保存失败
    //do something
  }
});      
上传请求失败的回调

当请求上传时出现异常时触发(如网络异常、404/500等)。回调返回两个参数,分别为:当前文件的索引、重新上传的方法

upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,error: function(index, upload){
    //当上传失败时,你可以生成一个“重新上传”的按钮,点击该按钮时,执行 upload() 方法即可实现重新上传
  }
}); 
多文件上传完毕后的状态回调

只有当开启多文件时(即 multiple: true),该回调才会被触发。回调返回一个 object 类型的参数,包含一些状态数据:

upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,multiple: true
  ,allDone: function(obj){ //当文件全部被提交后,才触发
    console.log(obj.total); //得到总文件数
    console.log(obj.successful); //请求成功的文件数
    console.log(obj.aborted); //请求失败的文件数
  }
  ,done: function(res, index, upload){ //每个文件提交一次触发一次。详见“请求成功的回调”
  
  }
}); 
文件上传进度的回调

在网速一般的情况下,大文件的上传通常需要一定时间的等待,而浏览器并不会醒目地告知你它正在努力地上传中,此时为了提升用户体验,我们可以通过该回调制作一个进度条。注:该回调为 layui 2.5.5 新增

upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,progress: function(n, elem, res, index){
    var percent = n + '%' //获取进度百分比
    element.progress('demo', percent); //可配合 layui 进度条元素使用
    
    console.log(elem); //得到当前触发的元素 DOM 对象。可通过该元素定义的属性值匹配到对应的进度条。
    console.log(res); //得到 progress 响应信息
    console.log(index); //得到当前上传文件的索引,多文件上传时的进度条控制,如:
    element.progress('demo-'+ index, n + '%'); //进度条
  }
});
重载实例

有时你可能需要对 upload.render() 实例进行重载,通过改变一些参数(如将上传文件重置为只上传图片等场景)来重置功能。如:

//创建一个实例
var uploadInst = upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,size: 1024*5 //限定大小
});
 
//重载该实例,支持重载全部基础参数
uploadInst.reload({
  accept: 'images' //只允许上传图片
  ,acceptMime: 'image/*' //只筛选图片
  ,size: 1024*2 //限定大小
}); 

注意:该方法为 layui 2.5.0 开始新增

重新上传

在执行 upload.render(options) 方法时,其实有返回一个实例对象,以便对完成重新上传等操作。注意:这是对当前上传队列的全局重新上传,而 choose 回调返回的 obj.upload(index, file) 方法则是对单个文件进行重新上传。如:

var uploadInst = upload.render({
  elem: '#id'
  ,url: '/api/upload/'
  ,choose: function(obj){
    obj.preview(function(index, file, result){
      //对上传失败的单个文件重新上传,一般在某个事件中使用
      //obj.upload(index, file);
    });
  }
});
 
//重新上传的方法,一般在某个事件中使用
//uploadInst.upload(); 
跨域上传

有些时候,可能会涉及到文件跨域操作,过去版本的 upload 模块最大的缺陷恰恰在于这里。而从 layui 2.0 的版本开始,我们已经对 跨域做了支持。但鉴于代码的冗余度等多方面考虑,在IE9以下版本环境中,仍然不支持跨域。其它所有版本的IE和Chrome/FireFox等高级浏览器均支持。

那么,需要你怎么做?通常来说,是借助 CORS(跨资源共享) 方案,即对接口所在的服务器设置:Access-Control-Allow-Origin 详见Google,配置起来还是挺简单的。而至于域名限制,一般是服务端程序中去做处理。这里不做过多赘述。
官网链接

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值