methods: {
sendEmail() {
this.$axios.post('/mail/send', { toEmail: this.email })
.then(response => {
this.$message.success('邮件发送成功')
})
.catch(error => {
this.$message.error('邮件发送失败: ' + error.message)
})
},
}
没有界面的在Methods:里面配置
有界面的在router里面配置。
修改前端的时候首先要注意更改后,方法能否获取到entity对应字段
entity分情况和数据库保持一致,尽量只写好方法在有用的字段之后获取
public void updateById(Info info) {
if (ObjectUtil.isNotEmpty(info.getStatus()) && StatusEnum.CHECK_OK.status.equals(info.getStatus())) {
//加锁,防止code相同
synchronized (this) {
// 给该教员一个教员编号
if (ObjectUtil.isEmpty(info.getCode())) {
info.setCode(DateUtil.format(new Date(), "yyyyMMddHHmmss"));
}
}
}
infoMapper.updateById(info);
}
synchronized
)的作用解释在这段代码中,synchronized (this)
的作用是 防止多线程并发时生成重复的 code
。具体分析如下:
业务场景:当多个线程同时调用 updateById()
方法时,可能会同时进入 if (ObjectUtil.isEmpty(info.getCode()))
条件,导致多个线程同时执行 info.setCode(...)
,从而生成相同的 code
。
问题:DateUtil.format(new Date(), "yyyyMMddHHmmss")
是基于当前时间的,如果在 同一毫秒 内多个线程同时调用,可能会生成相同的 code
(因为 SimpleDateFormat
不是线程安全的)。
加锁目的:确保同一时间只有一个线程能执行 info.setCode(...)
,避免 code
重复。
synchronized (this)
表示 当前对象实例(this
)作为锁,即:
如果多个线程调用 同一个 teacher
实例 的 updateById()
方法,会互斥执行同步块。
但如果多个线程操作 不同的 teacher
实例,锁不会生效(因为锁对象不同)。
锁粒度:仅锁住 code
生成的代码块,不影响 infoMapper.updateById(info)
的并发执行。
Form 中的 get 和 post 方法,在数据传输过程中分别对应了 HTTP 协议中的 GET 和 POST 方法。二者主要区别如下:
使用 Post 传输的数据,可以通过设置编码的方式正确转化中文;而 Get 传输的数据却没有变化。在以后的程序中,我们一定要注意这一点。(来自博客园 风哥2019-03-07)
Vue 2 和 Vue 3 的核心区别主要体现在架构设计、性能优化和开发体验上。以下是详细对比,涵盖语法、原理和工程实践:
特性 | Vue 2 | Vue 3 |
---|---|---|
响应式系统 | Object.defineProperty |
Proxy |
虚拟DOM | 全量Diff | 静态标记(PatchFlag) |
代码组织 | Options API | Composition API + Options API |
源码结构 | Monolithic(单体) | 模块化(Tree-shakable) |
javascript
复制
下载
// 基于Object.defineProperty Object.defineProperty(data, 'key', { get() { /* 依赖收集 */ }, set() { /* 触发更新 */ } })
缺陷:
无法检测对象新增/删除属性(需用Vue.set
/Vue.delete
)
数组变异方法需要重写(如push
, pop
)
javascript
new Proxy(data, { get(target, key) { /* 依赖收集 */ }, set(target, key, value) { /* 触发更新 */ } })
优势:
直接监听对象/数组的所有操作
支持Map/Set等新数据类型
javascript
export default { data() { return { count: 0 } }, methods: { increment() { this.count++ } }, mounted() { console.log('mounted') } }
痛点:逻辑关注点分散(如相同功能的代码分散在data/methods中)
javascript
import { ref, onMounted } from 'vue' export default { setup() { const count = ref(0) const increment = () => count.value++ onMounted(() => console.log('mounted')) return { count, increment } } }
优势:
逻辑复用(自定义Hook)
更好的TypeScript支持
优化点 | Vue 2 | Vue 3 |
---|---|---|
打包体积 | 完整版约22KB | 按需引入(核心约10KB) |
编译时优化 | 无 | 静态提升、区块树 |
更新性能 | 全组件树Diff | 动态节点标记(快3倍) |
工具库 | Vue 2 支持 | Vue 3 支持 |
---|---|---|
Vue Router | v3.x | v4.x |
Vuex | v3.x | v4.x / 推荐Pinia |
Element UI | ✔️ | Element Plus |
场景 | 推荐版本 | 原因 |
---|---|---|
新项目 | Vue 3 + Vite | 更好的性能、TS支持和未来生态 |
老项目维护 | Vue 2 | 避免重构风险 |
需要IE11支持 | Vue 2 | Vue 3 不兼容IE11 |
javascript
// useCounter.js (可复用的Hook) import { ref } from 'vue' export function useCounter() { const count = ref(0) const increment = () => count.value++ return { count, increment } } // 组件中使用 import { useCounter } from './useCounter' export default { setup() { return { ...useCounter() } } }