项目难点
涉及到多个关联的数据库
脚手架
在这里我使用的是element-plus框架👉
具体文献参考->element-plus官网
-
运行项目(同时运行前端和后端)
- program/xsxk/vue/package.json
- program/xsxk/springboot/src/main/java/com/example/SpringbootApplication.java
-
在该脚手架中,加入了自定义异常检查 exception
遇到文件夹名称全红解决方案
IDEA中,如果项目目录显示红色,主要是有版本控制所导致的,解决办法就是——解除版本控制。
- 🔺打开 → File->setting->目录映射->VCS->null
一定要注意拼写拼写拼写
批注:formVisible 和 fromVisible
SpringBoot启动失败Application run failed的解决办法
★这个问题得具体问题具体分析,得看下面那些报错什么意思,不能直接去网上找解决办法,查阅好多博主写的文章都没解决,大致出现问题的原因如下:
-
注解问题:
Controller、service层的注解缺失会造成创建bean时出现错误。
@Controller@Service -
依赖包缺失,检查pom配置文件
检查pom.xml文件下是否缺失依赖或者有多余的依赖,判断是否对bean的正常创建有影响。 -
xml包中存在空文件:
在 XML格式声明中的编码伪属性前面必须有空格 -
报错信息:Error parsing Mapper XML. The XML location is ‘file [D:\gitee\self_development\program\xsxk\springboot\target\classes\mapper\StudentMapper.xml]’. Cause: org.apache.ibatis.builder.BuilderException: An invalid property ‘score’ was found in mapping #{collegeId, score = #{score}. Valid properties are javaType,jdbcType,mode,numericScale,resultMap,typeHandler,jdbcTypeName
- An invalid property – 不合法属性
🔺在解决以上问题之后发现仍然不能运行,所以我就采取最原始的办法,将之前运行成功后写的那些文件一一删除,然后重新写一份,排除错误的代码,然后成功解决🎇(泪目)
真的是实在没有办法了,重写了一份,也不知道哪里有改动,反正就是没出错了 :(
- 综上所述:还得是要养成一边写代码一边运行的习惯才行,然后记得备注和检查错别字😭
tableDate 和 tableData 找不同
- 在网页上面显示请求成功,说明已经连接上数据库,但是依旧显示不出教师信息,说明是前端有问题,于是我反过来检查代码,嘿?你猜这么着,拼写错误!😊
⭐嘻嘻,注意不要犯低级错误喔~
405报错
一般是因为请求函数报错,经常是因为请求接口对不上缘故,多检查一下
error: "Method Not Allowed"
path: "/teacher/update"
status: 405
timestamp: "2024-11-05T02:58:22.373+00:00"
- GET / PUT / POST / DELETE
404报错
- 接口UI有问题
图片上传失败
添加教师图片,明明已经显示avatar已经修改完成,但是怎么也上传不到数据库,我刚开始以为可能出错有以下几点:
- 前端没写好,对接不上
- FileController文档
- 接口
⚪然而无论我怎么检查代码完全都没有问题时候,灵光一闪,我教师类的avatar是不是没有写好。
🔺嘻嘻,果不其然,没有写getAvatar函数
- 明明很简答的问题又耽搁很久时间,所以说细心细心再细心,不过能想到教师类的我简直就是天才。日常辛苦我自己了:)
请求错误
- 数据库申请代码报错
Cannot read properties of undefined (reading ‘sex’)
遇到这种报错,基本上是遇到了 xxx.sex,比如form.sex,如果这个xxx(form)是undefined,那么就会出现这样的报错。
点击没反应排查方法
- F12查看网络请求,接口和参数有无问题
- 后台是否报错
- 打断点判断出问题具体环节
user.role,
- 那么如果这个user是个undefined(未被定义)的时候,再去访问这个user里面的某个属性变量的时候,就会报这种错误。
针对管理员和学生无法看到课程信息bug
-
导致teachid可以被三个角色定义,其他角色也调用到teacher的if语句中
-
由于教师数据库没有其他角色信息
-
故查询不到课程
// 分页查询
const load = () => {let teacherId= nullif(data.user.role === 'TEACHER') {teacherId = data.user.id}request.get('/course/selectPage', {params: {pageNum: data.pageNum,pageSize: data.pageSize,name: data.name,teacherId: teacherId //误写成 data.user.id }}).then(res => {data.tableData = res.data?.listdata.total = res.data?.total})
}
遗忘知识点
type="primary"
表示这个按钮是“主要”按钮,通常用来表示主要操作或强调重要功能。例如,在一个表单中,“提交”按钮通常会被设置为主要按钮,以引起用户的注意。
在 Element UI 中,常见的按钮类型还有:
default
: 默认按钮success
: 成功按钮warning
: 警告按钮danger
: 危险按钮info
: 信息按钮
- el-form-item:是Element UI库中用来包裹表单项的组件。在表单里,每个表单项都放在el-form-item里,不仅能让布局更整齐,还能给这些项添加标签和做验证
el-form
就是整个表单,而el-form-item
就是里面的每一个小格子啦。每个el-form-item
都可以有个label
属性来显示标签,比如“用户名”、“密码”这些。然后里面就可以放各种输入框啦,像el-input
、el-select
这些。
- autocomplete=“off” – 用来关闭浏览器的自动填充功能的。
在JavaScript或TypeScript项目中,import
语句用于导入模块。你提到的两种导入方式主要区别在于路径的不同,这会影响代码如何解析和加载相应的模块。
-
绝对路径 vs 相对路径
import request from "@/utils/request";
使用了绝对路径(也称为别名路径)。这种路径通常由构建工具(如Webpack)配置的别名来解析。例如,@/
可能被配置为项目的根目录。import request from "../../utils/request";
使用的是相对路径,从当前文件的位置向上两级目录找到utils/request
模块。
-
依赖解析
- 绝对路径:如果使用绝对路径,你需要确保构建工具已经正确配置了这些路径别名,否则会导致模块找不到的问题。
- 相对路径:相对路径依赖于文件的物理位置,因此在不同的文件结构中可能需要调整路径。
-
可维护性
- 绝对路径:使用绝对路径可以使你的模块导入更加简洁和一致,特别是在大型项目中,可以减少路径深度带来的复杂性。
- 相对路径:相对路径更直观地反映了文件之间的层级关系,但在项目结构调整时可能需要频繁修改。
示例
- **import request from “@/utils/request”;**和
- **import request from “…/…/utils/request”;**的区别
假设项目结构如下:
project-root/
│
├── src/
│ ├── components/
│ │ └── MyComponent.vue
│ ├── utils/
│ │ └── request.js
│
└── webpack.config.js
Webpack配置(webpack.config.js)
const path = require('path');module.exports = {// ...其他配置...resolve: {alias: {'@': path.resolve(__dirname, 'src')}}
};
使用绝对路径
在 MyComponent.vue
中:
import request from '@/utils/request';
使用相对路径
在 MyComponent.vue
中:
import request from '../../utils/request';
总结
选择哪种方式取决于项目需求和团队约定。如果项目使用构建工具并且已经配置了路径别名,那么使用绝对路径会更加方便和一致。如果不使用构建工具或者项目较小,相对路径可能会更直接一些。
- ElMessage.success(‘操作成功’)
这个涉及到的知识点有:
- Element UI框架:
ElMessage.success('操作成功')
是 Element UI 框架中的一个方法,用于显示一个成功的提示信息。在使用该方法前,需要先引入 Element UI 框架。 - 字符串模板语法:如果你想要在
ElMessage.success
中加入变量,可以使用 ES6 的字符串模板语法,例如:const name = "John"; ElMessage.success(
Hello, ${name}!);
。这样,变量name
的值就会被插入到字符串中,输出的结果类似于:Hello, John!
。你也可以使用拼接字符串的方式,例如:const name = "John"; ElMessage.success("Hello, " + name + "!");
。 - 全局重写:对于 Vue.js 3,你可以通过在
main.js
文件中全局重写app.config.globalProperties
来修改ElMessage.success
的行为。 - 组件VNode的生成:无论组件嵌套多深,只要在 Vue.component 中定义全局组件,这些构造函数都会被添加到组件的原型链上。生成的文本和 my-button 组件的 VNode 会一起作为最终 #app VNode 的组成部分。
- Scope(作用域)和组件间通信:通过 scope 标签和自定义事件传递数据,推荐使用全局事件总线进行组件间的复杂通信。
- 组件定义位置:全局组件的定义应放在 Vue 实例创建之前,因为 Vue 实例在初始化时需要先知道所有的组件信息才能正确挂载。
- 确认操作:在用户执行一些重要的操作时,为了防止误操作,可以使用弹窗组件来进行二次确认。
- placeholder
它就是input和textarea标签的一个属性,用来在文本框内啥都没输入的时候显示灰色的提示文字。这样用户就知道该填啥啦!不过啊,placeholder属性还没被CSS标准收进去哦。不同浏览器得用不同的伪元素来改它的样式
- 比如Chrome、Edge这些就用 ::webkit-input-placeholder
- Firefox用的是 ::-moz-placeholder。
- @RequestParam和@RequestBody
public Result selectPage(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "5") Integer pageSize) {
这段代码是一个Java方法的声明,通常用于Spring框架中的控制器类(Controller)。这个方法名为selectPage
,它接受两个参数:pageNum
和pageSize
,并返回一个Result
对象。
知识点解释
-
Spring MVC:
- Spring MVC是Spring框架的一部分,用于构建Web应用程序。它使用控制器来处理HTTP请求,并将请求映射到相应的处理方法上。
-
@RequestParam:
@RequestParam
注解用于将HTTP请求参数绑定到控制器方法的参数上。defaultValue
属性指定了当请求中没有提供相应参数时使用的默认值。例如,如果请求中没有提供pageNum
参数,那么它的默认值将是1;如果没有提供pageSize
参数,那么它的默认值将是5。
-
分页查询:
- 分页查询是一种常见的数据库操作,用于在大量数据中分批获取数据。
pageNum
表示当前页码,pageSize
表示每页显示的数据条数。
- 分页查询是一种常见的数据库操作,用于在大量数据中分批获取数据。
-
Result:
Result
是一个自定义的返回类型,通常用于封装API的响应结果。它可以包含状态码、消息以及实际的数据内容。
@RequestParam 和 @RequestBody 的区别
-
@RequestParam:
- 用于从URL请求参数中获取数据。
- 适用于GET请求或POST请求中的表单数据。
- 示例:
@GetMapping("/example") public String example(@RequestParam String name) {return "Hello, " + name; }
-
@RequestBody:
- 用于从HTTP请求体中获取数据,通常用于POST请求。
- 适用于接收JSON、XML等格式的数据,并将其转换为Java对象。
- 示例:
@PostMapping("/example") public String example(@RequestBody User user) {return "User created: " + user.getName(); }
总结
这段代码定义了一个分页查询的方法,通过@RequestParam
注解从请求中获取分页参数,并返回一个封装了查询结果的Result
对象。@RequestParam
和@RequestBody
的主要区别在于它们获取数据的方式不同,前者从URL参数中获取数据,后者从请求体中获取数据。
- < el-table-column label=“职称” prop=“title”>< /el-table-column>中的prop是什么意思
在 Vue.js 框架中,el-table-column
是 Element UI 库中的一个组件,用于定义表格的列。prop
属性在这个上下文中表示该列对应的数据对象中的字段名。
具体来说,当你使用 el-table-column
时,你通常会将一个数组的数据传递给 el-table
组件,这个数组中的每个对象代表一行数据。prop
属性的值就是这些对象中的属性名,它告诉 el-table-column
应该从每行数据对象中提取哪个属性来显示在表格的这一列中。
例如:
<el-table :data="tableData"><el-table-column label="姓名" prop="name"></el-table-column><el-table-column label="年龄" prop="age"></el-table-column><el-table-column label="职称" prop="title"></el-table-column>
</el-table>
假设 tableData
是这样的:
[{ name: '张三', age: 25, title: '工程师' },{ name: '李四', age: 30, title: '经理' }
]
那么,el-table-column
的 label
属性会显示为 “职称”,而 prop
属性会告诉表格从每个对象中提取 title
属性的值来填充这一列。因此,表格中第三列会显示 “工程师” 和 “经理”。
- data.form = JSON.parse(JSON.stringify(row))
这个代码片段是JavaScript中的一种深拷贝操作,涉及的知识点包括JSON对象、字符串和JavaScript对象的转换。具体来说,它使用了JSON.parse()
和JSON.stringify()
两个方法来实现对象的深拷贝。
详细解释:
-
JSON.stringify(row):
JSON.stringify()
是一个JavaScript内置的方法,用于将JavaScript对象转换为一个JSON格式的字符串。- 在这个例子中,它将变量
row
(假设它是一个对象)转换为一个JSON字符串。
-
JSON.parse(…):
JSON.parse()
是另一个JavaScript内置的方法,用于将JSON格式的字符串解析成JavaScript对象。- 这里,它将之前通过
JSON.stringify(row)
得到的JSON字符串重新解析回一个新的JavaScript对象。
整体作用:
data.form = JSON.parse(JSON.stringify(row))
这行代码的作用是将row
对象进行深拷贝,并将结果赋值给data.form
。深拷贝意味着新的对象与原对象之间没有引用关系,修改新对象不会影响到原对象。
涉及的知识点:
- JSON (JavaScript Object Notation): 一种轻量级的数据交换格式。
- JSON.stringify(): 将JavaScript对象转换为JSON字符串。
- JSON.parse(): 将JSON字符串转换为JavaScript对象。
- 深拷贝 vs 浅拷贝:
- 浅拷贝: 只复制对象的引用,不复制对象的内容。
- 深拷贝: 完全复制对象及其子对象的内容,使得新旧对象之间互不影响。
示例代码:
let row = {name: "Alice",age: 30,address: {city: "Wonderland",zipCode: "12345"}
};let data = {};
data.form = JSON.parse(JSON.stringify(row));console.log(data.form); // 输出:{ name: "Alice", age: 30, address: { city: "Wonderland", zipCode: "12345" } }
在这个例子中,data.form
是row
的一个深拷贝,对data.form
的任何修改都不会影响到row
。