• 每日技术: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>

    关键点:

    1. 上传文件file控件的e对象里面有很多信息,其中要用到 e.target.files 
    2. new FormData() 
    3. 请求头header
    4. 请求成功返回的数据存入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

  • 相关阅读:
    System.Web.HttpRequestValidationException——从客户端检测到危险的Request值
    SignalR 实现web浏览器客户端与服务端的推送功能
    MVC4项目中验证用户登录一个特性就搞定
    C# winform 上传文件到服务器
    解决memcached不能远程访问的问题
    MVC4验证用户登录特性实现方法
    IIS增加并发数
    IIS处理并发请求时出现的问题及解决
    jQuery使用ajax跨域获取数据
    jQuery调用WCF服务传递JSON对象
  • 原文地址:https://www.cnblogs.com/cathy1024/p/10276618.html
Copyright © 2020-2023  润新知