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”