每日技术:Vue实现上传图片功能
前言:
用vue实现上传图片功能,效果图如下:
先说文件上传控件样式美化怎么做,我有两种方法。
1.先上代码
html部分:
<div class="pics-wrapper"> <div class="addimg-bg"> <input type="file" name="uploadImg" class="ipt-file" @change="fileInput"> </div> <ul class="imgshow"> <li v-for="(item, index) in showImg"> <img :src="item.url"> <i class="icon-del" @click="imgDel(item.id)"></i> </li> </ul>
</div>
CSS(scss)代码如下:
.addimg-wrapper { border: 1px solid #dfdfdf; border-top: 0; height: 153px; padding: 25px; .pics-wrapper { .addimg-bg { float: left; background: url(../static_img/btn-addpic.png) no-repeat center center; width: 78px; height: 78px; } .ipt-file { width: 78px; height: 78px; padding: 0; border: 0; opacity: 0; } .imgshow { float: left; height: 76px; font-size: 0; li { display: inline-block; width: 76px; height: 76px; background-color: #eee; border: 1px solid #dfdfdf; margin-left: 5px; position: relative; img { width: 100%; height: 100%; } .icon-del { display: inline-block; position: absolute; right: 0; top: 0; width: 16px; height: 16px; background: url(../static_img/icon-del.png) no-repeat center center; } } } } }
给input标签外面包一层背景,加号框作为背景,input设置透明度为0
图片素材如下:
btn-addpic.png
icon-del.png
js代码如下:
<script>
new Vue({ el: '#page-publish', data: { msg: 'hello world', imgData: { accept: 'image/gif, image/jpeg, image/png, image/jpg' }, showImg: [] }, methods: { // 添加并上传图片 fileInput(e) { let img1 = e.target.files[0] let type = img1.type let size = img1.size if (this.imgData.accept.indexOf(type) === -1) { alert('请选择我们支持的图片格式!') return false } if (size > 3145728) { alert('请选择3M以内的图片!') return false } let fd = new FormData() fd.append('Filedata', img1, img1.name) axios.post('<{url action=toputil_ctl_uploads@uploads}>', fd, { headers: { 'Content-Type': 'multipart/form-data' } }).then(res => { const data = res.data.data this.showImg.push(data) }).catch(err => { console.log(err) }) }, } })
</script>
关键点:
- 上传文件file控件的e对象里面有很多信息,其中要用到 e.target.files
- new FormData()
- 请求头header
- 请求成功返回的数据存入data中的showImg, v-for循环渲染即可。
但是我需要限制图片数量。最多5张。我可以把这个判断逻辑直接写在fileInput()方法里,但是只要一点击input,就会打开文件选择框,而后才执行fileInput方法里面的代码。这样非常不优雅。所以请看第二种方法。
2.美化上传文件控件第二种方法
Html部分:
<div class="pics-wrapper"> <div class="addimg-bg" @click="addImg"></div> <ul class="imgshow"> <li v-for="(item, index) in showImg"> <img :src="item.url"> <i class="icon-del" @click="imgDel(item.id)"></i> </li> </ul> <input ref="file" type="file" name="uploadImg" class="ipt-file" @change="fileInput"> </div>
CSS代码不变。
Html代码的变化在于单独使用一个div容器显示加号框,和input控件分离。
现在问题是点击加号框的时候如何触发input的change事情,以前用jquery很容易实现的,
jquery版代码:
$(function(){ $('input').click(function(){ // do something }) $('a').click(function(){ $('input').click() // 触发input click事件 }) })
但这是vue啊!!!
我查了好久,终于...
解决方法如下:
(1)给input加上ref="file"
<input ref="file" type="file" name="uploadImg" class="ipt-file" @change="fileInput">
(2)js代码,在vue methods中添加如下代码
// 触发添加图片 addImg () { if (this.showImg.length >= 5) { alert('晒图仅限5张~') return } this.$refs.file.click() },
this.$refs.file.click()
这句是关键。
这样就实现了点击加号框,先判断数量,再触发input控件点击事件。
到这里,添加图片功能实现了,效果如下:
数量超过5张时:
3.删除图片功能
vue methods 中添加如下方法:
// 删除图片 imgDel(id) { axios.post('<{url action=toputil_ctl_uploads@deletePic}>', { id: id }).then(res => { console.log(res) const data = res.data if (data.success) { this.showImg = this.showImg.filter((n) => { return n.id !== id }) } else { alert(data.msg) } }) }
细节没什么要说的,传入要删除的图片id,接口请求成功后,删除相应的数据,用filter方法过滤掉数据。这功能用vue实现还是相当方便。
该页面其他功能,我会另写博文。到时再贴链接。
-----玩-----
我写技术博客的目的主要是整理自己做过的功能,主要是写给自己看,当然,我尽量写清楚。
若给你造成误解,我很抱歉。若给你带来帮助, 我很欣慰。
有疑问欢迎交流 扣扣:2136946914
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了