76- vue3案例 - 07-首页

一. 首页 layout 架子[element-plus 菜单组件]

功能需求说明:
        (1).基本架子拆解(菜单组件的使用)

        (2).登录访问拦截

        (3).用户基本信息获取&渲染

        (4).退出功能[element-plus 确认框]

1. 首页静态页面结构

        src\views\layout\LayoutContainer.vue

<script setup>
import {
  Management,
  Promotion,
  UserFilled,
  User,
  Crop,
  EditPen,
  SwitchButton,
  CaretBottom
} from '@element-plus/icons-vue'
import avatar from '@/assets/default.png'
</script>

<template>
  <!-- 
    el-menu 整个菜单组件
        :dafault-active="$route.path"  配置默认高亮的菜单项
        router router选项开启,el-menu-item 的 index 就是点击跳转的路径
    
    el-menu-item 菜单项
        index="/article/channel" 配置的是访问的跳转路径,配合default-active的值,实现高亮
   -->
  <el-container class="layout-container">
    <el-aside width="200px">
      <div class="el-aside__logo"></div>
      <el-menu
        active-text-color="#ffd04b"
        background-color="#232323"
        :default-active="$route.path"
        text-color="#fff"
        router
      >
        <el-menu-item index="/article/channel">
          <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 index="/user">
          <!-- 多级菜单的标题 - 具名插槽 title-->
          <template #title>
            <el-icon><UserFilled /></el-icon>
            <span>个人中心</span>
          </template>
          <!-- 展开内容 - 默认插槽-->
          <el-menu-item index="/user/profile">
            <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/password">
            <el-icon><EditPen /></el-icon>
            <span>重置密码</span>
          </el-menu-item>
        </el-sub-menu>
      </el-menu>
    </el-aside>
    <el-container>
      <el-header>
        <div>程序员:<strong>小帅鹏</strong></div>
        <el-dropdown placement="bottom-end">
          <span class="el-dropdown__box">
            <el-avatar :src="avatar" />
            <el-icon><CaretBottom /></el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="profile" :icon="User"
                >基本资料</el-dropdown-item
              >
              <el-dropdown-item command="avatar" :icon="Crop"
                >更换头像</el-dropdown-item
              >
              <el-dropdown-item command="password" :icon="EditPen"
                >重置密码</el-dropdown-item
              >
              <el-dropdown-item command="logout" :icon="SwitchButton"
                >退出登录</el-dropdown-item
              >
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </el-header>
      <el-main>
        <router-view></router-view>
      </el-main>
      <el-footer>大事件 ©2023 Created by 黑马程序员</el-footer>
    </el-container>
  </el-container>
</template>

<style lang="scss" scoped>
.layout-container {
  height: 100vh;
  .el-aside {
    background-color: #232323;
    &__logo {
      height: 120px;
      background: url('@/assets/2.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. 登录访问拦截

        src\router\index.js

import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/stores'

const router = createRouter({...})

// 登陆访问拦截 => 默认是直接放行的
// 根据返回值决定,是放行还是拦截
// 返回值:
// 1.undefined / true 直接放行
// 2.false 拦回from的地址页面
// 3.具体路径 或 路径对象 拦截到对应的地址
//   '/login'   {name: 'login'}
router.beforeEach((to) => {
  // 如果没有token,且访问的是非登录页,拦截到登录,其他情况正常放行
  const useStore = useUserStore()
  if (!useStore.token && to.path !== '/login') return '/login'
})

export default router

二. 用户信息基本获取&渲染

1. 封装获取信息api

        src\api\user.js

import request from '@/utils/request'
...
// 获取用户基本信息
export const userGetInfoService = () => request.get('/my/userinfo')
2. user仓库定义数据

        src\stores\modules\user.js

...
import { userGetInfoService } from '@/api/user'

// 用户模块 token setToken removeToken
//export const useUserStore = defineStore(
 // 'big-user',
 // () => {
   ...
    const user = ref({})  //定义空数据
    const getUser = async () => {
      const res = await userGetInfoService() // 调用获取用户信息接口
      user.value = res.data.data
    }

//    return {
     ...
      user,
      getUser
 //   }
//  },
// ...
//)
3. 页面中调用user仓库

        src\views\layout\LayoutContainer.vue

<script>
...
import { useUserStore } from '@/stores' // 引入user仓库
import { onMounted } from 'vue'
const userStore = useUserStore()  
onMounted(() => {  // 进入页面就加载
  userStore.getUser()   
  // console.log(userStore.user)
})
</script>
4. 页面中动态渲染

        src\views\layout\LayoutContainer.vue

<!--动态渲染用户名-->
<div>
  程序员:<strong>{{ userStore.user.nickname || userStore.user.username }}</strong>
</div>
<!--动态渲染用户头像-->
<el-avatar :src="userStore.user.user_pic || avatar" />

三. 添加个人信息跳转 & 退出操作

1. 注册点击事件
<template>
...
 <!-- @command="handleCommand": 注册下拉事件 -->
 <el-dropdown placement="bottom-end" @command="handleCommand">
    ...
         <!-- 折叠的下拉部分 -->
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="profile" :icon="User"
                >基本资料</el-dropdown-item
              >
              <el-dropdown-item command="avatar" :icon="Crop"
                >更换头像</el-dropdown-item
              >
              <el-dropdown-item command="password" :icon="EditPen"
                >重置密码</el-dropdown-item
              >
              <el-dropdown-item command="logout" :icon="SwitchButton"
                >退出登录</el-dropdown-item
              >
            </el-dropdown-menu>
          </template>
    </el-dropdown>
...
</template>
2. user仓库提供设置user数据方法

        src\stores\modules\user.js

...
//export const useUserStore = defineStore(
 // 'big-user',
//  () => {
   ...
    const setUser = (obj) => {
      user.value = obj
    }

 //   return {
      ...
      setUser
  //  }
 // },
  ...
//)
3. 添加 跳转 & 退出功能
<script>
...
import { useRouter } from 'vue-router'
const router = useRouter()
...
const handleCommand = async (key) => {
  if (key === 'logout') {
    //退出操作
    await ElMessageBox.confirm('你确认要进行退出么', '温馨提示', {
      type: 'warning',
      confirmButtonText: '确认',
      cancelButtonText: '取消'
    })

    //清除本地的数据(token + user信息)
    userStore.removeToken()
    userStore.setUser({})
    router.push('/login')
  } else {
    //个人中心跳转操作
    router.push(`/user/${key}`)
  }
}
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值