08.b-全局后置守卫案例-进度条加载
大约 2 分钟
src/main.ts
import { createApp, createVNode, render } from 'vue'
// import './style.css'
import App from './App.vue'
import router from './router'
import ElementUi from 'element-plus'
import 'element-plus/dist/index.css'
import loadingBarVue from './components/loadingBar.vue'
console.log(loadingBarVue); //不能直接使用
const Vnode = createVNode(loadingBarVue) //转成虚拟Dom
render(Vnode, document.body) //挂载
const app = createApp(App)
const whiteList = ['/']
//全局前置守卫
router.beforeEach((to, from, next) => {
Vnode.component?.exposed?.startLoading() //loadingBar
let token = localStorage.getItem('token')
//白名单 有值 或者登陆过存储了token信息可以跳转 否则就去登录页面
if (whiteList.includes(to.path) || token) { //token每次都要跟后端校验一下是否过期
}
})
//全局后置守卫
router.afterEach((to, from) => {
Vnode.component?.exposed?.endLoading()
})
app.mount('#app')
src/components/loadingBar.vue
<template>
<div class="wraps">
<div ref="bar" class="bar"></div>
</div>
</template>
<script setup lang='ts'>
import { ref, reactive, onMounted } from 'vue'
let speed = ref<number>(1)
let bar = ref<HTMLElement>()
let timer = ref<number>(0) //设置id
const startLoading = () => {
let dom = bar.value as HTMLElement
speed.value = 1
console.log(dom);
timer.value = window.requestAnimationFrame(function fn() {//不用箭头函数的原因,递归
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 + '%'
})
}, 1000)
}
// 放到全局导航守卫-后置守卫 后不需要了
// //只有在 onMounted 之后才能获取 DOM
// onMounted(() => {
// startLoading()
// endLoading()
// })
defineExpose({
startLoading,
endLoading,
})
</script>
<style lang='less' scoped>
.wraps {
position: fixed;
top: 0;
width: 100%;
height: 2px;
.bar {
height: inherit;
width: 0;
background: blue;
}
}
</style>
js 动画渲染补充
javascript 动画-计时器-requestAnimationFrame
src/views/Login.vue
看看效果,最好是放到 全局导航守卫-后置守卫
<template>
<!-- <loadingBar></loadingBar> 这里只是看看效果,最好是放到 全局导航守卫-后置守卫 !!!-->
<div class="login">
<el-form ref="form" :rules="rules" :model="formInline" class="demo-form-inline">
<el-form-item prop="user" label="账号:">
<el-input v-model="formInline.user" placeholder="请输入账号" />
import { useRouter } from 'vue-router'
import router from '../router';
import { ElMessage, FormRules, FormInstance } from 'element-plus'
import loadingBar from '../components/loadingBar.vue';
const formInline = reactive({
user: '',