vue 暴露组件方法
loadingbar
<template>
<div class="wrapper">
<div ref="bar" class="bar"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
let speed = ref<number>(1);
let bar = ref<HTMLDivElement>();
let timer = ref<number>(0);
const startLoading = () => {
let dom = bar.value as HTMLDivElement;
speed.value = 1;
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 = () => {
window.requestAnimationFrame(() => {
let dom = bar.value as HTMLDivElement;
setTimeout(() => {
speed.value = 100;
dom.style.width = '100%';
}, 1000);
});
};
onMounted(() => {
// startLoading();
// endLoading();
});
// 给组件暴露出去方法,可以让组件在外部被调用方法
defineExpose({
startLoading,
endLoading,
});
</script>
<style scoped lang="scss">
.wrapper {
position: fixed;
top: 0;
width: 100%;
left: 0;
height: 10px;
.bar {
height: inherit;
width: 0%;
background: red;
}
}
</style>
在路由守卫中使其每次都能被自动加载
import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router';
import { ElMessage } from 'element-plus';
import LoadingBar from '@/components/LoadingBar.vue';
import { createVNode, render } from 'vue';
// 把组件转成虚拟dom
const vLoadingBar = createVNode(LoadingBar);
render(vLoadingBar, document.body);
const routes: RouteRecordRaw[] = [
{
path: '/',
alias: ['/login'],
component: () => import('@/views/Login.vue'),
},
{
path: '/index',
meta: {
requireAuth: true,
transition: 'animate__fadeInDownBig',
},
component: () => import('@/views/Index.vue'),
},
];
const router = createRouter({
// createRouter返回一个router实例
history: createWebHistory(),
routes,
});
//const whiteList = ['/'];
router.beforeEach((to, from, next) => {
vLoadingBar.component?.exposed?.startLoading();
if (to.meta.requireAuth) {
if (localStorage.getItem('token')) {
next();
} else {
ElMessage.error('您没有权限访问');
next('/');
}
} else {
next();
}
// if (whiteList.includes(to.path) || localStorage.getItem('token')) {
// next();
// } else {
// next('/');
// }
});
router.afterEach((to, from) => {
vLoadingBar.component?.exposed?.endLoading();
});
export default router;