源码:https://gitee.com/xqnode/pure-design/tree/master
学习视频:https://www.bilibili.com/video/BV1U44y1W77D
开始讲解
个人信息的下拉菜单:
<el-dropdown style="width: 150px; cursor: pointer; text-align: right">
<div style="display: inline-block">
<img :src="user.avatarUrl" alt=""
style="width: 30px; border-radius: 50%; position: relative; top: 10px; right: 5px">
<span>{{ user.nickname }}</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i>
</div>
<el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<router-link to="/password">修改密码</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<router-link to="/person">个人信息</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<span style="text-decoration: none" @click="logout">退出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
路由设置(静态)
const manageRoute = { path: '/', name: 'Manage', component: () => import('../views/Manage.vue'), redirect: "/home", children: [
{ path: 'person', name: '个人信息', component: () => import('../views/Person.vue')},
{ path: 'password', name: '修改密码', component: () => import('../views/Password.vue')},
] }
新建 Person.vue页面
<template>
<div>
<el-card style="width: 600px">
<el-form label-width="80px" size="small">
<div style="text-align: center; margin: 10px 0">
<el-upload
class="avatar-uploader"
action="http://localhost:9090/file/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<img v-if="form.avatarUrl" :src="form.avatarUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
<el-form-item label="用户名">
<el-input v-model="form.username" autocomplete="off" disabled></el-input>
</el-form-item>
<el-form-item label="昵称">
<el-input v-model="form.nickname" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="form.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="电话">
<el-input v-model="form.phone" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="地址">
<el-input v-model="form.address" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div style="text-align: center">
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-card>
</div>
</template>
然后再写请求接口的JS:
<script>
export default {
name: 'Person',
data() {
return {
form: {},
user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
}
},
created() {
this.load()
},
methods: {
load() {
const username = this.user.username
if (!username) {
this.$message.error("当前无法获取用户信息!")
return
}
this.request.get("/user/username/" + username).then(res => {
this.form = res.data
})
},
save() {
this.request.post("/user", this.form).then(res => {
if (res.code === '200') {
this.$message.success("保存成功")
this.dialogFormVisible = false
this.load()
this.$emit('refreshUser')
} else {
this.$message.error("保存失败")
}
})
},
handleAvatarSuccess(res) {
// res就是文件的路径
this.form.avatarUrl = res
}
}
}
</script>
我要求你去检查你的请求接口,这样可以防止404的错误!
Manage.vue需要做的改动:
// 传入 user对象到 Header组件里面
<Header :collapseBtnClass="collapseBtnClass" @asideCollapse="collapse" :user="user" />
data() {
return {
user: {}
}
}
created() {
// 从后台获取最新的User数据
this.getUser()
},
// 在methos里面写一个函数, 获取用户的最新数据
getUser() {
let username = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")).username : ""
if (username) {
// 从后台获取User数据
this.request.get("/user/username/" + username).then(res => {
// 重新赋值后台的最新User数据
this.user = res.data
})
}
}
Header.vue需要做的改动
// 定义一个user属性接受从Manage.vue传进来的user对象
props: {
user: Object
},
// 然后在Header的这个地方使用:
<el-dropdown style="width: 150px; cursor: pointer; text-align: right">
<div style="display: inline-block">
<img :src="user.avatarUrl" alt=""
style="width: 30px; border-radius: 50%; position: relative; top: 10px; right: 5px">
<span>{{ user.nickname }}</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i>
</div>
<el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<router-link to="/password">修改密码</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<router-link to="/person">个人信息</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<span style="text-decoration: none" @click="logout">退出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
最后一步,在Person.vue里面写触发方法:
this.$emit('refreshUser')
然后在 Manage里面做相应的修改即可:
<router-view @refreshUser="getUser" />
修改密码:
<template>
<el-card style="width: 500px;">
<el-form label-width="120px" size="small" :model="form" :rules="rules" ref="pass">
<el-form-item label="原密码" prop="password">
<el-input v-model="form.password" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="form.newPassword" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item label="确认新密码" prop="confirmPassword">
<el-input v-model="form.confirmPassword" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save">确 定</el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<script>
export default {
name: "Password",
data() {
return {
form: {}, // username, password, newPassword, confirmNewPassword 这4个属性
user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
rules: {
password: [
{ required: true, message: '请输入原密码', trigger: 'blur' },
{ min: 3, message: '长度不少于3位', trigger: 'blur' }
],
newPassword: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 3, message: '长度不少于3位', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 3, message: '长度不少于3位', trigger: 'blur' }
],
}
}
},
created() {
this.form.username = this.user.username
},
methods: {
save() {
this.$refs.pass.validate((valid) => {
if (valid) { //合法
if (this.form.newPassword !== this.form.confirmPassword) {
this.$message.error("2次输入的新密码不相同")
return false
}
this.request.post("/user/password", this.form).then(res => {
if (res.code === '200') {
this.$message.success("修改成功")
this.$store.commit("logout")
} else {
this.$message.error(res.msg)
}
})
}
})
},
}
}
</script>
<style>
.avatar-uploader {
text-align: center;
padding-bottom: 10px;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 138px;
height: 138px;
line-height: 138px;
text-align: center;
}
.avatar {
width: 138px;
height: 138px;
display: block;
}
</style>
后台:
import lombok.Data;
@Data
public class UserPasswordDTO {
private String username;
private String phone;
private String password;
private String newPassword;
}
Controller接口
@PostMapping("/password") // /user/password
public Result password(@RequestBody UserPasswordDTO userPasswordDTO) {
userService.updatePassword(userPasswordDTO);
return Result.success();
}
业务类UserServiceImpl.java:
@Override
public void updatePassword(UserPasswordDTO userPasswordDTO) {
int update = userMapper.updatePassword(userPasswordDTO);
if (update < 1) {
throw new ServiceException(Constants.CODE_600, "密码错误");
}
}
数据Mapper层:
@Update("update sys_user set password = #{newPassword} where username = #{username} and password = #{password}")
int updatePassword(UserPasswordDTO userPasswordDTO);
好的,至此 个人中心、修改头像、数据联动、修改密码四个内容集成完毕!撒花~