1.首页架子搭建

1.1 样式布局

预期布局:
在这里插入图片描述
查看 element-ui 官方文档,看Container 布局容器

  • el-container 最外层
  • el-aside 侧边栏
  • el-main 主体内容
  • el-footer 底部内容
    在这里插入图片描述
    根据这个模板写的布局
  <el-container class="layout-container">
    <el-aside width="200px">
 		放入侧边栏菜单组件
    </el-aside>
    <el-container>
      <el-header>
     		头部区域:左边一个标题,右边一个下拉菜单
      </el-header>
      <el-main>
     		 主要内容部:放路由出口
        	 <router-view></router-view>
      </el-main>
      <el-footer>放入底部文字</el-footer>
    </el-container>
  </el-container>

首先考虑侧边栏,侧边栏用的

看官方文档菜单
在这里插入图片描述

<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">
          <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-menu
  active-text-color="#ffd04b"
  background-color="#232323"
  :default-active="$route.path"
  text-color="#fff"
  router
>
属性名 含义
active-text-color 当前选中项的文字颜色
background-color 菜单整体背景色
:default-active 默认高亮的菜单项,绑定的是 $route.path,即当前页面路径
text-color 普通菜单项的文字颜色
router 启用 Vue Router 模式,点击菜单自动跳转路由
普通菜单项(<el-menu-item>)
        <el-menu-item index="/article/channel">
          <el-icon><Management /></el-icon>
          <span>文章分类</span>
        </el-menu-item>
 index 放一个路由路径 el-icon 放图标 span 里放文字

带有下拉选项的菜单(el-sub-menu)
<el-sub-menu index="/user">
          <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>
 标题设置通过具名插槽的写法 
 <template #title>
  <el-icon><UserFilled /></el-icon>
  <span>个人中心</span>
</template>
下面的每一个子项都用el-menu-item包裹跟上面的一样

question one:
index=“/user/password” 是什么?

index 是 Element Plus 的菜单组件 或 的一个属性,用来标识这个菜单项的唯一标识值,不是浏览器的 index,也不是 Vue 的 index。不一定“必须”这么写成路径 /user/password,但 你必须给它一个唯一的 index 值,否则菜单行为无法区分每项。通过在最外层 el-menu配置router,可以实现路由跳转,它不是 Vue Router 的功能,而是 Element Plus 帮你封装好了

1.2 登入访问拦截

预期:在首页时,如果没有登入,应该拦截登入(没有 token的时候应该拦截登入
登入访问拦截,写在 router/index.js 中

在这里插入图片描述
两个参数 to 和 from 的解释:
假设你当前页面是 /login,然后点击跳转到 /article/manage
to.path 就是/article/manage
from.path 就是/login

登入访问拦截=>默认是直接放行的
放回值的几种情况

  • undefined/true 直接放行
  • false 拦回 from 的地址页面,从哪里来回到哪里去
  • 具体路径或路径对象 拦截到对应的地址
    • ‘/login’ {name:‘login’}
import { useUserStore } from '@/stores'

//登入访问拦截,默认不写 return 直接放行
router.beforeEach((to)=>{
  // 如果没有 token,且访问的是非登入界面,拦截到登录,其他情况正常放行
  const useStore=useUserStore()
  if(!useStore.token&&to.path!=='/login') return '/login'
})

在这里插入图片描述

1.3 右上角用户信息实现

查看接口文档 ,基本的请求封装已经写好了
在这里插入图片描述

1.将获取用户的基本信息,写在 api/user.js

// 获取用户基本信息
export const userGetInfoService=()=>  request.get('/my/userinfo')

2.将拿到的用户信息存在 pinia 中

import { defineStore } from 'pinia'
import { ref } from 'vue'
import { userGetInfoService } from '@/api/user'

export const useUserStore = defineStore(
  'big-user',
  () => {
    const token = ref('') // 定义 token
    const setToken = (newToken) => (token.value = newToken) // 设置 token
    const removeToken=()=>{token.value=''}

    // 定义用户信息
    const user=ref({})  //定义一个空的用户信息

    const getUser =async()=>{
      const res =await userGetInfoService() //请求获取数据
      user.value=res.data.data
    }

    return { token,setToken,removeToken,user,getUser }
  },
  {
    persist: true,
  },
)

3.在架子页面中调用拿去用户信息的代码,然后渲染用户信息

import {useUserStore} from '@/stores'
import { onMounted } from 'vue'

const userStore =useUserStore()

//加载阶段访问获取到的用户数据,不写这个钩子函数也可以
onMounted(async () => {
  await userStore.getUser()         // 等请求完
  console.log(userStore.user)       // 这时候数据就拿到了
})

cosole.log 结果,注意等创建完成功后打印,才能拿到 console.log 的结果,如果不需要 console.log,也不用写成 await 的那种写法
在这里插入图片描述
开始渲染页面

 <div>用户:<strong>{{ userStore.user.nickname||userStore.user.username}}</strong></div>
        <el-dropdown placement="bottom-end">
          <span class="el-dropdown__box">
            <el-avatar :src="userStore.user.user_pic||avatar" />

渲染成功
在这里插入图片描述

1.4 下拉菜单dropdown实现

<el-dropdown placement="bottom-end">
          <span class="el-dropdown__box">
            <el-avatar :src="userStore.user.user_pic||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-dropdown

  • placement=“bottom-end”:控制下拉菜单展开方向为右下角(靠右展开)。
  • #dropdown:这是插槽,表示下拉面板的内容。
  • el-dropdown-menu:下拉列表容器。
  • el-dropdown-item:每一个选项。
<template #dropdown>是具名插槽的写法,template中间放置下拉菜单中的每一个小项

关于 command,例子如下
command 是 Element Plus(Element-UI 的 Vue 3 版本)提供的标准属性,用于 <el-dropdown-item> 组件。其中 cmd 传入的就是 command 的值,点击事件传入 command
function handleCommand(cmd) {
  console.log(cmd) // 打印出 'logout' 或 'profile'
}

<el-dropdown @command="handleCommand">
  <template #dropdown>
    <el-dropdown-menu>
      <el-dropdown-item command="logout">退出登录</el-dropdown-item>
      <el-dropdown-item command="profile">基本资料</el-dropdown-item>
    </el-dropdown-menu>
  </template>
</el-dropdown>

单独定义handleCommand函数

自定义command 函数,点击路由跳转,点击退出登入清除本地信息

LayoutContainer.vue

const router =useRouter()
//自定义 command 函数,编写跳转路由和退出登入
const handleCommand =(key)=>{
    // 1.如果key 是退出登入,则清除本地数据(本地数据包含 token 和 user 信息)
    // 2.跳转路由

    if(key=='logout'){
        userStore.removeToken()
        userStore.setUser({})
        router.push('/login')
    }else{
      //如果 key 不是退出登入,跳转到相应的路由
      router.push(`/article/${key}`)
    }

src/stores/modules/user.js

//清除用户数据的函数
    const setUser =(obj)=>{
      user.value=obj
    }

功能测试成功

直接退出登入显得比较随意,应该让用户确认退出
使用组件
在这里插入图片描述
将红框内的函数加到下面的代码中,注意使用 async await,等待 await 成功执行并执行,否则不执行

const router =useRouter()
//自定义 command 函数,编写跳转路由和退出登入
const handleCommand =(key)=>{
    // 1.如果key 是退出登入,则清除本地数据(本地数据包含 token 和 user 信息)
    // 2.跳转路由

    if(key=='logout'){
        userStore.removeToken()
        userStore.setUser({})
        router.push('/login')
    }else{
      //如果 key 不是退出登入,跳转到相应的路由
      router.push(`/article/${key}`)
    }
const router =useRouter()
//自定义 command 函数,编写跳转路由和退出登入
const handleCommand =async (key)=>{
    // 1.如果key 是退出登入,则清除本地数据(本地数据包含 token 和 user 信息)
    // 2.跳转路由
     await ElMessageBox.confirm(
    '你确认要进行退出吗?',
    '温馨提示',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )

    if(key=='logout'){
        userStore.removeToken()
        userStore.setUser({})
        router.push('/login')
    }else{
      //如果 key 不是退出登入,跳转到相应的路由
      router.push(`/article/${key}`)
    }
   

}

在这里插入图片描述

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐