本文介绍: PC端和Mob端最多可以上传3张照片 每张大小不超过3M 格式支持bmp,gif,jpg,png,jpeg PC端上传图片展示添加图片按钮和上传图片文案描述中间 mob默认一个添加图片的图 如果上传了图片 会出现在添加图片这张图之前 上传到第三张时候 添加图片这张图就隐藏掉了 当前显示3张正方形的上传图。这里写的有点多哈 大家可以不看这块 只看js业务逻辑部分 这里思路上面已经写出来了 业务逻辑也不一定一致 大家按照思路自己写就好。layoutmobileonly手机端的样式适配

1.场景

工作场景中,需要一个上传图片功能 效果如下

PC端

 mob

2.业务逻辑

PC端和Mob端最多可以上传3张照片 每张大小不超过3M 格式支持bmp,gif,jpg,png,jpeg PC端上传的图片展示添加图片按钮和上传图片文案描述中间 mob默认一个添加图片的图 如果上传了图片 会出现在添加图片这张图之前 上传到第三张的时候 添加图片这张图就隐藏掉了 当前显示3张正方形的上传图。 PC和Mob端每一个上传好的图上面都有一个x按钮 点击x可以删除掉上传的图片 并且这个块是封装成了组件 组件复用在了查看详情页 如果是查看详情 进入这个组件 我这里会传递进来一个resonDisabledinput隐藏掉 只能查看当前内容 不能点击上传 代码里的:class=”{ ‘componentorderreturndetail__applyabouthidden’: resonDisabled }”就是控制input隐藏

3.前后端约定

formdata方式上传 key value格式 上传 这里的baseUrl就是接口请求地址公共url 做了全局配置而已 可以忽略 这个截图主要看传参格式

4.css部分代码

css实现先写了个父元素 包含input和上面的上传图片按钮元素 position:relative;子元素 position:absolute;input大小和上面的添加图片按钮大小一致  然后设置opacity: 0;并且input的z-index层级设置的高一点 透明的浮在按钮之上

layoutmobileonly手机端的样式适配 

layoutdesktop 是PC端的样式适配

layoutresponsive手机端和PC端分别是什么样式

如果需要写单端 可以手动把这些代码分离出来

这里写的有点多哈 大家可以不看这块 只看js业务逻辑部分 这里思路上面已经写出来了 业务逻辑也不一定一致 大家按照思路自己写就好

<!-- 上传图片按钮相关代码 -->
<div class="component-order-return-detail__apply-about-outer">
    <div class="component-order-return-detail__apply-about-reason">图片信息</div>
    <div class="component-order-return-detail__apply-about-position layout-desktop-only">
        <div class="component-order-return-detail__apply-about-upload">+ 添加图片</div>
        <input class="component-order-return-detail__apply-about-file component-order-return-detail__apply-about-upload" :class="{ 'component-order-return-detail__apply-about-hidden': resonDisabled }" type="file" multiple accept="image/png,image/jpeg,image/jpg,image/gif,image/bmp" @change="uploadApplyImage" />
    </div>
</div>
<!-- PC端展示上传的图相关代码 以及mob端展示默认上传按钮以及上传图片以后 不够3张 默认图片往后推移相关逻辑 -->
<div v-if="showUploadImage" class="component-order-return-detail__apply-about-static">
    <div v-for="(item, index) of returnImageInfo" :key="index" class="component-order-return-detail__apply-about-static-outer">
        <img class="component-order-return-detail__apply-about-img" :src="item.url" alt="" />
        <svg-icon name="icon-delete-img" class="component-order-return-detail__delete-svg" @click="deleteImage"></svg-icon>
    </div>
    <img v-if="returnImageInfo.length < 3" class="component-order-return-detail__apply-about-img" :src="addMobileImage" alt="" />
</div>

<style lang="scss">
    $MQMobile: 1024px !default;
    @mixin layout-mobile-only {
      @media (max-width: calc(#{$MQMobile - 1px})) {
        @content;
      }
    }

    @mixin layout-desktop {
      @media (min-width: $MQMobile) {
        @content;
      }
    }

    // RESPONSIVE
    @mixin layout-responsive($property, $mobile: null, $desktop: null, $lage-desktop: null) {
      @if ($mobile) {
        @include layout-mobile {
          #{$property}: $mobile;
        }
      }
      @if ($desktop) {
        @include layout-desktop {
          #{$property}: $desktop;
        }
      }
    }
    .component-order-return-detail__apply-about-outer {
      width: 100%;
      @include layout-desktop {
        display: flex;
        align-items: center;
      }
      .block-input {
        @include layout-mobile-only {
          background-color: transparent !important;
        }
      }
      @include layout-responsive(margin-top, vw(24), 26px);

      .component-order-return-detail__apply-about-reason {
        @include layout-responsive(width, 100%, 100px);
        @include layout-mobile-only {
          margin-bottom: vw(6);
        }
        @include layout-desktop {
          margin-right: 49px;
        }
      }
      .component-order-return-detail__reason-red {
        color: red;
      }
      .component-order-return-detail__apply-about-input {
        color: #888;
        @include layout-responsive(font-size, vw(13), 13px);
        @include layout-responsive(width, 100%, 335px);
        @include layout-responsive(height, vw(36), 36px);
        .block-input {
          color: #888;
        }
        .is-black {
          border-color: #c0c0c0 !important;
        }
      }
      .component-order-return-detail__apply-about-textarea {
        box-sizing: border-box;
        color: #888;
        @include layout-responsive(width, 100%, 642px);
        @include layout-responsive(height, vw(100), 117px);
        @include layout-responsive(line-height, vw(20), 20px);
        @include layout-responsive(padding, vw(9) vw(5), 8px 11px);
      }
      .component-order-return-detail__apply-about-position {
        position: relative;
        width: 335px;
        height: 36px;
        .component-order-return-detail__apply-about-hidden {
          display: none !important;
        }
        .component-order-return-detail__apply-about-file {
          position: absolute;
          z-index: 9;
          opacity: 0;
        }
        .component-order-return-detail__apply-about-upload {
          @include layout-desktop {
            position: absolute;
            width: 335px;
            height: 36px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #888;
            font-size: 13px;
            border: 1px solid #c0c0c0;
          }
        }
      }
    }
</style>

样式基本上就写好了

5.js部分代码

下面是js部分逻辑 看起来内容有点多 但是注释的很详细 可以耐心看一下 按需贴到自己代码中直接使用 这里的axios是我单独自己写进去的 原项目中 是有封装的 避免看起来麻烦 改写了 如果不小心有问题 大家改一下哈

    // 上传图片 点击input的时候 获取到图片信息
    uploadApplyImage(e) {
		const files = e.target.files
		// 如果获取到了上传的内容 才进行以下业务逻辑操作
		if (files &amp;&amp; files.length > 0) {
			// 如果上传多个图片或者文件 对其进行循环每个文件的格式都进行校验
			for (let i = 0; i < files.length; i++) {
				const file = files[i]
				// 对支持上传的图片格式 进行判断
				if (!/.(jpg|jpeg|png|bmp|gif|JPG|PNG|BMP|GIF)$/.test(file.name)) {
					this.$toast.show('请上传.png /.jpg /.jpeg格式的图片')
				} else if (file.size > 1024 * 1024 * 3) {
					// 弹出不满足上传格式的弹窗
					this.$toast.show('单张图片不可以超过3M,请重新上传')
					return
				} else {
					// 图片超过三张 弹出提示
					if (this.returnImageInfo.length === 3) {
					  this.setToast('最多可上传3张图片')
					  return
					}
					console.log('满足上传条件', file)
					// 转base64格式 这里约定的格式是key value 直接传file就好 就没用到base64
					// const reader = new FileReader()
					// // 因为这两个组件fils文件不一样所有一个判断
					// if (file?.originFileObj) {
					//   reader.readAsDataURL(file.originFileObj)
					// } else {
					//   reader.readAsDataURL(file)
					// }
					// reader.addEventListener('load', () => {
					//   console.log('reader.result', reader.result)
					// })
					// 转base64格式结束
					// 上传图片 form-data方式进行参数序列化 和后端约定的参数uploadFile
					const formData = new FormData()
					formData.append('uploadFile', file)
					axios.post('/upload', formData,
					{headers: { 'Content-Type': 'application/form-data' }})
					.then(function (response) {
						// 上传成功 执行对应操作
						console.log(response);
					})
					.catch(function (error) {
						// 上传失败 执行对应操作
						console.log(error);
					});
				}
			}
		}
	}

好了 就写到这里吧 希望可以对你有帮助~ 如果大家什么问题 可以私信我 或者我们评论区见 

原文地址:https://blog.csdn.net/qq_38111015/article/details/129832228

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_30490.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注