vue3-实战-05-管理后台顶部tabbar开发-全局守卫

目录

1-顶部tabbar组件静态搭建与拆分

2-菜单折叠效果

3-顶部面包屑动态展示

4-刷新和全屏

4.1-点击刷新操作

4.2-全屏

4.3-退出登录

5-路由鉴权


1-顶部tabbar组件静态搭建与拆分

       分析一下,顶部分为左右两侧,左侧是面包屑,右边是 刷新-全屏-设置 以及用户信息相关;我们将左右分别拆分两个组件。tabbar组件src\layout\tabbar\index.vue 如下

<template>
  <div class="tabbar">
    <div class="tabbar_left">     
      <!--顶部左侧图标 -->
      <Breadcrumb></Breadcrumb>
    </div>
    <!--顶部右侧设置按钮 -->
    <div class="tabbar_right">
      <Setting></Setting>
    </div>
  </div>
</template>

<script setup lang="ts">
import Breadcrumb from './breadcrumb/index.vue'
import Setting from './setting/index.vue'
</script>
<script lang="ts">
export default {
  name: 'Tabbar',
}
</script>

<style scoped lang="scss">
.tabbar {
  width: 100%;
  height: 100%;
  display: flex;//水平分布
  justify-content: space-between;//左右布局
  background-image: linear-gradient(to right,rgb(240, 233, 233),rgb(204, 175, 175),rgb(197, 111, 111));
  .tabbar_left {
    display: flex;
    align-items: center; //Y轴侧轴居中
    margin-left: 20px;
  }
  .tabbar_right {
    display: flex;
    align-items: center; //Y轴侧轴居中
  }
}
</style>

       顶部左侧面包屑抽取为组件src\layout\tabbar\breadcrumb\index.vue,我们需要使用element-plus框架中的el-breadcrumb 组件,组件内容如下:

<template>
  <!--顶部左侧图标 -->
  <el-icon style="margin-right: 10px"><Expand /></el-icon>
  <el-breadcrumb separator-icon="ArrowRight">
    <el-breadcrumb-item>权限管理</el-breadcrumb-item>
    <el-breadcrumb-item>用户管理</el-breadcrumb-item>
  </el-breadcrumb>
</template>

<script setup lang="ts"></script>

<style scoped lang="scss"></style>

顶部右侧的图标和用户信息模块src\layout\tabbar\setting\index.vue 组件内容如下:

<template>
  <el-button size="small" icon="Refresh" circle></el-button>
  <el-button size="small" icon="FullScreen" circle></el-button>
  <el-button size="small" icon="Setting" circle></el-button>
  <img
    src="../../../../public/logo.png"
    style="width: 24px; height: 24px; margin: 0px 10px"
  />
  <el-dropdown>
    <span class="el-dropdown-link">
      admin
      <el-icon class="el-icon--right">
        <arrow-down />
      </el-icon>
    </span>
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item>退出登录</el-dropdown-item>
      </el-dropdown-menu>
    </template>
  </el-dropdown>
</template>

<script setup lang="ts"></script>

<style scoped lang="scss"></style>

2-菜单折叠效果

       当我们点击tabbar左侧的展开按钮时,菜单需要折叠,我们需要将菜单layout组件的左右缩小,顶部和内容区我们需要向左伸展。tabbar左侧的组件与layout通信,告诉layout组件我是展开还是折叠,这时就涉及到孙子和爷爷的通信;这时我们可以使用仓库实现数据共享。

新建小仓库:src\store\modules\setting.ts,来实现折叠还是展开的响应式数据;

 面包屑左侧图标显示展开还是折叠,我们使用vue的component组件(vue2和vue3都有),

       当我们折叠菜单后,我们需要变更顶部tabbar和内容区的宽度,需要动态展示,这时我们需要采用动态样式。菜单组件有个collapse属性,我们使用这个来折叠菜单。顶部导航的tabbar和内容展示去来个动态的class,并且来个过渡动画transition效果。

ps:展示菜单中属性background-color应该取值background-color="#001529";如果写成background-color="$base-menu-background"会看不见子菜单,白色。

 

3-顶部面包屑动态展示

       tabbar组件的顶部面包屑我们已经静态展示了,现在需要动态展示。我们可以使用路由matched属性就可以匹配到路由信息,内部自己嵌套路由。

       由于首页是在layout组件下的二级,我们可以将src\router\router.ts中的layout组件信息meta中的title和icon置空,这样我们可以实现隐藏v-show。点击面包屑上面的标题,也需要进行路由跳转,使用到了to属性。如果点击一级路由,我们在router中配置重定向到一级路由下第一个二级路由。

ps:在vue3中在v-for中如果使用v-if,v-if的优先级更高,所以这里我们使用v-show

4-刷新和全屏

当我们点击tabbar右侧的刷新和全屏的时候,我们需要进行刷新和全屏操作。

4.1-点击刷新操作

      当我们点击刷新操作的时候,需要重新加载main区域数据,刷新按钮在tabbar组件里面的setting组件中,main和setting不在一个组件中,涉及到组件通信,而且main组件和setting组件是 叔侄 关系。我们采用仓库来定义一个属性控制是否点击刷新。然后在main中使用watch来监听数据是否发生变化,来重新销毁和创建组件。

 src\layout\main\index.vue

4.2-全屏

       当我们点击全屏按钮的时候,我们需要切换到全屏模式,这里我们直接使用dom对象里面的方法实现;document.fullscreenElement和document.documentElement.requestFullscreen()以及document.exitFullscreen()来实现。

 

4.3-退出登录

tabbar左右的主题模式因为目前没有数据,暂时不显示,后续开发和完善....获取用户信息在下一章节,路由鉴权和守卫一起开发,先开发退出登录功能。当用户点击退出登录按钮时,需要清空本地的localStorage数据和用户基本信息数据。

5-路由鉴权

路由鉴权:鉴权,项目当中路由能不能被的权限的设置(某一个路由什么条件下可以访问、什么条件下不可以访问)。

比如本项目中,如果没有登录(没有token),我们不能访问其他路由,只能跳转到登录的组件页面;当已经登录,我们需要获取用户信息,渲染用户名和图像;当有token没有用户信息时,我们需要获取用户信息。我们用户信息存储在store中(非持久化),当我们点击页面刷新时,用户信息接口没有重新调用(此时token还有效);我们不可能每个组件页面加载时调用获取用户信息接口,我们可以将这个功能放在守卫中进行。

1-封装获取用户信息接口存储到store,请求头需要带登录返回的token信息。

 

2-路由导航,全局守卫开发;任意路由切换实现进度条业务,路由鉴权(路由组件访问权限的设置)

src\permisstion.ts内容如下:如果要使用,必须在入口文件main.ts中引入。

 

//路由鉴权:鉴权,项目当中路由能不能被的权限的设置(某一个路由什么条件下可以访问、什么条件下不可以访问)
import router from '@/router'
import setting from './setting'
//@ts-ignore
import nprogress from 'nprogress'
//引入进度条样式
import 'nprogress/nprogress.css'
nprogress.configure({ showSpinner: false })

//获取用户相关的小仓库内部token数据,去判断用户是否登录成功
import useUserStore from './store/modules/user'
import pinia from './store'
import {GET_TOKEN} from './utils/token'
const userStore = useUserStore(pinia)

//全局守卫:项目当中任意路由切换都会触发的钩子
//全局前置守卫
router.beforeEach(async (to: any, from: any, next: any) => {
    document.title = `${setting.title} - ${to.meta.title}`
    //to:你将要访问那个路由; from:你从来个路由而来;next:路由的放行函数
    nprogress.start()
    const token = GET_TOKEN() //获取token,去判断用户登录、还是未登录
    const username = userStore.username //获取用户名字
    //用户登录判断
    if (token) {     
      if (to.path == '/login') {//登录成功,访问login,不能访问,指向首页
        next({ path: '/' })
      } else {//登录成功访问其余六个路由(登录排除)     
        if (username) {//有用户信息         
          next()//放行
        } else {//如果没有用户信息,在守卫这里发请求获取到了用户信息再放行          
          try {            
            await userStore.userInfo()//获取用户信息
            //放行
            //万一:刷新的时候是异步路由,有可能获取到用户信息、异步路由还没有加载完毕,出现空白的效果
            next({ ...to })
          } catch (error) {//token过期:获取不到用户信息了--用户手动修改本地存储token           
            userStore.userLogout()
            next({ path: '/login', query: { redirect: to.path } })
          }
        }
      }
    } else {//用户未登录判断    
      if (to.path == '/login') {
        next()
      } else {
        next({ path: '/login', query: { redirect: to.path } })
      }
    }
  })
  //全局后置守卫
  router.afterEach((to: any, from: any) => {
    nprogress.done()
  })
  

3-用户点击退出登录,我们需要调用后端接口,目前我们没有mock数据,我们暂时先忽略;前端需要清除store数据和清除localStorage里面的token信息。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值