在 vue3 中动态路由问题记录

第一种

如果这样子的话需要加上 /* @vite-ignore / ,但是在这样用这行部署服务器上跳转会有问题

component: () => import(/ @vite-ignore */ '../views/' + e.component + '.vue')

第二种

  // 解决跳转问题
  const modeules = imporet.meta.glob('@/views/**/**.vue')
  
  
  component: modules['../views/' + e.component +'.vue']

其实这是vite的原因导致的,他在编译的是没有处理这种情况所以报错

完整代码

addRoute.ts

const pages = import.meta.glob('@/views/**/**.vue')

import router from '@/router/index'
import type { RouteRecord } from 'vue-router'

export interface LoginInfo {
  id?: Number,
  title: String,
  icon: String,
  path?: String,
  name: String,
  component: String,
  children?: [],
}

export function addRoute(list: any[]) {
  list.forEach((menu: { children: any[] }) => {
    if (menu.children) {
      menu.children.forEach((e: any) => {
        if (!e.component) {
          return
        }

        router.addRoute('index', {
          name: e.name,
          path: e.path,
          meta: {
            icon: e.icon,
            title: e.title,
            fatherTitle: menu.title,
            fatherPath: menu.children[0].path,
            dynamic: true
          },
          component: pages['/src/views/' + e.component + '.vue']
        })

        if (e.children.length) {
          addRoute(e.children)
        }
      })
    }
  })

  // console.log(router.getRoutes());

}

export function removeRoute() {
  router.getRoutes().forEach((v: RouteRecord) => {
    if (v.meta.dynamic) {
      router.removeRoute(v.name as string)
    }
  })
}

menus.ts

// @src/store/menus.ts
import { defineStore } from 'pinia'
import { ref } from 'vue';
import { addRoute } from './addRoute'
import { routes } from '@/router/index'
import { getMenuList } from "@/api/login"


interface AddRoute {
  id?: Number,
  title: String,
  icon: String,
  path?: String,
  name: String,
  component: String,
  children?: [],
}

export const useMeanStore = defineStore('mean', () => {

  // 菜单数据
  const menuList = ref([] as AddRoute[])
  // 权限数据
  const permList = ref([])
  // 是否有路由
  const hasRoute = ref(false)
  // 改变路由状态
  function changeRouteStatus(state: any) {
    hasRoute.value = state
    sessionStorage.setItem("hasRoute", state)
  }

  // 设置菜单数据
  function setMenuList(menus: any) {
    let addRouterList = routes.filter(route => !route?.meta?.notDetect)
    menuList.value = [...addRouterList, ...menus]
    // 生成动态路由
    addRoute(menus)
  }
  // 获取菜单
  function getMenu() {
    return getMenuList().then((res: any) => {
      setMenuList(res.data.nav);
      setPermList(res.data.authoritys)
    })
  }

  // 设置权限数据
  function setPermList(authoritys: any) {
    permList.value = authoritys
  }

  return {
    menuList,
    permList,
    hasRoute,
    changeRouteStatus,
    setMenuList,
    setPermList,
    getMenu
  }
})

user.ts

// @src/store/user.ts
import { defineStore } from 'pinia'
import { logout } from '@/api/login'
import { ref } from 'vue';

export const useUserStore = defineStore(
  'user',
  () => {
    const token = ref("")
    const userInfo = ref({})
    function SET_TOKEN(name: string) {
      token.value = name
      localStorage.setItem("token", name)
    }
    function SET_INFO(user: any) {
      userInfo.value = user
    }
    async function remove() {
      await logout()
      localStorage.clear()
      sessionStorage.clear()
      location.reload()
      SET_INFO({})
    }

    return {
      persist: true,
      token,
      userInfo,
      remove,
      SET_TOKEN,
      SET_INFO
    }
  }
)

index.ts

import { useMeanStore } from './menus'
import { useUserStore } from './user'

export { useUserStore, useMeanStore }

router.ts

import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import Layout from '@/components/Layouts/index.vue'

import { useMeanStore } from '@/stores/routes/menus'

import NProgress from 'nprogress'
import '/node_modules/nprogress/nprogress.css'
NProgress.configure({ showSpinner: true })

export const routes = [
  {
    path: '/login',
    name: 'login',
    component: () => import('@/views/login/login.vue'),
    meta: {
      notDetect: true
    }
  },
  {
    path: '/404',
    name: 'NotFound',
    component: () => import('@/views/404/error.vue'),
    meta: {
      title: 'Page not found',
      notDetect: true
    }
  },
  // 所有未定义路由,全部重定向到404页
  {
    path: '/:catchAll(.*)',
    redirect: '/404',
    meta: {
      title: 'Page not found',
      notDetect: true
    }
  },
  {
    path: '/',
    name: 'index',
    component: Layout,
    redirect: '/home',
    title: '首页',
    icon: 'home',
    children: [
      {
        path: '/home',
        name: 'home',
        title: '首页',
        icon: 'el-icon-s-home',
        component: () => import('@/views/home/index.vue'),
        children: [],
      }
    ],
  },
]

const router = createRouter({
  // 刷新时,滚动条位置还原
  scrollBehavior: () => ({ left: 0, top: 0 }),
  history: createWebHashHistory(import.meta.env.BASE_URL),
  // @ts-ignore
  routes
})


router.beforeEach((to, from, next) => {
  NProgress.start()
  let token = localStorage.getItem("token")
  const useMean = useMeanStore()
  // console.log('hasRoute', useMean.hasRoute)
  if (to.meta.notDetect) {
    // 不需要检测的页面 直接放行
    next()
  } else if (!token) {
    // console.log("还没有token!!!")
    next({ path: "/login" })
  } else {
    // console.log("已经有路由了")
    next()
  }
})


router.afterEach(() => {
  setTimeout(() => {
    NProgress.done()
  }, 300)
})
export default router

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值