Vue中读取本地图片实现预览和上传

先看效果图:

在这里插入图片描述
上面展示了两张从本地添加的准备上传服务器的预览图片,效果还不错吧,哈哈哈。

下面是该页面中紫色框的布局与实现代码,我想有些人也不喜欢HTML中默认的上传文件样式,实在辣眼睛:

<template>
      <div class="uploadFile">
        <!-- ul、li标签用于展示从本地添加的预览图片 -->
        <ul v-show="uploadImg.length!=0">
          <li v-for="(item,index) in uploadImg"
              :key="index"
              class="addPic">
            <img :src="item">
          </li>
        </ul>
        <input type="file"
               id="file"
               accept="image/*"
               @change="getPicture($event)">
        <button @click="callFile"
                v-show="showInputImg">+</button>
      </div>
</template>
<script>
	export default {
     
     
		data(){
     
     
			return {
     
     
				uploadImg:[]
			}
		},
  		computed: {
     
     
		    showInputImg () {
     
     
		      return this.uploadImg.length < 3;
		    }
  		},
  		methods: {
     
     
  			getPicture (e) {
     
     
		      //预览图片
		      let src = window.URL.createObjectURL(e.target.files[0]);
		      this.uploadImg.push(src);
		
		      //将图片文件转化成base64格式图片
		      var reader = new FileReader();
		      reader.onload = (e) => {
     
     
		        //e.target.result  就是从本地读取的图片的base64格式,将它上传给服务器即可
		        //使用axios的post方法上传即可
		      }
		      reader.readAsDataURL(e.target.files[0])
		    },
		    callFile () {
     
     
		      //点击添加图片按钮,触发type:"file"的input标签
		      let fileDom = document.querySelector("#file")
		      fileDom.click()
		    }
  		}
	}
</script>
<style scoped>
		input {
     
     
		  /* 隐藏默认的"打开文件"样式 */
		  display: none;
		}
		.uploadFile {
     
     
		  display: flex;
		  height: 120px;
		  line-height: 120px;
		  padding: 10px 0;
		  border-bottom: 1px solid rgb(235, 235, 235);
		  overflow: hidden;
		}
		.uploadFile ul {
     
     
		  display: flex;
		}
		.uploadFile ul li {
     
     
		  margin-right: 10px;
		}
		.uploadFile .addPic img {
     
     
		  height: 100px;
		  width: 100px;
		}
		.uploadFile button {
     
     
		  height: 100px;
		  width: 100px;
		  font-size: 50px;
		  border: 1px dashed rgb(182, 182, 182);
		  color: rgb(182, 182, 182);
		  background-color: rgb(243, 243, 243);
		}
</style>

上面是紫色框中完整的代码。

HTML分析:

  1. ul、li 标签是用于展示从本地选中的图片的,uploadImg数组是用于存放选中的图片的"临时"URL,若uploadImg.length==0表明没有选中本地图片,则此时ul、li标签不展示。
  2. 当type="file"的input标签是用于打开本地文件的,它有个默认样式,但在css中我们将它设置为不展示,即display:none.
  3. button标签就是紫色框中的带有+号的选择图片的方框按钮,它触发打开本地文件界面。button的v-show绑定了一个计算属性控制着该按钮的显示,因为我只想让它最多添加三张图片,当有三张图片后,就不再展示这个按钮,自然就实现了最多添加三张图片。

JS分析:

  1. callFile()被按钮的点击事件绑定,当点击按钮它就调用input标签的click事件,因为为了更美观的样式,input被我们设置为不可见,那么我们只能通过按钮点击去调用input的click事件,从而打开本地文件界面。
  2. input标签的change事件绑定了getPicture()函数,即当用户点击选中某张图片,那么就会触发change事件。参数$event带有选中图片相关的信息。可以通过console.log(e.target.files)查看选中文件的信息。为什么我们使用e.target.files[0]呢?因为我这里实现的是选中单张图片,因此files数组中的0下标就是我们选中的图片信息。
  3. 为了预览图片,我们需要生成一个URL,即使用window.URL.createObjectURL(e.target.files[0]),注意:这个URL是临时URL,不是服务器返回的图片URL,当我们关闭网页,该URL就会失效,因此用来预览图片非常合适。
  4. FileReader是文件读取函数,reader.readAsDataURL(e.target.files[0])这是同步读取文件,参数就是图片的相关信息,当图片读取完毕之后就会触发reader.onload,进而执行它的回调函数,注意这里的回调函数最好使用箭头函数,因为箭头函数不改变this指针的指向,此时this还是指向vue组件实例,如果是function(){}则this.指向这个文件对象。

猜你喜欢

转载自blog.csdn.net/weixin_43334673/article/details/110564172