1.知识充电
1.箭头函数 ()=>{}
什么是箭头函数?
- 箭头函数类似一个匿名函数:var return = (参数列表)=>{函数体}
- 将原函数的“function”关键字和函数名都删掉,并使用“=>”连接参数列表和函数体,返回值是函数体的处理结果
- 当函数参数只有一个,括号可以省略;函数体只有return语句时,可以省略return
- 注意,如果返回一个对象:()=> ({name:“hao”}) 最外层变为小括号
箭头函数有什么用?使用它的好处?
- 使表达更加简洁,隐式返回值;简化回调函数
箭头函数与普通函数的区别?
- 普通函数中的this:代表它的直接调用者,若没找到直接调用者,则this指的是 window (常见的window的属性和方法有: alert, - —location,document,parseInt,setTimeout,setInterval等)或者 undefined
- 箭头函数中的this:代表它的外层调用者,箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象);
2.解构赋值
有什么用?
- 按照一定模式,从数组和对象中提取值,对变量进行赋值
- 赋值两边的结构和格式要保持一致,这样才能对应赋值,左边是key,右边是value
怎么用?
- 数组解构
let [a,b,c]=[0,1,2] - 对象解构
let {name,age} = {name:“swr”,age:28}
3.v-for指令
有什么用?
- 遍历数组元素进行循环渲染
- 遍历一个对象的所有属性
怎么用?
- 遍历数组:
<div v-for="(item, index) in items" :key="item.id">
{{ item.name }}
</div>
items:需要遍历的数组,即源数据数组
item:被迭代的数组元素的别名
index:可选参数,是当前项的索引,从0开始
:key:可以根据它改变渲染的顺序
- 遍历对象:
<div v-for="(value, name, index) in object">
{{ name }}:{{ value }}
</div>
4.JS中的异步操作
什么是异步操作?
当一个操作开始执行后,主程序无需等待它的完成,可以继续向下执行。此时该操作可以跟主程序同就称之为 异步操作。 通常当操作完成时,会执行一个我们事先设定好的回调函数来做后续的处理。
异步会带来什么问题?
按顺序来执行两个操作A和B,传统的解决方法是通过回调,把B作为A的参数传递进去执行,不过这种方案显然不太好,如果有很多异步操作需要顺序执行,就会产生所谓的“回调地狱”。
另外一种解决方案是使用Promise或者async / await来解决
4.async / await
- 控制异步操作顺序执行
- 函数声明之前加上 async 关键字,就变成了异步函数了,返回值为promise。
- await 只有用于异步函数才起作用,基于 promise 的函数之前加上 await ,代码会在此行暂停,直到 promise 操作完成,当然其他代码可以继续执行。
5.FormData
是什么?有什么用?
- 一种表示表单数据的键值对 key/value 的构造方式,可以轻松的将数据通过前端Ajax 方法发送出去
- 将form表单元素的name与value进行组合,实现表单数据的序列化
- 异步上传文件
怎么用?
2.图片上传功能实现
需求:上传图片数目为1张,文件格式限制为jpg和png,图片大小限制为10MB
仔细阅读官方文档,我们可以知道el-upload组件可以设置一些属性,生命周期钩子和事件处理函数。
在文件还没有上传之前,被封装的file对象有如下信息:
我们写一个能够接收前端file对象的接口,尝试一下:
利用postman进行接口测试:
好了,接口大体上做好了,我们终于可以在前端上传图片了
修改前端el-upload的action属性为完整请求地址,特别注意的一点是,修改auto-upload属性为false,因为我们要先提交表单数据,等表单数据写入数据库后再进行文件上传,这样是为了在让图片的保存地址能够有对应的记录可写,这样后面就可以更新商品记录的图片地址了
为了能够找到要更新图片地址的,我们在提交表单的时候将file对象的uid属性(应该是惟一的)也传过去,保存到图片地址中,后面上传图片时方便查找记录,进行替换
成功上传后,我们再打印file对象,发现除了前面没有上传时的属性外,多了一个response对象,如下
这个response封装了我们后台返回的响应消息
好!现在我们需要重写后台的图片上传接口了,随便实现一下访问路径映射,将磁盘地址映射为URL
1.将本地磁盘地址映射为URL进行访问
添加一个继承WebMvcConfigurer 接口的配置类
@Configuration
public class PreReadUploadConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/images/**").addResourceLocations("file:C:\\Users\\HAO\\Desktop\\images\\");
}
}
C:\Users\HAO\Desktop\images\1.png ====> http://localhost:8081/images/1.png
通过URL访问磁盘文件
2.重写接口
public HashMap<String, Object> imageUpload(MultipartFile file, String uid) {
result.clear();
PreReadUploadConfig config = new PreReadUploadConfig();
TProduct product = getOne(new QueryWrapper<TProduct>().eq("proPic", uid));
//文件为空
if (file.isEmpty()) {
result.put("code", "400");
result.put("message", "文件为空");
return result;
}
//没有该uid
if (product == null) {
result.put("code", "400");
result.put("message", "不存在对应记录");
return result;
}
//改文件名
String fileName = file.getOriginalFilename();
fileName = ImageUploadTool.renameToUUID(fileName);
//保存文件到磁盘中
try {
ImageUploadTool.uploadFiles(file, config.getLocalPath(), fileName);
} catch (Exception e) {
e.printStackTrace();
}
String url = "/images/" + fileName;
//把url保存到数据库中
UpdateWrapper<TProduct> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("proPic",uid).set("proPic", url);
update(updateWrapper);
result.put("imageUrl", url);
result.put("code", "200");
result.put("message", "上传成功");
return result;
}
不过file对象中uid好像不是唯一的,明天改一下用别的具有唯一性的标识
参考文章:
ES6基础:变量的解构赋值
vue 箭头函数与function函数的区别