- 🏠 简介
- 📥 源码下载
- 🚀 安装指南
- 🔧 niucloud (服务端)
- 🖥️ admin (后台管理端)
- 📱 uni-app(手机端前端)
- 🌐 web端(PC前端)
- ⚙️ 代码生成器
- ⚙️ 配置手册
- 📚 使用手册
- 🔄 版本更新
-
❓ 常见问题
- 服务器问题
- 安装问题
- 使用问题
- 版本问题
-
其他问题
- 怎么添加菜单,添加了菜单不出现怎么回事
- 站点site端(租户端、商家端)和saas管理端(平台端)究竟啥意思,有啥区别
- 框架中是有订单表order,假如开发一个商城插件,请问商城的订单数据是不是重新搞一个订单表shop_order
- 有些支付平台是绑定回调唯一网址或目录,如果有几个开发者开发插件都有支付那这块怎么解决?
- 站点过期,可以登录,这样对吗?
- 计划任务怎么启动啊
- Git多分支开发,切换分支
- 安装应用出现is_dir()报错处理方案
- 绑定授权时出现“请求来源产品与授权产品不一致”解决方案
- “未找到admin源码所在目录”的解决方案
- 页面装修本地开发环境配置
- 接口请求错误处理方案
- 未获取到授权信息问题处理方案
- 腾讯地图配置
- 请求超时问题处理方案
- 下载应用时提示找不到zip解决方案
- 怎么关闭开发调试模式
- 获取数据失败问题处理方案
- 框架安装后,访问域名无法进入admin端(多数发生在本地)
- 底部导航失效问题
- 开放平台小程序审核通过发布失败问题
- 先升级插件后升级框架,导致云编译报debounce的错误
- 微信公众号自动回复不通
- 如何修改访问域名默认跳转端口
- 插件与框架的版本兼容问题处理方案
- 升级提示mkdir()处理方案
- 云编译时node.js内存不足导致内存溢出处理方案
- 报错Allowed memory size of ** bytes exhausted (tried to allocate ** bytes)处理方法
- Mysql修改sql_mode模式
- 框架1.0.2之前升级最新版错误Undefined array key "content"
- 安装插件提示不适配框架版本的处理
路由
路由配置详解
路由结构概述
采用Vue Router进行路由管理,路由配置位于src/router/目录下,主要包含两个核心文件:
-
index.ts:路由主配置文件,负责路由的创建、全局守卫和拦截逻辑 -
routers.ts:路由定义文件,包含静态路由、免登录路由、根路由等基本结构定义
路由类型概述
静态路由 (STATIC_ROUTES)
静态路由是应用运行时始终存在的基础路由,如404页面:
export const STATIC_ROUTES: Array<RouteRecordRaw> = [
{
path: '/:pathMatch(.*)*',
component: () => import('@/app/views/error/404.vue')
}
]
免登录路由 (NO_LOGIN_ROUTES)
免登录路由是不需要用户登录即可访问的路由列表,通常包含登录页面和一些公开页面:
export const NO_LOGIN_ROUTES: string[] = [
'/404'
]
应用类型路由
项目支持多种应用类型,每种类型都有对应的根路由配置:
-
根路由 (ROOT_ROUTER):应用的顶层路由
-
平台端根路由 (ADMIN_ROUTE):管理员端路由,路径以
/admin开头 -
HOME端根路由 (HOME_ROUTE):首页相关路由,路径以
/home开头 -
站点端根路由 (SITE_ROUTE):站点管理路由,路径以
/site开头 -
装饰路由 (DECORATE_ROUTER):装饰相关路由,路径以
/decorate开头
以管理员端路由为例:
export const ADMIN_ROUTE: RouteRecordRaw = {
path: '/admin',
name: Symbol('admin'),
children: [
{
path: '',
name: Symbol('adminRoot'),
component: Default
},
{
path: 'login',
meta: {
type: 1,
title: '用户登录'
},
component: () => import('@/app/views/login/index.vue')
}
]
}
路由初始化
路由在应用启动时进行初始化,主要步骤如下:
-
创建路由实例:使用
createRouter函数创建Vue Router实例 -
合并基础路由:将静态路由、应用类型路由和插件路由合并到路由实例中
-
重写路由方法:对
push和resolve方法进行重写,以支持多应用类型的路由处理
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [ADMIN_ROUTE, HOME_ROUTE, SITE_ROUTE, ...STATIC_ROUTES, ...ADDON_ROUTE]
})
/**
* 重写push方法
*/
const originPush = router.push
router.push = (to: RouteLocationRaw) => {
const route: any = typeof to == 'string' ? urlToRouteRaw(to) : to
if (route.path) {
const paths = route.path.split('/').filter((item: string) => { return item })
route.path = ['admin', 'site', 'home'].indexOf(paths[0]) == -1 ? `/${getAppType()}${route.path}` : route.path
}
return originPush(route)
}
/**
* 重写resolve方法
*/
const originResolve = router.resolve
router.resolve = (to: RouteLocationRaw, currentLocation?: RouteLocationNormalizedLoaded) => {
const route: any = typeof to == 'string' ? urlToRouteRaw(to) : to
if (route.path) {
const paths = route.path.split('/').filter((item: string) => { return item })
route.path = ['admin', 'site', 'home'].indexOf(paths[0]) == -1 ? `/${getAppType()}${route.path}` : route.path
}
return originResolve(route, currentLocation)
}
路由守卫
项目实现了全局路由守卫,用于处理路由跳转前的权限验证、数据加载等逻辑:
// 全局前置守卫
router.beforeEach(async (to: any, from, next) => {
// 显示加载进度条
NProgress.start()
// 处理重定向参数
to.redirectedFrom && (to.query = to.redirectedFrom.query)
// 获取用户和系统状态
const userStore = useUserStore()
const systemStore = useSystemStore()
// 加载语言包
await language.loadLocaleMessages(to.meta.addon || '', (to.meta.view || to.path), systemStore.lang);
// 权限验证和动态路由加载逻辑...
})
// 全局后置钩子
router.afterEach(() => {
// 隐藏加载进度条
NProgress.done()
})
动态路由加载
项目支持基于用户权限的动态路由加载,主要流程如下:
-
用户登录成功后,获取用户的权限菜单列表
-
根据权限菜单列表动态生成路由配置
-
使用
router.addRoute方法将动态路由添加到路由实例中
// 动态添加可访问路由表
userStore.routers.forEach(route => {
if (!route.children) {
if (route.meta.app == 'admin') {
router.addRoute(ADMIN_ROUTE.children[0].name, route)
} else {
router.addRoute(SITE_ROUTE.children[0].name, route)
}
return
}
// 添加带子路由的路由
if (route.meta.app == 'admin') {
router.addRoute(ADMIN_ROUTE.name, route)
} else {
router.addRoute(SITE_ROUTE.name, route)
}
})
路由工具函数
项目提供了一系列路由相关的工具函数,用于路由的格式化、查找等操作:
-
formatRouters:将后端返回的路由数据格式化为Vue Router可识别的路由配置
-
findFirstValidRoute:查找第一个有效的路由,用于设置应用首页
-
findRules:从路由配置中提取按钮权限规则
/**
* 格式化路由
* @param routes 原始路由数据
* @param parentRoute 父路由配置
*/
export function formatRouters(routes: Route[], parentRoute: RouteRecordRaw | null = null) {
return routes.map((route) => {
const routeRecord = createRoute(route, parentRoute)
if (route.children != null && route.children && route.children.length) {
routeRecord.children = formatRouters(route.children, routeRecord)
}
return routeRecord
})
}
插件路由集成
项目支持插件路由的集成,通过以下方式加载插件中的路由配置:
// 加载插件中定义的router
const ADDON_ROUTE = []
const addonRoutes = import.meta.globEager('@/addon/**/router/index.ts')
for (const key in addonRoutes) {
const addon: any = addonRoutes[key]
addon.ROUTE && ADDON_ROUTE.push(...addon.ROUTE)
addon.NO_LOGIN_ROUTES && NO_LOGIN_ROUTES.push(...addon.NO_LOGIN_ROUTES)
}
路由使用示例
页面跳转
// 使用router.push进行页面跳转
import { useRouter } from 'vue-router'
const router = useRouter()
// 字符串路径跳转
router.push('/admin/auth/user')
// 对象形式跳转
router.push({
path: '/admin/auth/user',
query: { id: '123' }
})
// 命名路由跳转
router.push({
name: 'user',
params: { id: '123' }
})
路由元信息
路由配置中可以包含元信息(meta),用于存储路由相关的额外数据:
const route = {
path: '/admin/auth/user',
name: 'user',
meta: {
title: '用户管理',
icon: { name: 'user', type: 'iconfont' },
type: 1,
show: true,
app: 'admin'
},
component: () => import('@/app/views/auth/user.vue')
}
在组件中可以通过useRoute().meta访问路由元信息。