1.1 用户信息需要在多个链接使用,所以需要用pinia持久化
1.1.1 定义store
import {defineStore} from 'pinia'
import {ref} from 'vue'
const useUserInfoStore = defineStore('userInfo',()=>{
//定义状态相关的内容
const info = ref({})
const setInfo = (newInfo)=>{
info.value = newInfo
}
const removeInfo = ()=>{
info.value = {}
}
return {info,setInfo,removeInfo}
},{persist:true})
export default useUserInfoStore;
1.1.2 接口函数
import {userInfoService} from '@/api/user.js'
import useUserInfoStore from '@/stores/userInfo.js'
import {useTokenStore} from '@/stores/token.js'
const tokenStore = useTokenStore();
const userInfoStore = useUserInfoStore();
//调用函数,获取用户详细信息
const getUserInfo = async()=>{
//调用接口
let result = await userInfoService();
//数据存储到pinia中
userInfoStore.setInfo(result.data);
}
getUserInfo();
1.1.3 layout.vue中调用接口显示昵称和头像
1.2 下拉菜单
1.2.1 绑定事件
1.2.2 编写函数
//条目被点击后,调用的函数
import {useRouter} from 'vue-router'
const router = useRouter();
import {ElMessage,ElMessageBox} from 'element-plus'
const handleCommand = (command)=>{
//判断指令
if(command === 'logout'){
//退出登录
ElMessageBox.confirm(
'您确认要退出吗?',
'温馨提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
//退出登录
//1.清空pinia中存储的token以及个人信息
tokenStore.removeToken()
userInfoStore.removeInfo()
//2.跳转到登录页面
router.push('/login')
ElMessage({
type: 'success',
message: '退出登录成功',
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '用户取消了退出登录',
})
})
}else{
//路由
router.push('/user/'+command)
}
}
1.3 基本资料的修改
1.3.1 定义接口
1.3.2 页面搭建
1.3.3 数据回显
1.3.4 调用接口
<script setup>
import { ref } from 'vue'
import useUserInfoStore from '@/stores/userInfo.js'
const userInfoStore = useUserInfoStore();
const userInfo = ref({...userInfoStore.info})
const rules = {
nickname: [
{ required: true, message: '请输入用户昵称', trigger: 'blur' },
{
pattern: /^\S{2,10}$/,
message: '昵称必须是2-10位的非空字符串',
trigger: 'blur'
}
],
email: [
{ required: true, message: '请输入用户邮箱', trigger: 'blur' },
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
]
}
//修改个人信息
import {userInfoUpdateService} from '@/api/user.js'
import {ElMessage} from 'element-plus'
const updateUserInfo = async ()=>{
//调用接口
let result = await userInfoUpdateService(userInfo.value);
ElMessage.success(result.msg? result.msg : '修改成功');
//修改pinia中的个人信息
userInfoStore.setInfo(userInfo.value)
}
</script>
<template>
<el-card class="page-container">
<template #header>
<div class="header">
<span>基本资料</span>
</div>
</template>
<el-row>
<el-col :span="12">
<el-form :model="userInfo" :rules="rules" label-width="100px" size="large">
<el-form-item label="登录名称">
<el-input v-model="userInfo.username" disabled></el-input>
</el-form-item>
<el-form-item label="用户昵称" prop="nickname">
<el-input v-model="userInfo.nickname"></el-input>
</el-form-item>
<el-form-item label="用户邮箱" prop="email">
<el-input v-model="userInfo.email"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateUserInfo">提交修改</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</el-card>
</template>
1.4修改头像
1.4.1 编辑页面
1.4.2 回显头像
1.4.3 图片上传
<script setup>
import { Plus, Upload } from '@element-plus/icons-vue'
import {ref} from 'vue'
// import avatar from '@/assets/default.png'
const uploadRef = ref()
import {useTokenStore} from '@/stores/token.js'
const tokenStore = useTokenStore();
import useUserInfoStore from '@/stores/userInfo.js'
const userInfoStore = useUserInfoStore();
//用户头像地址
const imgUrl= ref(userInfoStore.info.userPic)
//图片上传成功的回调函数
const uploadSuccess = (result)=>{
imgUrl.value = result.data;
}
import {userAvatarUpdateService} from '@/api/user.js'
import {ElMessage} from 'element-plus'
//头像修改
const updateAvatar = async ()=>{
//调用接口
let result = await userAvatarUpdateService(imgUrl.value);
ElMessage.success(result.msg? result.msg:'修改成功')
//修改pinia中的数据
userInfoStore.info.userPic = imgUrl.value
}
</script>
<template>
<el-card class="page-container">
<template #header>
<div class="header">
<span>更换头像</span>
</div>
</template>
<el-row>
<el-col :span="12">
<el-upload
ref="uploadRef"
class="avatar-uploader"
:show-file-list="false"
:auto-upload="true"
action="/api/upload"
name="file"
:headers="{'Authorization':tokenStore.token}"
:on-success="uploadSuccess"
>
<img v-if="imgUrl" :src="imgUrl" class="avatar" />
<img v-else width="278" />
</el-upload>
<br />
<el-button type="primary" :icon="Plus" size="large" @click="uploadRef.$el.querySelector('input').click()">
选择图片
</el-button>
<el-button type="success" :icon="Upload" size="large" @click="updateAvatar">
上传头像
</el-button>
</el-col>
</el-row>
</el-card>
</template>
<style lang="scss" scoped>
.avatar-uploader {
:deep() {
.avatar {
width: 278px;
height: 278px;
display: block;
}
.el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 278px;
height: 278px;
text-align: center;
}
}
}
</style>