1.概要
2.Layout主页布局
文件地址:src\views\Layout.vue
2.1 script行为模块
从elementUI中选取图标图案。
<script setup>
import {
Management,
Promotion,
UserFilled,
User,
Crop,
EditPen,
SwitchButton,
CaretBottom
} from "@element-plus/icons-vue"
</script>
2.2 template结构模块
2.2.1 左侧菜单
<template>
<el-container class="layout-container">
<!-- 左侧菜单 -->
<el-aside width="200px">
<!-- 网站logo -->
<div class="el-aside__logo"></div>
<!-- 下拉菜单组件 -->
<el-menu active-text-color="#ffd04b" background-color="#232323" text-color="#fff" router>
<el-menu-item index="/article/category">
<el-icon>
<Management/>
</el-icon>
<span>
文章分类
</span>
</el-menu-item>
<el-menu-item index="/article/manage">
<el-icon>
<Promotion/>
</el-icon>
<span>
文章管理
</span>
</el-menu-item>
<el-sub-menu>
<template #title>
<el-icon>
<UserFilled/>
</el-icon>
<span>个人中心</span>
</template>
<el-menu-item index="/user/info">
<el-icon>
<User/>
</el-icon>
<span>基本资料</span>
</el-menu-item>
<el-menu-item index="/user/avatar">
<el-icon>
<Crop/>
</el-icon>
<span>更换头像</span>
</el-menu-item>
<el-menu-item index="/user/resetPassword">
<el-icon>
<EditPen/>
</el-icon>
<span>重置密码</span>
</el-menu-item>
</el-sub-menu>
</el-menu>
</el-aside>
<!-- 右侧内容区 -->
<!-- ... -->
</el-container>
</template>
2.2.2 右侧菜单
<template>
<el-container class="layout-container">
<!-- 左侧菜单 -->
<!-- ... -->
<!-- 右侧内容区 -->
<el-container>
<!-- 头部分 -->
<el-header>
<div>用户:<strong>昼夜节律</strong></div>
<!-- 下拉菜单 -->
<el-dropdown placement="bottom-end" @command="handleCommand">
<span class="el-dropdown__box">
头像
<el-icon>
<CaretBottom/>
</el-icon>
</span>
<template #dropdown>
<ed-dropdown-menu>
<el-dropdown-item command="info" :icon="User">基本资料</el-dropdown-item>
<el-dropdown-item command="avatar" :icon="Crop">更换头像</el-dropdown-item>
<el-dropdown-item command="resetPassword" :icon="EditPen">重置密码</el-dropdown-item>
<el-dropdown-item command="logout" :icon="SwitchButton">退出登录</el-dropdown-item>
</ed-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<!-- 体部分 -->
<el-main>
<RouterView></RouterView>
</el-main>
<!-- 脚部分 -->
<el-footer>
XXX版权所有,备案地址,友情链接
</el-footer>
</el-container>
</el-container>
</template>
2.3 style样式模块
<style lang="scss" scoped>
.layout-container{
height: 100vh;
background-color: #999;
.el-aside{
background-color: #232323;
&__logo{
height:120px;
background: url('@/assets/logo.png') no-repeat center / 120px auto;
}
.el-menu{
border-right: none;
}
}
.el-header{
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
.el-dropdown__box{
display: flex;
align-items: center;
.el-icon{
color: #999;
margin-left: 10px;
}
&:active,&:focus{
outline: none;
}
}
}
.el-footer{
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
}
}
</style>
2.4 效果视图
3.左侧菜单点击跳转路由
新建文件×5,用于存放不同功能的网址内容,分别是:
文章管理:src\views\article\ArticleCategory.vue
文章分类:src\views\article\ArticleManage.vue
更换头像:src\views\user\UserAvatar.vue
用户信息:src\views\user\UserInfo.vue
更改密码:src\views\user\UserPassword.vue
文件地址:src\router\index.js
import { createRouter, createWebHistory } from 'vue-router'
import Login from '@/views/Login.vue'
import Layout from '@/views/Layout.vue'
import ArticleCategory from '@/views/article/ArticleCategory.vue'
import ArticleManage from '@/views/article/ArticleManage.vue'
import UserAvatar from '@/views/user/UserAvatar.vue'
import UserInfo from '@/views/user/UserInfo.vue'
import UserPassword from '@/views/user/UserPassword.vue'
//配置路由关系
const routes = [
{
path:'/login',
component:Login
},{
path:'/',
component:Layout,
redirect:'article/manage',
children:[
{path:'/article/category',component:ArticleCategory},
{path:'/article/manage',component:ArticleManage},
{path:'/user/info',component:UserInfo},
{path:'/user/avatar',component:UserAvatar},
{path:'/user/resetPassword',component:UserPassword}
]
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: routes
})
export default router
4.定义一个新Store
使用 Vue.js 的状态管理库 Pinia 来创建一个名为 useUserInfoStore
的状态存储(store)。
文件地址:src\stores\userInfo.js
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;
5.向后端获取用户信息
发送一个 POST 请求到服务器的 /user/userinfo
路径,以获取用户信息。
export const userInfoService=()=>{
return request.post('/user/userinfo')
}
6.顶部导航动态信息显示
6.1 调用服务端接口
从服务端获取用户信息并将其存储到 Pinia store 中。
<script setup>
import {...} from "@element-plus/icons-vue"
import avatar from '@/assets/default.png'
import { userInfoService } from "@/apis/user.js";
import useUserInfoStore from "@/stores/userInfo";
import { useTokenStore } from "@/stores/token";
const userInfoStore = useUserInfoStore()
//调用访问服务端接口函数,获取用户详细信息
const getUserInfo = async()=>{
//调用接口
let result = await userInfoService();
//将数据存储到pinia中
userInfoStore.setInfo(result.data)
}
getUserInfo()
</script>
6.2 替换固态数据
给用户名及其头像换成数据库中的动态数据。
注:此时头像为“未加载成功”条件下的默认头像