Vue3添加动态路由及项目搭建

这篇具有很好参考价值的文章主要介绍了Vue3添加动态路由及项目搭建。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

安装项目

yarn create vite vue3-project

安装依赖包

yarn add @types/node -D

在tsconfig.json中配置别名

 "baseUrl": "./",
    "paths": {
      "@/*":["src/*"]
    },

在vite中进行配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
导入resolve
import {resolve} from 'path'
配置resolve
export default defineConfig({
  plugins: [vue()],
  resolve:{
    alias:{
      "@":resolve(__dirname,'./src')
    }
  },
})

安装elementUi-Plus

  1. 下载依赖包
 yarn add element-plus
  1. 完整引入
    在项目入口文件main.js
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')
  1. 按需导入
    • 首先安装依赖包
npm install -D unplugin-vue-components unplugin-auto-import
  • 在项目入口文件main.js
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],

静态路由搭建

  1. 安装依赖
yarn add vue-router
  1. 路由表搭建
import {RouteRecordRaw,createRouter, createWebHashHistory} from 'vue-router';
const routes:Array<RouteRecordRaw> = [
    {
        path:'/login',
        component:()=>import('@/views/Login.vue')
    },
    {
        path:'/',
        redirect:'/homg'
    },
    {
        path:'/home',
        component:()=>import('@/views/HomePage.vue')
    }
]
const router = createRouter({
    routes,
    history:createWebHashHistory()
})
export default router
  1. main.js中配置
import { createApp } from 'vue'
import App from '@/App.vue'
import 'element-plus/dist/index.css'
import router from '@/router/index'
const app = createApp(App)
app.mount('#app')
app.use(router)

  1. axios二次封装
import axios,{AxiosError, AxiosResponse, InternalAxiosRequestConfig} from 'axios';
const newAxios = axios.create({
    baseURL:'http://www.zhaijizhe.cn:3005',
    timeout:5000
})
newAxios.interceptors.request.use((config:InternalAxiosRequestConfig)=>{
    const token = localStorage.getItem('token')
    if(token){
        config.headers.Authorization = token
    }
    return config
})
newAxios.interceptors.response.use((response:AxiosResponse)=>{
    return response
},(error:AxiosError)=>{
    return Promise.reject(error)
})
export default newAxios

请求的类型限制为:InternalAxiosRequestConfig
响应的类型限制为:AxiosResponse

  1. 添加路由守卫
router.beforeEach(async(to,from,next)=>{
    if(to.path == '/login'){
        next()
    }else{
        const token = localStorage.getItem('token')
        if(!token){
            ElMessage.warning('用户未登录,请登录')
            next('/login')
        }else{
            try {
                await $api.user.getMenus()
                 dynamicRoute()
                next()
            } catch (error) {
                ElMessage.warning('token已失效,请重新登录')
                next('/login')
            }
        }
    }
})

动态路由搭建

  1. 定义路由的接口
export interface IUserMenu{
    _id:string,
    title:string,
    pid:string,
    path:string,
    icon:string,
    children:Array<IUserMenu>
}
export interface StateType{
    permissionList:Array<IUserMenu>
}

路由是数组所以定义为Array

  1. 安装pinia
yarn add pinia
  1. 创建store的模块
1. 导入defineStore
import {defineStore} from 'pinia'
2. 导入路由限定接口
import { stateType} from 'type地址'
3. 导入api
import $api from 'api地址'
4. 导入路由类型限制
import {RouteRecordRaw} from 'vue-router'
  - RouteRecordRaw是Vue Router v4.x中新增的一种路由配置类型,可以使得我们在编写路由时更加方便灵活。它定义在@vue/router中,并且支持使用TypeScript类型推断
5. 导入动态获取一组文件符合特定模式的模块getViews方法
import {getViews} from '@/utils/getViews.ts'
6. 创建仓库
const store = defineStore('auth',{
      state:():stateType=>{
        return {
          permissionList:[]
        }
      }
})
7. 根据action异步获取菜单路由
actions:{
  async getAuthMenuAsync(){
    const result = await $api.user.getMenus()
    this.permissionList = result.data.data
  }
}
8. 通过getters获取动态路由
getters:{
  getHomeRoute(state:StateType){
    let homeRouteObj:RouteRecordRaw = {
      path:'/home',
       component:()=>import('../../views/HomePage.vue'),
      children:[]
    }
    // 定义一个数组用来存放子菜单的路由
    let arr:Array<RouteRecordRaw>=[]
   //  添加判断解决首次进入token失效,路由没有跳转的问题
    if(state&&state.permissionList){
            state.permissionList.forEach(item=>{
                if(item.children){
                    item.children.forEach(subItem=>{
                        let routeItem ={
                            path:subItem.path,
                            component:getViews((`../views${subItem.path}.vue`))
                        }
                        ary.push(routeItem)
                    })
                }
            })
           }
    // 将定义的数组赋值给路由对象中的子路由
    homRouteObj.children = arr
    return homRouteObj
  }
}

因为getters可以直接获取状态,action主要是用于异步操作和业务逻辑的处理

  1. 安装pinia持久化插件
yarn add pinia-plugin-persist
  • 在store的user模块中配置persist
const useAuthStore = defineStore('auth', {
    state: (): StateType => { },
    getters:{},
    actions:{},
    persist:{
        enabled:true,
        strategies:[
            {
                key:'userAuth',
                storage:localStorage
            }
        ]
    }
})

这时会报错,需要在tsconfig.json中将 “moduleResolution”: “node”,改为node

  • 在仓库的入口文件中配置插件
import {createPinia} from 'pinia';
import piniaPluginPersist from 'pinia-plugin-persist'
const pinia = createPinia()
pinia.use(piniaPluginPersist)
export default pinia
  1. 在utils文件中创建动态路由添加的方法
1. 导入useAuthStore仓库
import useAuthStore from '@/store/modules/user'
2. 导入路由
import router from '@/router/index'
3. 编写方法
 const dynamicRoute = ()=>{
    const store = useAuthStore()
    - 将异步获取菜单权限的方法结构出来
    const {getAuthMenuAsync} = store
    - 调用异步方法
    getAuthMenuAsync()
    - 调用获取路由的方法
    const homeRoute= store.getDynicRoute
    - 将获取的路由添加到路由
    router.addRoute(homeRoute)
}
  1. 在utils文件中创建动态获取Component的方法
export const getViews(path:string){
   let modules = import.meta.glob('../**/*.vue')
   return modules[path]
}

import.meta.glob是ES2020的一个新特性,用于动态获取一组文件符合特定模式的模块,返回一个键/值对象形式的Promise。可以使用import.meta.glob将所有以.vue结尾的文件导入为模块,并且可以使用for…in循环遍历得到每个匹配到的路径,再通过动态导入对应的组件进行处理。

  1. 在路由守卫中调用utils中动态获取路由的方法
1. 导入动态获取路由的方法
import dynamicRoute from '@/utils/dynicRoute'
2. 导入路由的限制类型
import {RouteRecordRaw,createRouter,createWebHistory} from 'vue-router'
3. 导入api
import $api from '@/api/index'
4. 导入elmessage
import { ElMessage } from 'element-plus'
5. 导入动态路由
import dynamicRoute from '@/utils/dynicRoute'
6. 创建路由表
const routes: Array<RouteRecordRaw> = [
    {
        path: '/login',
        component: () => import('@/views/Login.vue')
    },
    - 设置路由重定向
    {
        path: '/',
        redirect: '/home'
    }
]
7. 创建路由
const router = createRouter({
    history: createWebHistory(),
    routes
})
8. 添加路由守卫
router.beforeEach(async (to, _, next) => {
    if (to.path == '/login') {
        next()
    } else {
        const token = localStorage.getItem('token')
        if (!token) {
            ElMessage.warning('用户未登录,请登录')
            next('/login')
        } else {
            try {
                await $api.user.getMenus()
                - 调用动态获取路由的方法
                dynamicRoute()
                next()
            } catch (error) {
                ElMessage.warning('token已失效,请重新登录')
                next('/login')
            }
        }
    }
})
9. 导出路由
export default router

创建菜单组件

  1. 创建路由限制接口 IUserMenu
export interface IUserMenu{
    _id:string,
    title:string,
    pid:string,
    path:string,
    icon:string,
    children:Array<IUserMenu>
}
  1. 导入Mounted生命周期和ref
import { onMounted,red} from 'vue'
  1. 导入Api
import $api from 'api地址'
  1. 声明Menus数据变量
const Menus = ref<Array<IUserMenu>>([])
  1. 创建动态获取用户菜单
const getMenus = async () => {
    const result = await $api.user.getMenus()
    Menus.value = result.data.data
    dynamicRoute()
}
  1. 挂载方法
onMounted(() => {
    getMenus()
})
  1. 菜单的模板
  • 如果要让elementplus的menu菜单启用vu-router路由模式,需要在el-menu标签中设置:router=“true”
- 在Home的el-main区域内容配置二级路由出口
<template>
    <div>
        <el-menu :router="true" class="elMenu" background-color="#545c64">
            <el-sub-menu v-for="item in Menus" :key="item._id" :index="item._id">
                <template #title>
                    <el-icon>
                        <component :is="item.icon"></component>
                    </el-icon>
                    <span>{{ item.title }}</span>
                </template>
                <el-menu-item v-for="subItem in item.children" :key="subItem._id" :index="subItem.path">
                    <template #title>
                        <span>{{ subItem.title }}</span>
                    </template>
                </el-menu-item>
            </el-sub-menu>
        </el-menu>
    </div>
</template>

其中渲染icons图标使用动态组件component, #title是v-slot的缩写

main.js中进行路由的配置

  1. 导入createApp和App组件
import { createApp } from 'vue'
import App from '@/App.vue'
  1. 导入路由
import router from '@/router/index'
  1. 导入Element相关配置
import 'element-plus/dist/index.css'
import ElementPlus from 'element-plus'
- 导入element中的icon
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
  1. 导入动态获取路由的方法
import dynamicRoute from '@/utils/dynicRoute'
  1. 导入仓库入库文件
import pinia from '@/store'
  1. 使用pinia,ElementPlus,router并且挂载app
const app = createApp(App)
// 循环遍历elementUI的icon
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}
app.use(pinia)
app.use(ElementPlus)
dynamicRoute()
app.use(router)
app.mount('#app')

一定要注意动态路由的添加必须放在app.use(router)之前,app.use(pinia)之后文章来源地址https://www.toymoban.com/news/detail-448954.html

到了这里,关于Vue3添加动态路由及项目搭建的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue-create 创建 VUE3项目-创建

    1.创建文件夹右键点击打开终端或目录cmd  2.输入命令 vue create (这里跟的是项目的名称 不能为或带中文)  3.选中第三个类别自定义创建项目              //   或者选择第一个快捷创建VUE3 进入第12步 4.我们可以按上下键,然后按空格键选中需要的选项,最后按回车

    2024年02月03日
    浏览(56)
  • 【前端Vue】Vue3+Pinia小兔鲜电商项目第4篇:静态结构搭建和路由配置,1. 准备分类组件【附代码文档】

    Vue3+ElementPlus+Pinia开发小兔鲜电商项目完整教程(附代码资料)主要内容讲述:认识Vue3,使用create-vue搭建Vue3项目1. Vue3组合式API体验,2. Vue3更多的优势,1. 认识create-vue,2. 使用create-vue创建项目,1. setup选项的写法和执行时机,2. setup中写代码的特点。什么是pinia,创建空Vue项目并安装

    2024年04月11日
    浏览(50)
  • 【vue create】一.使用vue creat搭建项目

    场景 :使用vue create脚手架快速搭建vue的项目 前提 :需要安装node.js和cnpm以及yarn 并且cnpm需要设置为淘宝镜像,cnpm和yarn安装教程网上很多可以自行搜索 查看安装的版本(显示版本号说明安装成功) 1.cmd窗口跳到需要新建项目的文件夹下,使用vue create 2.我这里选择第三个Ma

    2024年02月06日
    浏览(38)
  • 基于vscode实现vue3项目创建启动+安装配置路由vue-router实现单页面组件切换

    访问https://nodejs.org/en,点击下载最新版本的nodejs,并安装。 在项目目录文件下,通过cmd运行下述指令。 依次输入下列命令,启动vue项目 在浏览器中加载http://localhost:5173/,页面加载成功,说明vue项目安装启动成功。 建议安装第三方库通过vscode中的终端来操作,项目启动通过

    2024年02月03日
    浏览(84)
  • Vue-根据角色获取菜单动态添加路由

    如果大家写过后台管理系统的项目,那么动态路由一定是绕不开的,如果想偷懒的话,就把所有路由一开始都配置好,然后只根据后端返回的菜单列表渲染就好菜单就好了,但是这样的隐患就是我在地址栏输入的地址的时候,也会进入这个页面,不偷懒的方法就是本文要介绍

    2024年01月24日
    浏览(77)
  • Vue3+Vite+Pinia+Naive项目搭建之二:scss 的安装和使用

    前言 如果对 vue3 的语法不熟悉的,可以移步 Vue3.0 基础入门,快速入门。 github 开源库:Vue3-Vite-Pinia-Naive-Js gitee   开源库:Vue3-Vite-Pinia-Naive-Js 1. 安装依赖  2. 新增 src/assets/style/reset.scss 页面样式初始化 3. 新增 src/assets/style/common.scss 共用样式 4. 新增 src/assets/style/utils.scss 工

    2024年02月12日
    浏览(57)
  • Vue2中根据权限添加动态路由

    大概记录一下主要代码 大概结构如下:

    2024年02月12日
    浏览(38)
  • vue实现动态路由添加(简单无废话版本)

    最近练习vue的项目,有关于后台管理系统的动态添加路由部分,根据思路实现了基本的功能,在这里记录一下,等后面学习后在进行优化。 这里只是记录我个人最后实现的思路,本人由于是初学者,可能思路和代码有不正确地方,还求多见谅。也请能不吝赐教,一同进步。 我

    2023年04月08日
    浏览(37)
  • Vue3动态路由(Vite+Vue3+TS+Mock)

    Vue通过路由进行页面管理,不同的路由绑定到不同的页面。一般来说,前端直接写好的路由为静态路由,在不修改代码的情况下,路由表是不会改变的。对于不需要动态改变路由表的网站,静态路由就已经足够了,但是当页面需要与权限进行绑定时,不同用户允许浏览的页面

    2024年02月02日
    浏览(123)
  • vue3实现动态菜单和动态路由和刷新后白屏处理

    项目中,当每一个角色得到的界面不一致的时候,我们就不能使用静态菜单了,而是要从后端得到动态的菜单数据,然后动态的将菜单数据展示在界面上。 除了在界面展示,也还要将界面的路由动态添加,在路由动态添加之后,你可能会出现刷新界面,界面变白的情况,页面

    2024年02月06日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包