一个职场小白,增删改查都写不明白,去公司好多都看不懂,老师可能教过,但自己不写就不明白其中的乐趣,要做一个文件上传,我们以图片上传为列,首先一个前后台交互的问题,第一步一定要有自己的前端,前端怎样与后台交互,后台怎样控制,最后操作数据库,怎样写sql语句。
1先画一个页面 一个页面有三个部分
<template></template>放前端我们能看到的所有东西,大部分数据和按钮,好不好看就看个人的前端水平,
<script></script>导入资源一些前端要用的依赖,自定义用来接收后台数据的变量数组什么的主要有import 导入一些依赖,js写的一些方法,之前在公司写的项目用JS实现前后台交互的 在JS写好与后台交互的方法通过import在页面导入这些方法
<script>
import Pagination from "../../components/pagination";
import File from "../../components/file.vue";
export default
{
component:{Pagination,File},
name: 'business-teacher',
components: {Pagination,File},
data:function(){
return{
teacher:{},/*映射表单数据*/
teachers:[]
}
},
data: function () {
return {
course: {},/*映射表单数据*/
courses: [],
COURSE_LEVEL: COURSE_LEVEL,
COURSE_CHARGE: COURSE_CHARGE,
COURSE_STATUS: COURSE_STATUS,
categorys: [],
tree: {},
savaContentLabel:"",/*内容v保存时生成的变量,用来记录自动保存的时间*/
sort: {
id: "",
oldSort: 0,
newSort: 0
},/*用来更新排序*/
teachers:[],/*接收所有的老师*/
}
},
data: function () {}用来定义一些我们用来存放数据的集合,数组,全局变量,
mounted: function () {}用来执行页面初始化要执行的方法,比如数据的查询操作,
methods:{}自定义一些方法页面调用,在我最近学的项目中,在这些方法中会会用ajax请求后台contrller层的方法, <style scoped></style scoped>,定义一些标签的共有的属性 如字体大小,颜色等
<template>
<div>
<!--hidden隐藏 input class="hidden"-->
<input ref="file" type="file" v-on:change="uploadFile()" v-bind:id="inputId+'-input'">
</div>
</template>
定义一个div 容器 用input自带的文件上传type="file"默认是text 定义一个change事件点击的时候会触发uploadFile()方法,在mounted: function () {}定义一个uploadFile()方法
/*
* 文件上传方法
* */
uploadFile(){
let _this=this;
let formData=new window.FormData;
console.log("开始判断文件格式")
// let file=_this.$refs.file.files[0];取得控件上传的数据
let file=_this.$refs.file.files[0];
console.log("开始判断文件格式2")
//判断文件格式
//let suffixs=["jpg","jpeg","png"];
let suffixs=_this.suffixs;
let fileName=file.name;
let suffix=fileName.substring(fileName.lastIndexOf(".")+1,fileName.length).toLowerCase();
let validateSuffix=false;
for(let i=0;i<suffixs.length;i++){
if(suffixs[i].toLowerCase()===suffix) {
validateSuffix = true;
break;
}
}
if(!validateSuffix){
toast.warning("文件格式不正确!只支持上传:"+suffixs.join(","));
//每次上传完都要清空,解决重复上传同样的文件时不触发上场的方法
$("#" + _this.inputId + "-input").val("");
return;
}
console.log("开始上传")
//key:"file"必须和后端controller参数名一致
/*formData.append('file',document.querySelector('#file-upload-input').files[0]);*/
formData.append('file',file);
_this.$ajax.post('http://localhost:9000/file/admin/upload',formData)
.then((response)=>{
let resp = response.data;
console.log("文件上传成功===",resp)
_this.afterUpload(resp);
//每次上传完都要清空,解决重复上传同样的文件时不触发上场的方法
$("#" + _this.inputId + "-input").val("");
/* console.log("头像上传的路径===",response)
_this.teacher.image=image;*/
});
console.log("结束上传")
},
开始的时候使用的是formData.append('file',document.querySelector('#file-upload-input').files[0]);根据id获取要上传的文件
后来是用ref="file"定义一个别名,根据别名来获取上传的文件
主要是通过_this.$ajax.post('http://localhost:9000/file/admin/upload',formData)请求后台contrller层的方法,
/**
* @author admin
* @version 1.0.0
* @ClassName TestController.java
* @Description TODO
* @createTime 2022年01月22日 21:11:00
*/
@RequestMapping("/admin")
@RestController
public class UploadController {
@RequestMapping("/upload")
public ResponseDto upload(@RequestParam MultipartFile file) throws IOException {
//保存文件到本地
String fileName=file.getOriginalFilename();
String key= UuidUtil.getShortUuid();//自己生成的八位id
String fullPath="D:/2022/course1/image/"+key+"-"+fileName;//本地路径
File dest=new File(fullPath);//目标路径
file.transferTo(dest);
ResponseDto responseDto = new ResponseDto();
responseDto.setContent("http://localhost:9000/file/f/"+key+"-"+fileName);
return responseDto;
}
}
无论怎们样看的时候只要前端能访问到后台就行,这样我们一个完整的文件上传的功能就结束了,做一些 优化最终的效果
很多地方都会用到文件上传的功能怎样给他做成一个公共组件呢,公共组件怎样使用呢,总体就是把变化的部分做成公共组件的属性,让使用者能在公共组件自由定义,
export default { name: 'file',//标签名,自定义组件的名称 props: {//在这里定义,自定义组件的属性,就是使用者能自由定义的部分,能定义一些方法 /*标签要暴露的属性*/ text:{ default: "文件上传" }, /*回调函数*/ afterUpload: { type: Function, default: null }, } }
最终代码效果
<template>
<div>
<button type="button" v-on:click="selectFile()" class="btn btn-white btn-default btn-round">
<i class="ace-icon fa fa-upload"></i>
{{text}}
</button>
<!--hidden隐藏 input-->
<input class="hidden" ref="file" type="file" v-on:change="uploadFile()" v-bind:id="inputId+'-input'">
</div>
</template>
<script>
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'file',//标签名
props: {
/*标签要暴露的属性*/
text:{
default: "文件上传"
},
inputId:{
default: "file-upload"
},
suffixs:{
default: []
},
/*回调函数*/
afterUpload: {
type: Function,
default: null
},
},
data: function () {
return {
}
},
methods: {
/*
* 文件上传方法
* */
uploadFile(){
let _this=this;
let formData=new window.FormData;
console.log("开始判断文件格式")
// let file=_this.$refs.file.files[0];取得控件上传的数据
let file=_this.$refs.file.files[0];
console.log("开始判断文件格式2")
//判断文件格式
//let suffixs=["jpg","jpeg","png"];
let suffixs=_this.suffixs;
let fileName=file.name;
let suffix=fileName.substring(fileName.lastIndexOf(".")+1,fileName.length).toLowerCase();
let validateSuffix=false;
for(let i=0;i<suffixs.length;i++){
if(suffixs[i].toLowerCase()===suffix) {
validateSuffix = true;
break;
}
}
if(!validateSuffix){
toast.warning("文件格式不正确!只支持上传:"+suffixs.join(","));
//每次上传完都要清空,解决重复上传同样的文件时不触发上场的方法
$("#" + _this.inputId + "-input").val("");
return;
}
console.log("开始上传")
//key:"file"必须和后端controller参数名一致
/*formData.append('file',document.querySelector('#file-upload-input').files[0]);*/
formData.append('file',file);
_this.$ajax.post('http://localhost:9000/file/admin/upload',formData)
.then((response)=>{
let resp = response.data;
console.log("文件上传成功===",resp)
_this.afterUpload(resp);
//每次上传完都要清空,解决重复上传同样的文件时不触发上场的方法
$("#" + _this.inputId + "-input").val("");
/* console.log("头像上传的路径===",response)
_this.teacher.image=image;*/
});
console.log("结束上传")
},
/*
* 用一个按钮控制文件上传,触发文件上传方法根据id 触发一次点击事件
*
* */
selectFile(){
let _this = this;
$("#" + _this.inputId + "-input").trigger("click");
},
}
}
</script>
那要怎么使用呢,在我们需要使用文件上传功能的页面,先导入我们的公共组件
import File from "../../components/file.vue";
export default
{
component:{File},
components: {File},
}
在需要实现上传功能的位置使用自定义标签,标签名和 自定义属性的name一致
最终实现效果
v-bind:后面接自己定义的属性,我不知道为什么,就查查百度,真记不住那么多
1.插值操作主要作用 :将Vue实例中的数据插入到我们模板的内容当中,并改变data可以动态改变显示。 2.动态绑定属性 :除了内容需要动态来决定外,元素的某些属性我们也希望动态来绑定。 比如,动态绑定a元素的href属性、动态绑定img元素的src属性。 Mustache双括号语法,只能在内容插值里使用,属性值是不可以用的 <img src="{{imgURL}}">、<img src="imgURL">是错误的, vue不会解析将data值放里面去;会被当做字符,而不是变量; 3.动态绑定属性则使用v-bind指令: 作用:动态绑定属性 缩写:: 在前面加上v-bind后,就表明将该属性的属性值当成一个变量 vue会对它解析,将解析到的变量 赋予data属性中对应的值。 一般图片的img中src属性值都是不固定的,像轮播图等 src属性值:可以是服务器端请求过来的 服务器端请求过来的值放在vue实例的data中,然后将data中的属性赋给src属性值来使用 则响应式:修改data中的属性也可以实时响应,动态变化; ———————————————— 版权声明:本文为CSDN博主「卡布达。」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_45700583/article/details/108968570
最终实现效果是
就可以在多个地方复用了。