emmm我又来了๑乛◡乛๑
饿了么上传组件的文件列表
filelist
有个删除功能,我看源代码它是直接删除,并不会提示。issue
上也有不少开发者提过这个问题,开发组还是建议自己写(想偷懒都不行……)
除了复写文件列表外,还加了一个上传状态的显示。
先上效果图:
悬浮时的效果:
上传时的效果:
以下测试在vue(v2.5) + vue-router(v3.0) + element-ui(v2.0)环境下进行,一些细节(如icon)会与上述图片不相符。所以每个步骤都加个图片=。=
步骤一:卡片化
其实就是重写样式,写个类似el-card
组件的样式
<template>
<div class="img-list">
<div class="img-content" v-for="(item,key) in imagelist" :key="key">
<img :src="item.url">
<div class="name">
<div>{{ item.name }}</div>
<el-button type="text" @click="handleFileName(item,key)">修改名字</el-button>
</div>
<!-- 删除icon -->
<div class="del">
<i @click="handleFileRemove(item,key)" class="el-icon-delete2"></i>
</div>
<!-- 放大icon -->
<div class="layer" @click="handleFileEnlarge(item.url)">
<i class="el-icon-view"></i>
</div>
</div>
</div>
</template>
<script>
export default{
name: 'upload-list',
data(){
return {
imagelist: [{
url: 'http://img.hb.aicdn.com/723f8754f412debce188626d09cc0a1b2be6b7a6751a3-ICEp1E_fw658',
name: 'lemon'
},{
url: 'http://img.hb.aicdn.com/38ab9e558bcba041be979f03bfd31bd67bf1e6f35815a-8PD8Eo_fw658',
name: 'lemon2'
},{
url: 'http://img.hb.aicdn.com/0cd0dcc93f5b918e191dd84791101435136c7f9811e31-LRzYAQ_fw658',
name: 'lemon3'
}]
}
},
methods: {
handleFileEnlarge(_url){//放大图片
console.log(_url)
},
handleFileName(file,i){//修改名字
console.log(file,i)
},
handleFileRemove(file,i){//删除图片
console.log(file,i)
}
}
}
</script>
放大按钮和删除按钮只有鼠标悬浮才显示:
*{
box-sizing: border-box;
}
.img-list{
overflow:hidden;
width:100%;
}
.img-list .img-content{
float:left;
position:relative;
display:inline-block;
width:200px;
height:270px;
padding:5px;
margin:5px 20px 20px 0;
border:1px solid #d1dbe5;
border-radius:4px;
transition:all .3s;
box-shadow:0 2px 4px 0 rgba(0,0,0,.12), 0 0 6px 0 rgba(0,0,0,.04);
}
.img-list .img-content img{
display:block;
width:100%;
height:190px;
margin:0 auto;
border-radius:4px;
}
.img-list .img-content .name{
margin-top:10px;
}
.img-list .img-content .name>div{
width:90%;
text-overflow:ellipsis;
overflow:hidden;
height:25px;
line-height:25px;
}
.img-list .img-content:hover .del,
.img-list .img-content:hover .layer{
opacity:1;
}
.img-list .img-content .del,
.img-list .img-content .layer{
opacity:0;
transition:all .3s;
}
.img-list .img-content .del{
position:absolute;
bottom:10px;
right:10px;
color:#8492a6;
cursor:pointer;
font-size:1.1em;
}
.img-list .img-content .layer{
position:absolute;
left:0;
right:0;
top:0;
height:200px;
color:#fff;
text-align:center;
z-index:5;
background-color:rgba(0,0,0,.4);
}
.img-list .img-content .layer i{
font-size:1.6em;
margin-top:80px;
}
效果图:
步骤二:放大
这个操作很简单,用el-dialog
组件
<div class="img-list">
...
<el-dialog title="" :visible.sync="isEnlargeImage" size="large" :modal-append-to-body="false" top="8%" width="60%">
<img @click="isEnlargeImage = false" style="width:100%;" :src="enlargeImage">
</el-dialog>
</div>
<script>
export default{
data(){
return {
isEnlargeImage: false,//放大图片
enlargeImage: '',//放大图片地址
}
},
methods: {
handleFileEnlarge(_url){//放大图片
console.log(_url)
if(_url){
this.enlargeImage = _url;
this.isEnlargeImage = !this.isEnlargeImage;
}
},
}
}
</script>
步骤三:删除和修改名字
emmm还是个简单的操作
handleFileRemove(file,i){//删除图片
console.log(file,i)
if(!file.url){
return false;
}
let that = this;
this.$confirm('是否删除此附件?','提示',{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//可添加ajax
this.$message.success("删除成功")
this.$message({
type: 'success',
message: '删除成功',
onClose: () => {
that.imagelist.splice(i,1)
}
})
}).catch((meg) => console.log(meg))
},
handleFileName(file,i){//修改名字
console.log(file,i)
let that = this;
this.$prompt("请输入新文件名:","提示:",{
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(({ value }) => {
console.log(value)
if(!value){
return false;
}
//可添加ajax
this.$message.success("操作成功")
that.imagelist[i].name = value
}).catch(() => {})
},
效果图:
步骤四:上传进程
emmm其实这篇文章的重点在这儿。
css:
<style>
...
.img-list .img-upload{
float:left;
width:200px;
height:270px;
display:table;
text-align:center;
}
.img-list .uploader{
width:100%;
display:table-cell;
vertical-align:middle;
}
</style>
<template>
...
<div class="img-upload">
<el-upload class="uploader" accept="image/*"
ref="upload"
list-type="picture-card"
:show-file-list="false"
:action="params.action"
:data="params.data"
:on-change="uploadOnChange"
:on-success="uploadOnSuccess"
:on-error="uploadOnError"
:on-progress="uploadOnProgress">
<el-button type="primary">点击上传</el-button>
</el-upload>
</div>
</template>
<script>
...
data(){
return {
params: {
action: 'http://jsonplaceholder.typicode.com/posts/',
data: {}
}
}
},
...
methods: {
uploadOnProgress(e,file){//开始上传
console.log(e.percent,file)
},
uploadOnChange(file){
console.log("——————————change——————————")
// console.log(file)
if(file.status == 'ready'){
console.log("ready")
}else if(file.status == 'fail'){
this.$message.error("图片上传出错,请刷新重试!")
}
},
uploadOnSuccess(e,file){//上传附件
console.log("——————————success——————————")
this.$message.success("上传成功")
},
uploadOnError(e,file){
console.log("——————————error——————————")
console.log(e)
},
}
</script>
插播一则tips:在项目中文件是直接上传到阿里云,上传参数
data
会动态变化。但是由于自动上传一直出错(上传参数data
有些关键字不存在),后来用手动上传却是可行。所以测试了半天才采用以下方式:
<el-upload :auto-upload="false"></el-upload>
methods:
uploadOnChange(file){
if(file.status == 'ready'){
this.params.data = {
//change
}
this.$nextTick(() => {
this.$refs.upload.submit();
})
}
}
加个上传加载的过程,el-progress
组件恰好适用
css:
.img-list .img-progress{
text-align:center;
padding-top:50px;
}
<div v-if="!pass && progress !== 0" class="img-content img-progress">
<el-progress type="circle" :percentage="progress" :status="proStatus"></el-progress>
</div>
data:
data(){
return {
progress: 0,//上传进度
pass: null,//是否上传成功
}
},
computed: {
proStatus(){//上传状态
if(this.pass){
return 'success'
}else if(this.pass == false){
return 'exception'
}else{
return ''
}
}
},
methods:
uploadOnProgress(e,file){//开始上传
console.log(e.percent,file)
this.progress = Math.floor(e.percent)
},
uploadOnChange(file){
console.log("——————————change——————————")
// console.log(file)
if(file.status == 'ready'){
console.log("ready")
//重置progress组件
this.pass = null;
this.progress = 0;
}else if(file.status == 'fail'){
this.$message.error("图片上传出错,请刷新重试!")
}
},
uploadOnSuccess(e,file){//上传附件
console.log("——————————success——————————")
this.pass = true;
this.$message.success("上传成功")
this.imagelist.push({
url: file.url,
name: '新增图片'
})
},
uploadOnError(e,file){
console.log("——————————error——————————")
console.log(e)
this.pass = false;
},
原本是用this.progress
控制status
,但是后来发现及时上传进度100%也不一定上传成功,所以改用this.pass
。用饿了么的上传地址偶尔会跨域报错,上传多几次又成了=。=
Github地址:点我点我点我(component/uploadlist.vue)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。