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 🙏

© 2026 – Pkg Stats / Ryan Hefner

u-vue-router-intercept

v1.2.3

Published

erhai 前端组件库

Readme

@weier/u-vue-router-intercept

  • 基于compose实现路由拦截,方便精细化处理vue项目中复杂路由拦截规则
  • 开发者只需要定于不同的 路由拦截函数,插件会自动按先后顺序处理路由拦截

next()next(route) 是有区别的:next函数接收到参数会执行vueRouter.next(route)并且跳出拦截流程前往执行目标路由拦截流程;不接收参数时 会执行下一个拦截函数

// 安装
npm i @weier/u-vue-router-intercept -S

routerIntercept 示例

import routerIntercept from '@weier/u-vue-router-intercept' // 用法
import Vue from 'vue'
import VueRouter from 'vue-router'
  
Vue.use(VueRouter)

let hasLogined = false
let promissions = []

const checkLogin = async ({to, from, next, router}) => {
  if (!hasLogined) {
    try {
      await request('login')
      checkLogin = true
      // 进入下一流程
      next()
    } catch(e) {
      // 跳出拦截&不会执行下一个拦截函数,前往目标路由
      next('/login')
    }
  } else {
    // 进入下一流程
    next()
  }
}

const getPromission = async ({to, from, next, router}) => {
  if (promissions.length === 0) {
    await request('promissions')
    promissions = ['/admin']
    // 进入下一流程 可能是router.next or 下一个逻辑
    next()
  } else {
    next()
  }
}

const checkPromission = ({to, from, next, router}) => {
  if (promissions.includes(to.path)) {
    // 进入下一流程
    next()
  } else {
    next('/403')
  }
}

const router = {
  mode: 'hash',
  routes: [
    {
      path: '/',
      components: null,
      meta: {
        intercepts: [checkLogin, getPromission, checkPromission],
      }
    }
  ]
}

routerIntercept(router, [checkLogin])

路由权限控制示例

// src/router/index.js
 import Vue from 'vue'
 import VueRouter from 'vue-router'
 import api37919 from '@/api/interface/project93/api37919' // 菜单接口
 import api38808 from '@/api/interface/project93/api38808' // 组织接口
 import { useRouter, createMenuInterceptFn, getPermissionsIntercept, createUserInterceptFn } from '@weier/u-vue-router-intercept'
 import { routes } from '@/router/config'
 export const { router } = useRouter(Vue, VueRouter)({
   routes, // 路由表
   iconClassName: 'icon-menu', // icon指定的前缀 默认icon-menu
   closeGlobalRedirect: false, // 自动添加 {path: '*',redirect: { path: '/404' }}
   useMock: WEIER.isMock, // 是否使用mock模式
   defaultIntercept: (params) => { // 默认路由拦截器 meta.intercepts为undefined
    // createMenuInterceptFn, getPermissionsIntercept, createUserInterceptFn 内置方法
    return [createUserInterceptFn(api38808, '@@OrgId')(params), createMenuInterceptFn(api37919)(params), getPermissionsIntercept(params)]
   }
 })
 // src/router/config.js
import Layout from '@/components/layout'
/**
 * 需要权限验证的路由
 * meta:{
 *   title: 'title'                       breadcrumb或菜单名称
 *   icon: 'iconfont-class-name'          默认图标
 *   breadcrumb: false                    是否面包屑
 *   isMenu: false                      是否菜单
 *   intercepts: []                      路由拦截器
 * }
 */
export const routes = [{
  path: '/',
  component: Layout, 
// Layout组件props接收了 routeStore 包含 menus、selectOrg 两个observable属性 
// Layout组件可 通过包的两个方法 getActiveMenu, getBreadCrumbList  分别获取高亮和面包屑数据 自行组装使用
  children: [
    {
      name: 'orders',
      component: null, // 一级菜单可以不配置 component 也可以不配置path 
      meta: { title: '订单及回款管理', icon: 'el-icon-document-copy' }, 
      children: [
        {
          meta: { title: '订单管理', breadcrumb: true },
          path: '/orders/manage',
          name: 'orderManage',
          component: () => import('@/pages/orders/manage'),
          children: [
            {
              meta: { title: '创建订单', breadcrumb: true, isMenu: false }, // 三级菜单 可以通过isMenu控制不展示
              path: '/orders/action',
              name: 'orderCreate',
              component: OrderAction
            },
            {
              meta: { title: '编辑订单', breadcrumb: true, isMenu: false },
              path: '/orders/action/:id',
              name: 'orderEdit',
              component: OrderAction
            },
          ]
        },
        {
          meta: { title: '回款管理', breadcrumb: true },
          path: '/orders/outstanding',
          name: 'orderOutstanding',
          component: () => import('@/pages/orders/outstanding')
        },
        {
          meta: { title: '退款管理', breadcrumb: true },
          path: '/orders/refund',
          name: 'orderRefund',
          component: () => import('@/pages/orders/refund')
        },
      ]
    }
  ]
}]

// src/main.js
import Vue from 'vue'
import App from './App'
import { router } from './router'
/* eslint-disable no-new */
new Vue({
    router,
    render: h => h(App)
  }).$mount('#app')

常见场景

一个应用有如下需求

  1. 加载任意功能页面前,需要获取用户名展示
  2. 加载任意功能页面,需要获取权限,来确认是否能够进入
  3. 存在白名单路由,该页面即使无权限,无用户信息都可以自由进入
  4. login一类的页面,如果用户信息能正常拉取,是不需要进入的,可以自动定向到 首页

分析以上需求,有一下伪代码

import { state, commit } from '@/store'

const getUserDetailOnce = async ({ to, from, next }) => {
  const nextRoute = () => to.path === '/login' ? next('/home') : next()
  if (!state.userDetail.name) {
    try {
      const { name } = await request('/user/detail')
      commit('updateUserDetail', { name })
      nextRoute()
    } catch (e) {
      // 无法正常获取用户信息的,需要重新登录
      to.path !== '/login' ? next(`/login?redirectUri=${encodeURIComponent(window.location.href)}`) : next()
    }
  } else {
    nextRoute()
  }
}

// 获取权限
const getPremissionsOnce = async ({ next }) => {
  if (!state.premissions) {
    try {
      const premissions = await request('/user/premissions')
      commit('updatePremissions', premissions)
      if (premissions.length > 0) {
        next()
      } else {
        confirm('您似乎还没有权限,请联系管理员')
      }
    } catch (e) {
      // 无法正常获取用户信息的,需要重新登录
      next(`/login?redirectUri=${encodeURIComponent(window.location.href)}`)
    }
  } else {
    next()
  }
}

// 根据权限表校验权限
const checkPremission = ({to, next}) => {
  // 根据具体数据格式来校验
  if (state.premissions.includes(to.path)) {
    next()
  } else {
    next('/403')
  }
}

const routes = [
  {
    path: '/home',
    component: Home,
    meta: {
      intercepts: [
        getUserDetailOnce,
        getPremissionsOnce,
        checkPremission,
      ]
    }
  },
  {
    path: '/about',
    component: About,
    meta: {
      intercepts: [
        getUserDetailOnce,
        getPremissionsOnce,
        checkPremission,
      ]
    }
  },
  {
    path: '/productDescription',
    // 功能介绍页面,可以不拉取用户信息,权限
    component: ProductDescription,
    meta: {
      intercepts: []
    }
  },
  {
    path: '/login',
    // 如果能正常获取用户信息,应该直接切换到首页
    component: Login,
    meta: {
      intercepts: [
        getUserDetailOnce
      ]
    }
  }
]

以上流程,如果用户从 /home 切换到 /about 不会2次拉取用户信息、用户权限接口,虽然两个路由拦截配置是相同的,而且可以任意调换函数执行顺序

其他

作者:基础建设组-金麦郎