vue3 + vite + ts + setup , 第十八练 vue3 中使用vue-router(二),前置守卫、后置守卫、路由元信息、过渡动效、滚动行为

2023-05-16

router的全局前置守卫

router.beforeEach

每个守卫方法接收三个参数:

to: Route, 即将要进入的目标 路由对象;
from: Route,当前导航正要离开的路由;
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
 

router.beforeEach((to, form, next) => {
    console.log(to, form);
    next()
})

前置守卫可以用来做权限判断:

//判断用户是否登录,如果没有登录则拦截跳转,跳转到登录界面

router.beforeEach((to, form, next) => {
  console.log('beforeEach', Loading);
  Loading.component?.exposed?.startLoading()
  let token = localStorage.getItem('token')
  if (token && to.name != 'Login') {
    next()
  } else {
    to.name == 'Login' ? next() : next('/login')
  }

})

全局后置守卫

可以用来做路由跳转时 加载效果,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身

router.afterEach((to, from) => {
  Loading.component?.exposed?.endLoading()
})

loading组件

nprogress:

npm install --save nprogress

引用:

import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
NProgress.configure({
    showSpinner: false
});


 NProgress.start()
 NProgress.done()

自定义loading组件:

<template>
  <div class="wraps">
    <div ref="bar" class="bar"></div>
  </div>
</template>
    
<script setup lang='ts'>
import { ref, onMounted } from 'vue'
let speed = ref<number>(1)
let bar = ref<HTMLElement>()
let timer = ref<number>(0)
const startLoading = () => {
  let dom = bar.value as HTMLElement;
  speed.value = 1
  timer.value = window.requestAnimationFrame(function fn() {
    dom.style.display = 'block'

    if (speed.value < 90) {
      speed.value += 1;
      dom.style.width = speed.value + '%'
      timer.value = window.requestAnimationFrame(fn)
    } else {
      speed.value = 1;
      window.cancelAnimationFrame(timer.value)
    }
  })

}

const endLoading = () => {
  let dom = bar.value as HTMLElement;
  setTimeout(() => {
    window.requestAnimationFrame(() => {
      speed.value = 100;
      dom.style.width = speed.value + '%'
    })
    setTimeout(() => {
      dom.style.display = 'none'
    }, 300)
  }, 500)

}


defineExpose({
  startLoading,
  endLoading
})
</script>
    
<style scoped>
.wraps {
  position: fixed;
  top: 0;
  width: 100%;
  height: 2px;


}

.bar {
  height: inherit;
  width: 0;
  background: blue;
}
</style>

路由元信息

通过路由记录的 meta 属性可以定义路由的元信息。使用路由元信息可以在路由中附加自定义的数据,例如:

  • 权限校验标识。
  • 路由组件的过渡名称。
  • 路由组件持久化缓存 (keep-alive) 的相关配置。
  • 标题名称
const routes: Array<RouteRecordRaw> = [
  {
    path: "/login",
    name: "Login",
    component: () => import('../components/login.vue'),
    meta: {
      title: "登录",
      transition: "animate__fadeInUp"
    }
  },
  {
    //动态路由参数
    path: "/",
    name: "Reg",
    component: () => import('../components/reg.vue'),
    alias: ['/root', '/roots', '/home'],
    redirect: () => {
      return {
        path: "/tab1"
      }
    },
    children: [
      {
        path: "/tab1",
        name: "tab1",
        component: () => import('../components/tab1.vue'),
        meta: {
          title: "测试tab1",
          transition: "animate__fadeInUp"
        }
      },
      {
        path: "tab2",
        name: "/tab2",
        components: {
          default: () => import('../components/tab2.vue'),
          two: () => import('../components/login.vue')
        },
        meta: {
          title: "测试tab222",
          transition: "animate__fadeInUp"

        }
      }
    ]
  }
]

使用TS扩展

如果不使用扩展 将会是unknow 类型

declare module 'vue-router' {
  interface RouteMeta {
    title?: string
  }
}

过渡动画

transition

  <router-view #default="{ route, Component }">
      <transition :enter-active-class="`animate__animated ${route.meta.transition}`">
        <component :is="Component"></component>
      </transition>
    </router-view>

上面路由过渡动画是和路由元结合的

路由滚动

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。vue-router 可以自定义路由切换时页面如何滚动。

当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法

const router = createRouter({
  history: createWebHashHistory(),
  // scrollBehavior: (to, from, savePosition) => {
  //   console.log(to, '==============>', savePosition);
  //   return new Promise((r) => {
  //     setTimeout(() => {
  //       r({
  //         top: 100
  //       })
  //     }, 2000);
  //   })
  // },

  scrollBehavior: (to, from, savePosition) => {
    console.log("滚动距离", savePosition)
    if (savePosition) {
      return savePosition
    } else {
      return {
        top: 300
      }
    }
  },
  routes: routes,
});

 scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。

可以使用异步,也可以直接return 一个固定的高度参数


const router = createRouter({
  history: createWebHistory(),
  scrollBehavior: (to, from, savePosition) => {
    return {
       top:200
    }
  }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3 + vite + ts + setup , 第十八练 vue3 中使用vue-router(二),前置守卫、后置守卫、路由元信息、过渡动效、滚动行为 的相关文章

随机推荐