实现个人中心和修改密码
个人中心
基础搭建页面
添加点击事件
1
| <el-dropdown-item @click="router.push('/manager/person')">个人信息</el-dropdown-item>
|
新建一个Person.vue
1 2 3 4 5 6 7 8 9 10
| <template> <div> 个人中心 </div> </template>
<script setup>
</script>
|
路由:
1 2 3 4 5 6 7 8 9 10
| routes: [ {path: '/',redirect: '/manager/home'}, {path: '/manager', component:() =>import('../views/Manager.vue'), children: [ {path: 'home',meta:{name:'主页'}, component:() =>import('../views/Home.vue'),}, {path: 'admin',meta:{name:'管理员信息'}, component:() =>import('../views/Admin.vue'),}, {path: 'user',meta:{name:'普通用户信息'}, component:() =>import('../views/User.vue'),}, {path: 'person',meta:{name:'个人信息'}, component:() =>import('../views/Person.vue'),}, ] ...
|

接下来我们来做这个页面:
我们直接复制User.vue中的表单
遇到问题:
Cannot read properties of undefined (reading ‘username’)

搜索一下: xxx.username 然后xxx是一个undefined 或者null 就能排查这个问题了,因为复制过来的时候没有改form为user
改完即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <template> <div class="card" style="width: 50%;"> <div>个人中心</div>
<el-form ref="formRef" :model="data.user" label-width="80px" style="padding: 20px 30px 10px 0"> <el-form-item prop="username" label="账号"> <el-input v-model="data.user.username" autocomplete="off" placeholder="请输入账号"/> </el-form-item>
<el-form-item prop="name" label="名称"> <el-input v-model="data.user.name" autocomplete="off" placeholder="请输入名称"/> </el-form-item>
<el-form-item prop="name" label="电话"> <el-input v-model="data.user.phone" autocomplete="off" placeholder="请输入电话"/> </el-form-item>
<el-form-item prop="name" label="邮箱" placeholder="请输入邮箱"> <el-input v-model="data.user.email" autocomplete="off" /> </el-form-item>
<el-form-item prop="avatar" label="头像" > <el-upload action="http://localhost:9999/files/upload" :headers="{ token: data.user.token }" :on-success="handleFileSuccess" list-type="picture" > <el-button type="primary">上传头像</el-button> </el-upload> </el-form-item> </el-form>
<div style="text-align: center;"> <el-button type="primary" style="padding: 18px 35px" @click="update"> 保存 </el-button> </div> </div> </template>
<script setup> import {reactive} from "vue"; import request from "@/utils/request.js"; import {ElMessage} from "element-plus";
const data = reactive({ user: JSON.parse(localStorage.getItem("code2025_user") || '{}'),
})
const handleFileSuccess = (res) => { data.user.avatar = res.data }
const update = () => { let url; if(data.user.role === 'ADMIN'){ url = '/admin/update' } else if(data.user.role === 'USER'){ url = '/user/update' } request.put(url,data.user).then(res => { if(res.code === '200') { ElMessage.success('更新成功!') //更新localstorage localStorage.setItem("code2025_user",JSON.stringify(data.user)) //转成字符串存进去 } }) }
</script>
|
这样写完后的效果是这样: 
问题是每次保存完 我们上面的头像和名字不会立即更改,那是因为顶部是属于Manager.vue的
解决方法: 设计到数据的传递
Person.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const emit = defineEmits(['updateUser'])
const update = () => { let url; if(data.user.role === 'ADMIN'){ url = '/admin/update' } else if(data.user.role === 'USER'){ url = '/user/update' } request.put(url,data.user).then(res => { if(res.code === '200') { ElMessage.success('更新成功!') localStorage.setItem("code2025_user",JSON.stringify(data.user)) emit('updateUser') } }) }
|
Manager.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ... <!-- 菜单区域结束 -->
<!-- 数据渲染区域开始 --> <div style="flex: 1;width: 0; padding: 10px; background-color: #faf4fa"> <RouterView @updateUser="updateUser"/> </div> <!-- 数据渲染区域结束 --> </div> <!-- 下方区域结束 --> </div> </template>
<script setup> import router from "@/router/index.js"; import {reactive} from "vue"
const data = reactive({ user: JSON.parse(localStorage.getItem('code2025_user') || "{}") })
const updateUser = () => { data.user = JSON.parse(localStorage.getItem("code2025_user") || '{}') } ...
|
修改密码
基础搭建页面
manager.vue
1 2
| <el-dropdown-item @click="router.push('/manager/updatePassword')">修改密码</el-dropdown-item>
|
updatePassword.vue
1 2 3 4 5 6 7 8 9
| <template> <div>
</div> </template>
<script setup>
</script>
|
路由
1 2 3 4 5 6 7 8 9
| {path: '/manager', component:() =>import('../views/Manager.vue'), children: [ {path: 'home',meta:{name:'主页'}, component:() =>import('../views/Home.vue'),}, {path: 'admin',meta:{name:'管理员信息'}, component:() =>import('../views/Admin.vue'),}, {path: 'user',meta:{name:'普通用户信息'}, component:() =>import('../views/User.vue'),}, {path: 'person',meta:{name:'个人信息'}, component:() =>import('../views/Person.vue'),}, {path: 'updatePassword',meta:{name:'修改密码'}, component:() =>import('../views/updatePassword.vue'),}, ] },
|
Debug发现前端没有传递过来


点击页面没有反应怎么办?
1.打开f12看看前端控制台有没有报错,有报错就看一下,没有就下一步
2.确定一下有没有调用到后端接口 (打断点) ,如果没有走到那就排查一下接口,如果走到了,跟着断点跟到逻辑哪里看看是不是正确的走向.
3.再打开f12,看看该接口返回的数据
定位发现:

所以我们知道就是前端的问题,因为我们前端没有对返回500 做处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| <template> <div class="card" style="width: 50%"> <div style="font-size: 16px;">修改密码</div> <el-form ref="formRef" :rules="data.rules" :model="data.user" label-width="80px" style="padding: 20px 30px 10px 0;"> <el-form-item prop="password" label="原密码"> <el-input size="large" show-password v-model="data.user.password" auto-complete="off" prefix-icon="Lock" placeholder="请输入密码"> </el-input> </el-form-item>
<el-form-item prop="newPassword" label="新密码"> <el-input size="large" show-password v-model="data.user.newPassword" auto-complete="off" prefix-icon="Lock" placeholder="请输入密码"> </el-input> </el-form-item>
<el-form-item prop="new2Password" label="确认密码"> <el-input size="large" show-password v-model="data.user.new2Password" auto-complete="off" prefix-icon="Lock" placeholder="请输入密码"> </el-input> </el-form-item> </el-form>
<div style="text-align: center;"> <el-button type="primary" style="padding: 20px 30px;" @click="updatePassword">保存</el-button> </div> </div> </template>
<script setup>
import {reactive,ref} from "vue"; import request from "@/utils/request.js"; import {ElMessage} from "element-plus";
const data = reactive({ user: JSON.parse(localStorage.getItem("code2025_user") || '{}'), rules: { password: [ { required: true, message: '请输入原密码', trigger: 'blur' } ], newPassword: [ {required: true,message: '请填写新密码',trigger: 'blur'} ], new2Password: [ {required: true,message: '请确认新密码',trigger: 'blur'} ],
// newPassword: [ // { required: true, message: '请填写新密码', trigger: 'blur' }, // { min: 8, message: '密码至少8位', trigger: 'blur' }, // { pattern: /^(?=.*[A-Za-z])(?=.*\d).+$/, // message: '需包含字母和数字', // trigger: 'blur' // } // ] }
})
const formRef = ref()
const updatePassword = () => { formRef.value.validate(valid => { if (valid) { request.post('/updatePassword', data.user) .then(res => { try { if (res.code === '200') { ElMessage.success('修改成功'); setInterval(()=>{ localStorage.removeItem('code2025_user'); location.href = '/login'; },500)
} else { ElMessage.error(res.msg); } } catch (error) { console.error(error); ElMessage.error('请求失败'); } }) .catch(error => { console.error(error); ElMessage.error('请求失败'); }); } }); }; </script>
|
SpringBoot3 +vue3 实现个人中心和修改密码