自定义el-upload实现图文上传

奚和光
2023-12-01

一、跨域踩坑(axios):
第一步:config/index.js文件设置跨域

dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/':{//此处并非一定和url一致。
target:'后台ip+端口地址',
changeOrigin:true,//允许跨域
pathRewrite:{
'^/': ''
},
}
},

第二步:
main.js文件引入axios

import axios from 'axios';
Vue.prototype.$axios = axios//全局注册,使用方法为this.$axios.post/patch/delete/get(后台接口地址)

第三步:
在main.js同级目录创建一个 https.js 文件,设置响应拦截,添加请求头,修改完后记得重启项目应用配置。

import axios from 'axios'
axios.defaults.headers.post['Content-Type']='application/x-www-from-urlencoded';
// 窗体数据被编码为名称/值对,标准编码格式
// 请求拦截器
axios.interceptors.request.use(function(config){
return config;
},function(error){
return Promise.reject(error);
})
// 响应拦截器
axios.interceptors.response.use(function(response){
return response;
},function(error){
return Promise.reject(error);
})
export function fetch(url,params){
return new Promise((resolve,reject)=>{
axios.post(url,params)
.then(response => {
resolve(response.data)
})
.catch((error)=>{
reject(error);
})
})
}
export default{
mockdata(url,params){
return fetch(url,params);
}
}

二、上传踩坑:
要求是字段和图片一起上传,允许批量上传,批量修改前缀。
最开始的想法是做一个form表单的弹窗,里面一个el-input框,一个el-upload负责图片上传,提交表单的时候将输入框里的内容附在 el-upload里的:data里一起上传,设置:multiple=“true”,允许多文件上传,accept="image/jpeg, image/jpg, image/png"限制上传文件限制为图片。

第一个坑:判断文件上传成功还是失败。
el-upload有设置专门的on-success钩子和on-error钩子,参数都是 response, file, fileList,书写回调函数的时候核心代码其实只需要this.uploadFile = fileList一句话即可(如果没有特殊要求)。

第二个坑:添加前缀。
因为添加的前缀是随着el-upload生成的FromData一起上传的,我的想法就是在 :before-upload="beforeUpload"里书写相应函数,读取输入框内容并附加上去。但尝试之后发现失败了,百度后发现:before-upload里的函数是异步执行的,我为了方便el-upload设置的是自动上传,结果前缀没传上去,图片先传完提交了。

解决方法就是设置:auto-upload=“false”,关闭自动上传,el-upload里添加ref属性,在form表单提交的时候使用this.$refs.upload.submit()手动进行提交。

<el-upload
class="upload-demo"
list-type="picture-card"
accept="image/jpeg, image/jpg, image/png"
action="后台接口"
:auto-upload="false"
ref="upload"
:multiple="true"
:data="configForm"
:on-remove="handleUploadRemove"
:onSuccess="handleUploadSuccess"
>

第三个坑:清除缓存
提交一次上传之后,输入框和上传文件的框内默认会保留上一次输入的信息。
inup框内设置关闭autocomplete=“off”,el-upload则是在上传成功后的自定义回调函数里设置this.$refs.upload.clearFiles();清除提交成功后的图片缓存。

三、更新踩坑
更新图片要求是不改变前缀,不改变生成地址,只改变图片本身。
更新形式弹窗更新,编辑选中行数据,编辑完成后自动关闭弹窗。使用slot-scope,设置click事件"handleEdit(scope.KaTeX parse error: Expected '}', got 'EOF' at end of input: …onExceed="()=>{message.error(‘一次只能更新一张图片!’)}"。

四、分页相关
获取数据和分页的函数基本上通用的,不进行复杂处理的情况下变动不大(table表格显示数据)。
data()写入:

paginations: {
page_index: 当前位于哪页
total: 总数
page_size:  1页显示多少条
page_sizes:每页显示多少条
layout: 翻页属性
}

获取数据:

getProfile() {
this.$axios.post("后台接口").then(res => {
this.tableData = res.data;
this.allTableData = res.data;
this.filterTableData = res.data;
// 设置分页数据
this.setPaginations();
});

通用分页设置:

// 当前页
handleCurrentChange(page) {
let sortnum = this.paginations.page_size * (page - 1);
let table = this.allTableData.filter((item, index) => {
return index >= sortnum;
});
// 设置默认分页数据
this.tableData = table.filter((item, index) => {
return index < this.paginations.page_size;
});
},
// 切换size
handleSizeChange(page_size) {
this.paginations.page_index = 1;
this.paginations.page_size = page_size;
this.tableData = this.allTableData.filter((item, index) => {
return index < page_size;
});
},
// 总页数
setPaginations() {
// 总页数
this.paginations.total = this.allTableData.length;
this.paginations.page_index = 1;
this.paginations.page_size = 5;
// 设置默认分页数据
this.tableData = this.allTableData.filter((item, index) => {
return index < this.paginations.page_size;
});
}

五、搜索
搜索一般除了点击搜索图标搜索之外,也需要支持enter键搜索,这就需要监听回车键实现搜索。
添加@keyup.enter.native,el-input监听回车键实现搜索,非el-input 组件,可以直接用@keyup.enter实现监听。

实际是直接调用的后台接口实现搜索,但是也可以尝试一下前端实现搜索(存在获取全部数据接口的前提下是可以实现前端搜索的,但是数据量大的情况下后台处理更好),这里只贴一下前端实现搜索的思路,仅做参考。

SelectImg() {
var imgName = this.search_data.name;
this.allTableData = this.filterTableData.filter(item => {
if (!imgName) {
console.log("图片名不能为空!");
this.getProfile();
return;
} else {
return Object.keys(item).some(vals => {
return (
String(item[vals])
.toLowerCase()
.indexOf(imgName) > -1
);
});
}
});
// 分页数据
this.setPaginations();
}

六、书写页面时遇到的一些问题总结:

Q:绘制Canvas出现Cannot read property ‘getContext’ of null;
A:chrome下需要文档载入完成后才能获得canvas对象,方法写在 mounted()中即可。

Q:截取相同字符之间的字段
A:match(/#(.*?)#/g);

Q:element-ui Input加搜索图标。
A: suffix-icon 在搜索框后加入图标,prefix-icon 在搜索框头部加入图标。

Q:Cannot read property ‘filter’ of undefined。
A:后端内容返回之前先进行了分页操作,空数据使用过滤器,控制台会Cannot read property ‘xxx’ of undefined的错误。(根据实际情况判断,大部分情况下报这种类型的错误是因为没有声明或者是名称不一致)

Q:vue-router切换页面时如何设置过渡动画。
A:页面定义层级,监控路由跳转,判断切换页面之间的层级关系,并以此来判断路由前进或者后退,编写相应过渡动画即可。(最后这个方案废弃了,因为切换的时候页面内容会向一个方向压缩,过渡时间短了视觉效果不佳,长了又会看到压扁的页面残影)。

 类似资料: