index.js
4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
* @Date: 2025-10-30 10:29:15
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-11-12 15:48:17
* @FilePath: /stdj_h5/src/router/index.js
* @Description: 文件描述
*/
import { createRouter, createWebHashHistory } from 'vue-router'
import { useLoadingStore } from '@/stores/loading.js'
import Cookies from 'js-cookie'
const routes = [
{
path: '/',
name: 'Splash',
component: () => import('../views/Splash.vue')
},
{
path: '/home',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/masters',
name: '三師七證',
component: () => import('../views/Masters.vue')
},
{
path: '/masters/:id',
name: '三師七證详情',
component: () => import('../views/MastersDetail.vue')
},
{
path: '/yinlishi',
name: '引礼师',
component: () => import('../views/YinLiShi.vue')
},
{
path: '/yinlishi/:id',
name: '引礼师详情',
component: () => import('../views/YinLiShiDetail.vue')
},
{
path: '/news/:id',
name: 'NewsDetail',
component: () => import('../views/NewsDetail.vue')
},
{
path: '/students',
name: '戒子',
component: () => import('../views/Students.vue')
},
{
path: '/studentInfo',
name: '戒子详情',
component: () => import('../views/StudentInfo.vue')
},
{
path: '/login',
name: '登录',
component: () => import('../views/Login.vue')
},
{
path: '/jz_login',
name: '登录-戒子',
component: () => import('../views/LoginID.vue')
},
{
path: '/volunteers',
name: '义工',
component: () => import('../views/Volunteers.vue')
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: () => import('../views/NotFound.vue')
}
]
const router = createRouter({
history: createWebHashHistory('/index.html'),
routes,
/**
* 路由切换时的滚动行为
* 说明:不使用平滑滚动,进入新页面时立即滚动到顶部,确保用户无感知的快速回到初始位置。
*/
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
}
return { left: 0, top: 0 }
}
})
// 路由守卫
router.beforeEach((to, from, next) => {
// 设置页面标题
if (to.meta.title) {
document.title = to.meta.title
}
// 开启全局loading用于覆盖路由懒加载白屏
/**
* 开启路由级加载指示
* @description 进入任意页面前先展示全局loading,避免异步组件/资源加载期间出现白屏
*/
try {
const loading = useLoadingStore()
loading.start()
} catch (e) {
// 兜底:忽略异常,保证路由流程继续
void e
}
/**
* 访问控制:除首页('/')与登录页外,其余页面均需登录
*/
const token_cookie = Cookies.get('token-stdj')
const is_login = token_cookie !== undefined
// 白名单:无需登录校验的路径
const white_list = ['/', '/jz_login']
const need_auth = !white_list.includes(to.path)
if (need_auth && !is_login) {
// 在重定向前关闭或重置上一跳的loading,避免计数残留
try {
const loading = useLoadingStore()
loading.reset()
} catch (e) {
void e
}
next({ name: '登录-戒子', query: { redirect: to.fullPath } })
return
}
next()
})
// 路由解析完成(异步组件与守卫均已完成)后关闭loading
/**
* 关闭路由级加载指示
* @description 在组件解析完成后关闭一次全局loading,剩余由接口加载计数继续控制
*/
router.beforeResolve(() => {
try {
const loading = useLoadingStore()
loading.end()
} catch (e) {
// 兜底:忽略异常,保证路由流程继续
void e
}
})
// 路由错误时重置loading,避免蒙版残留
router.onError(() => {
try {
const loading = useLoadingStore()
loading.reset()
} catch (e) {
// 兜底:忽略异常,保证路由流程继续
void e
}
})
export default router