npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

admin-router-plus

v1.2.8

Published

vue-router扩展, 登录拦截【前置】、动态注册路由。

Readme

admin-router-plus

介绍

vue-router 登录拦截(前置)、动态注册路由。

安装

  npm i admin-router-plus --save

说明

  1. 插件依赖vue-router(路由),需在注册vue-router之后注册
  2. 登录拦截(前置):判断cookie中的token值是否不为空,否则将被拦截至登录页
  3. 无需登录鉴权路由需配置meta: { noAuth: true }, 否则将被拦截跳转到登录页
  4. 动态路由触发条件:会在进入首个鉴权路由前触发请求,并注册完动态路由后进入页面。

API

RouterConfig

动态路由配置项(注意路由路径 path 以/开头自动会变成顶级路由)。

export interface RouterConfig {
  modules?: Record<string, unknown>; // 所有动态路由文件(import.meta.glob 返回的对象)
  loginPagePath?: string; // 登录页路径,默认 '/login'
  parentRouteName?: string; // 动态路由挂载父级的 name
  routeTreeNodeHandler?: (route: any) => void; // 路由节点预处理回调(可以映射字段、设置 meta 等)
  dynamicRoutesRequest?: () => Promise<RouteTreeNode[]>; // 获取动态路由树的异步方法
}

export interface RouteTreeNode {
  path: string; // 路由地址
  name: string; // 路由名称
  redirect?: string; // 路由重定向
  component?: string; // 页面文件名
  meta?: Record<string, unknown>; // 路由元信息
  children?: RouteTreeNode[]; // 子路由
}

clearDynamicRoutes(router?) => string[]

用于移除已注册的动态路由(由插件在运行时注册的路由)。

import { clearDynamicRoutes } from 'admin-router-plus';

// 使用内部 router
const removed = clearDynamicRoutes();
console.log('移除的动态路由:', removed);

// 传入 router 实例
const removed2 = clearDynamicRoutes(router);
console.log('移除的动态路由(指定 router):', removed2);

使用

main.ts

import { createApp } from 'vue';
import { createPinia } from 'pinia';

import RouterPlus from 'admin-router-plus';

import router from './router';
import App from './App.vue';

const app = createApp(App);

app.use(createPinia());
app.use(router);

app.use(RouterPlus, {
  modules: import.meta.glob(`./views/**`),
  routeTreeNodeHandler: (route) => {
    route.name = route.menuCode;
    route.meta = { title: route.menuName };
  },
  dynamicRoutesRequest: async () => {
    // 请求动态路由...
    return menusTree;
  },
});

app.mount('#app');

实例

router/index.ts 如下:

import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/login',
      name: 'login',
      meta: { noAuth: true, noCache: true },
      component: () => import('../views/LoginView.vue'),
    },
    // 动态路由添加内容
    {
      path: '/',
      name: 'layout',
      redirect: '/home',
      component: () => import('../views/LayoutView.vue'),
      children: [],
    },
  ],
});

export default router;

动态路由接口响应 json 数据

[
  {
    "path": "company",
    "menuCode": "company",
    "menuName": "公司管理",
    "redirect": "/company/user",
    "children": [
      {
        "path": "user",
        "menuCode": "user",
        "menuName": "员工管理",
        "component": "./views/UserView.vue"
      },
      {
        "path": "department",
        "menuCode": "department",
        "menuName": "部门管理",
        "component": "./views/DepartmentView.vue"
      }
    ]
  }
]

等同效果

import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // 静态路由
    {
      path: '/login',
      name: 'login',
      meta: { noAuth: true, noCache: true },
      component: () => import('../views/LoginView.vue'),
    },
    // 等同动态路由添加内容
    {
      path: '/',
      name: 'layout',
      redirect: '/home',
      component: () => import('../views/LayoutView.vue'),
      children: [
        {
          path: 'company',
          name: 'company',
          redirect: '/company/user',
          meta: { title: '公司管理' },
          component: () => import('../views/Empty.vue'),
          children: [
            {
              path: 'user',
              name: 'user',
              meta: { title: '用户管理' },
              component: () => import('../views/UserView.vue'),
            },
            {
              path: 'department',
              name: 'department',
              meta: { title: '部门管理' },
              component: () => import('../views/DepartmentView.vue'),
            },
          ],
        },
      ],
    },
  ],
});

export default router;