vue项目实战速查记录

     1.图片下载到本地
     2.本地静态文件访问
     3.元素大小相同,相互覆盖
     4.vue项目打包动态切换环境
     5.vue项目占满全屏
     6.element相关
         6.1 el-upload
         6.11 el-upload中on-change校验文件数量限制失效问题与before-upload区别
         6.12 修改el-upload样式大小
         6.13 el-upload中accept文件类型限制失效问题
         6.14 el-upload中on-change多文件上传如何确定是否是最后一个文件
         6.15 el-upload+el-progress实现多文件上传进度条显示
         6.16 el-radio
         6.17 el-checkbox-group中v-model赋值后点击不生效
         6.18 el-table中一列显示多行
         6.19 el-upload中before-upload上传图片成功后不显示问题
         6.20 el-avatar中本地图片不显示问题
         6.21 el-table-column中数据为空设置默认值
         6.22 设置图标以及鼠标悬浮显示文字
     7.异常抛出与捕获
     8.Invalid prop: type check failed for prop “limit”. Expected Number with value 1, got String with value “1”.
     9.集合v-if判空报错,length报错

1.图片下载到本地

     实现原理:创建a标签,利用a标签下载属性.

  download(){
		   const link = document.createElement('a');
			link.href = "图片地址";
			link.setAttribute('download', name);
			document.body.appendChild(link);
			link.click();
		  }

PC端下载会自动调用浏览器文件下载选择窗口,谷歌浏览器默认指定下载位置不会弹窗,360浏览器可正常显示下载窗口.

2.本地静态文件访问

vue项目中按照项目路径直接访问静态文件是无法正常显示的
在这里插入图片描述
处理办法是静态文件项目路径使用require进行引入:

data() {
	    return{
			// qrCodeUrl:require("../assets/qrcode_bg.png"),
			qrCodeUrl:"../assets/qrcode_bg.png",
		}
	  },

可以正常访问:在这里插入图片描述

3.元素大小相同,相互覆盖

问题背景:canvas标签生成二维码,canvas需要占据一定空间,生成的二维码地址赋值给img标签,由于初始化canvas不需要展示,想将img初始化赋值默认图片覆盖掉canvas,然后生成二维码图片之后赋值新的图片地址.实现原理:

使用绝对定位来实现。父元素需要设置为相对定位(position: relative),
各子元素设置为绝对定位(position: absolute),z-index属性大的子元素显示在最上方.

4.vue项目打包动态切换环境

想要实现dev或是pro不同环境下进行区分打包.需要动态切换vue.conifg.js中publicPath.记录一下实现过程:
创建两个dev和pro配置文件
在这里插入图片描述
内容分别为:

VUE APP RUN ENV='development'

pro:

VUE APP RUN ENV='production'

vue.config.js中:

module.exports = {
	publicPath: process.env.NODE_ENV == 'production' ? '/qrCode_pro/' : '/qrCode_dev/',
}

package.json中:

"scripts": {
    "serve": "vue-cli-service serve",
    "build-dev": "vue-cli-service build --mode development", -- 指定配置环境
    "build-pro": "vue-cli-service build --mode production",
  },

打包操作时执行build-dev或是build-pro可实现区分环境.

5.vue项目占满全屏

 width: 100vw;           /* 视口宽度 */
height: 100vh;          /* 视口高度 */

6.1 el-upload

6.11 el-upload中on-change校验文件数量限制失效问题

  el-upload默认是通过action属性指定上传url进行自动上传,实际上大多数情况需要手动上传,此时应该设置

:auto-upload="false"

手动设置情况下action不需要设置请求路径:

action="#"

  选择文件后,且手动上传时(:auto-upload=“false”)调用,此函数执行默认为异步操作,选择几个文件就会执行几次.校验文件大小逻辑可以在此函数中执行,校验文件数量不可在此函数执行,原因是未达到文件最大限制之前的文件上传处理都会执行成功,与达到最大数量限制一个文件都不处理的初衷相违背.如果需要文件大小限制需要使用limit和on-exceed.示例:

<el-upload  :limit="2"  :on-exceed="exceedCount"></el-upload>
			exceedCount(files, fileList) {
				console.log("exceedCount执行了:", files, fileList)
				// 可添加文件达到最大数量限制提示
			},

  测试发现如果选择文件超过limit数量限制,on-change不会执行.也就达到了校验不通过,后续处理不执行的目的.
如果限制数量最大只有一个,除了使用limit也可以不使用multiple,即不支持多选.

手动上传模式通过on-change属性获取文件内容

handleChange(file, fileList) {
			// 此处的file以及fileList是组件自动获取
			},

非手动上传模式一般是通过before-upload获取文件内容

6.12 修改el-upload样式大小

.el-icon-upload:before {
    content: '\e7c3'   //设置图标
}
.el-icon-upload {
    font-size: 30px;      //图标的尺寸大小
    margin: 4px 0 2px;   //图标与四周元素的间距
}
//下面这几行代码就是设置上传框的长宽,可以按百分比来设置也可以用px去设置
/deep/ .el-upload .el-upload-dragger {
    width: 120%;
    height: 80%;
}

6.13 el-upload中accept文件类型限制失效问题

el-uplaod中使用accept限制选择文件类型,但出现的问题是还是可以选择所有文件,这样文件类型就会失效

<el-upload  accept="image/*" :on-change="handleChange"></el-upload>

在这里插入图片描述
处理方法是在on-change或是before-upload中校验文件类型是否一致.如果不一致则异常提示.示例:

handleChange(file, fileList) {
if (!file.raw.type.startsWith("image")) {
							throw new Error("文件类型不合法,请选择图片类型!");
						}}

6.14 el-upload中on-change多文件上传如何确定是否是最后一个文件

先说一下业务场景:一次实现多文件上传,使用on-change监听文件状态并再此实现文件类型校验,一次选择多个文件,on-change会执行多次,想要实现的逻辑是所有文件都通过校验之后才会执行上传文件逻辑,就需要确定on-change中最后一次文件执行的时机,并再此时机中执行文件上传逻辑.本身on-change默认异步处理,可以使用定时来实现同步效果.好比是两个运动员一块起跑,等到一定时间看下是否完成.

<el-upload  :on-change="handleChange"></el-upload>
handleChange(file, fileList) {
console.log("file:", file, "fileList:", fileList)
	try {
					// 判断文件类型是否有效
						if (!file.raw.type.startsWith("image")) {
							this.errorFlag = true
							throw new Error("文件类型不合法,请选择图片类型!");
						}
					// 多文件上传每个文件onchange都会执行一次,只需要最后一次文件选择执行
					this.maxLength = Math.max(length, this.maxLength)
					this.onlyLastTimeOut = setTimeout(() => {
						if (length === this.maxLength) { // 你的上传文件逻辑
							console.log("最后一次执行了,", file)
							// 执行上传逻辑
						}
					}, 100)
				} catch (error) {
					// 类型校验失败,则取消定时器
					if (this.onlyLastTimeOut) {
						clearTimeout(this.onlyLastTimeOut);
						this.onlyLastTimeOut = null;
					}
				} finally {
					// 清除文件,el-upload不显示文件列表
					if (this.errorFlag) {
						this.$refs.upload.clearFiles()
					}
				}
			}
						}}

上传两个文件,定时逻辑中只执行一次:
在这里插入图片描述

其中另外需要注意的一点是如果文件校验失败,需要取消定时,处理方法就是将文件校验异常捕获后看下定时器对象是否存在,存在则取消.相关内容如下:

catch (error) {
				// 类型校验失败,则取消定时器
				if (this.onlyLastTimeOut) {
					clearTimeout(this.onlyLastTimeOut);
					this.onlyLastTimeOut = null;
				}
			} 

6.15 el-upload+el-progress实现多文件上传进度条显示

多文件上传原理是用el-upload中on-change方法,一次选择多个文件,每个文件上传时都会执行on-change方法.具体上传使用的是阿里云oss的分片上传,支持返回上传进度.下面记录一下实现相关内容.
实现效果:
在这里插入图片描述

进度条真实显示,当然关于进度条也可以用假的来实现,这里不再展开.

<el-upload ref="upload" :auto-upload="false" v-if="showUpload" multiple
							:on-change="handleChange" accept="image/*" drag action="#" :limit="5"
							:on-exceed="exceedCount">
							<i class="el-icon-upload"></i>
							<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
						</el-upload>
						<div v-else v-for="(fileItem,index) in fileList">
							{{fileItem.name}}
							<el-progress :text-inside="true" :stroke-width="20" style="margin-top: 5px;"
								:percentage="fileItem.percentage"></el-progress>
						</div>

涉及方法:

async handleChange(file, fileList,) {
				this.showUpload = false
				// 设置路径
				var filePath = "/img/"
				var fileInfo = file.raw
				var errorFlag = false // 是否出现最少一次校验失败文件
				this.fileList = fileList
				var length = fileList.length
				try {

					// 多文件上传每个文件onchange都会执行一次,只需要最后一次文件选择执行
					await this.uploadFile(filePath, fileInfo.name, fileInfo)

				} catch (error) {
					// 处理多个提示信息重叠问题
					setTimeout(() => {
						this.msgError(error.message)
					}, 10);
				} finally {
					// 清除文件,el-upload不显示文件列表
					if (this.errorFlag) {
						this.$refs.upload.clearFiles()
					}
				}
			},

上传处理:

async uploadFile(filePath, fileName, file) {
				// 判断认证信息是否过期
				if (this.isCredentialsExpired(this.credentials)) {
					//获取临时认证权限
					await getStsCredentials().then(res => {
						if (res.code === 200) {
							this.credentials = JSON.parse(res.data)
						}
					}).catch((err) => {
						console.log("err:", err)
						throw new Error("请求失败!");
					})
					if (!this.credentials) {
						throw new Error("操作失败,请重试!");
					}
					const OSS = require('ali-oss');
					this.client = new OSS({
						// 将<YOUR_BUCKET>设置为OSS Bucket名称。
						bucket: bucketName,
						// 将<YOUR_REGION>设置为OSS Bucket所在地域,例如oss-cn-hangzhou。
						region: region,
						accessKeyId: this.credentials.accessKeyId,
						accessKeySecret: this.credentials.accessKeySecret,
						stsToken: this.credentials.securityToken
					});
					await this.ossUpload(filePath, fileName, file, this.client, )
				} else {
					await this.ossUpload(filePath, fileName, file, this.client)
				}
			},

oss上传:

async ossUpload(filePath, fileName, file, client) {
			const options = {
				// 获取分片上传进度、断点和返回值。
				progress: (p, cpt, res) => {
					console.log("上传进度:", p);
					// fileProcess.percentage = p
					this.fileList.map(item => {
						if (item.name == fileName) {
							if (item.percentage != 100) {
								item.percentage = parseInt(p * 100)
							}
						}
					})
				},
				// 设置并发上传的分片数量。
				// parallel: 4,
				// 设置分片大小。默认值为1 MB,最小值为100 KB。
				partSize: 1024 * 1024,
				timeout: 120000
			};
			// 这里使用oss分片上传
			await this.client.multipartUpload(filePath + fileName, file, options).then(res => {
				console.log("res:", res)
				if (this.contentUrl) {
					this.contentUrl = this.contentUrl + "," + ossPrefix + filePath + fileName
				} else {
					this.contentUrl = ossPrefix + filePath + fileName
				}
				this.fileNameArray.push(fileProcess)
			}).catch(err => {
				console.log(2222, err)
				throw new Error("操作失败,请重试!");
			})
		},

需要注意的是多文件上传进度条赋值的问题,每个文件都是异步上传,只能通过确定onchange当前执行的文件和文件数组名进行确定文件此次执行的是哪个文件,然后进行对应赋值.

6.16 el-radio

单选是否实现:

<el-radio-group v-model="valid" @change="validChange">
						<el-radio :label="true"></el-radio>
						<el-radio :label="false"></el-radio>
					</el-radio-group>
data() {
			return {
				valid:false		
		}}
methods:{
	validFlagChange(event) {
				console.log("单选切换变化:",event)
			},
}

需要注意的是el-radio中如果用布尔类型,label需要进行数据绑定;
单选值变化通过change事件进行监听

6.17 el-checkbox-group中v-model赋值后点击不生效

<el-checkbox-group v-model="form.userIds" @change="handleCheckedChange">
			<el-checkbox v-for="user in userList" :label="user.userId"
				:key="user.userId">{{user.userName}}</el-checkbox>
		</el-checkbox-group>

场景是编辑页面给form.userIds赋值后点击任意多选框点击无效.处理方法是使用$set赋值:

this.$set(this.form, 'userIds', userIds)

6.18 el-table中一列显示多行

实现效果如下:
在这里插入图片描述
实现方式:

<el-table-column label="选项" width="300">
				<template slot-scope="scope">
					<div v-for="(accessExamContent, index) in scope.row.accessExamContentList" :key="index">
						{{accessExamContent.content}}<br>
					</div>
				</template>
			</el-table-column>

6.19 el-upload中before-upload上传图片成功后不显示问题

处理方式是使用set方法强制更新

<el-upload 	 action="#" :show-file-list="false" :before-upload="beforeAvatarUpload">
						</el-upload>
beforeAvatarUpload(file) {
			
			let form = new FormData();
			form.append("multipartFile", file);
			form.append("fileType", 1);
			const tokenStr = window.localStorage.getItem('aaa')
			axios.post('/aliyun/uploadImg', form, {
					headers: {
						'Content-Type': 'multipart/form-data',
						token:tokenStr
					},
					timeout: 20000,
				}).then((res) => {
					if (res.code === 200) {
					   this.$set(this.updateForm, 'src', res.data); //强制更新图片
						this.updateForm.customImg = res.data
						this.msgSuccess('上传成功!')
						 return false
					} else {
						this.msgError("图片上传失败")
					}
				})
				.catch((res) => {
					console.log('res', res)
					this.msgError("图片上传失败")
				});
		},

补充另一种不生效的处理办法:data中需要定义图片属性

updateForm: {
					customImg 
				},

6.20 el-avatar中本地图片不显示问题

el-avatar中本地图片不显示,但是img使用相同的路径就可以显示.如果是这种情况按照下面方式引入即可:

 <el-avatar shape="square" :size="40" :src="require('../assets/img/login.jpg')"></el-avatar>

6.21 el-table-column中数据为空设置默认值

<el-table-column prop="identity" label="身份" width="200">
				<template slot-scope="scope">
					{{scope.row.identity || '无'}}
				</template>
			</el-table-column>

6.22 设置图标以及鼠标悬浮显示文字

 <el-tooltip class="item" effect="dark" content="试题随机模式:每个用户开始考试后不同题型下题目显示." placement="right">
				    <i class="el-icon-question" style="margin-left: 10px;font-size: 20px;color: blue;"></i>
				    </el-tooltip>

7.异常抛出与捕获

自定义异常

throw new Error('"异常信息");

捕获异常与获取异常信息

try {
throw new Error('"异常信息");
} catch (e) {
  console.log("异常信息:",e.message)
} finally {
  console.log('不管有没有错误,都会执行')
}

8.Invalid prop: type check failed for prop “limit”. Expected Number with value 1, got String with value “1”.

出现类似异常一般数数据绑定问题,错误写法:

<el-upload   limit="1"></el-upload>

正确写法:

<el-upload   :limit="1"></el-upload>

9.集合v-if判空报错,length报错

<template slot-scope="scope">
					<div v-if="!scope.row.mediaInfoList">暂无</div>
					<el-image v-else  v-for="(item,index) in scope.row.mediaInfoList" :key="index" :src="item"
					></el-image>
				</template>
				// 或是v-if=“scope.row.mediaInfoList && scope.row.mediaInfoList。length >0”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卖柴火的小伙子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值