> 文章列表 > VUE3项目实现动态路由demo

VUE3项目实现动态路由demo

VUE3项目实现动态路由demo

文章目录

      • 1、创建vue项目
      • 2、安装常用的依赖
        • 2.1 安装elementUI
        • 2.2 安装axios
        • 2.3 安装router
        • 2.4 安装vuex
        • 2.5 安装store
        • 2.6 安装mockjs
      • 3、编写登录页面以及逻辑
      • 4、编写首页以及逻辑
      • 5、配置router.js
      • 6、配置store.js
      • 7、配置menuUtils.js(动态路由重点)
      • 8、配置main.js
      • 9、编写mock.js
      • 10、项目结构
      • 11、启动:

1、创建vue项目

vue create orkasgb-vue3-app

2、安装常用的依赖

2.1 安装elementUI

npm install element-plus --save

2.2 安装axios

npm i --save axios

2.3 安装router

npm install vue-router

2.4 安装vuex

npm install vuex

2.5 安装store

npm install store

2.6 安装mockjs

// -D表示在开发环境中使用
npm install mockjs -D 

3、编写登录页面以及逻辑

编写登录页面
VUE3项目实现动态路由demo

登录逻辑实现:

/**
* 登录
*/
submitForm() {this.$refs["elForm"].validate((valid) => {if (!valid) return;// 请求后台,验证登录信息this.$axios.post("/test/api/login", "{}").then((resp) => {if (resp.status == "200" && resp.data &&resp.data.code == "200" && resp.data.data.legth != 0) {// 登录成功后,用户信息缓存localStorage.setItem("UserInfor", JSON.stringify(resp.data.data));window.sessionStorage.setItem("UserInfor",JSON.stringify(resp.data.data));this.$message.info(resp.data.message);// 登录成功后,缓存tokenthis.$store.commit("setToken", resp.data.data.token);window.sessionStorage.setItem("token", resp.data.data.token);// 登录成功后,跳转到home页this.$router.replace("/home");} else {this.$message.error("登录失败!");}});});
}

4、编写首页以及逻辑

首页布局:
VUE3项目实现动态路由demo

逻辑:

// 数据来源配置
data() {return {formData: {userInfor: window.sessionStorage.getItem("UserInfor"), // 获取用户信息,直接从sessionStorage中获取,在登录的时候已经保存在sessionStorage中}};
},/**
* 左侧菜单栏,直接通过监听路由,开启el-menu组件中路由模式实现
*/
// 开启el-menu组件中路由模式
<el-menu router="true"></el-menu>
// computed方法可以不断的监听路由变化,并当路由有变化时返回路由,并且computed方法是由缓存的,比watch性能好
computed: {routers() {return this.$store.state.routes;},
},/**
* 退出登录
*/
loginOut() {// 退出登录时,删除缓存的用户信息localStorage.removeItem("UserInfor");// 退出登录时,删除缓存的tokenthis.$store.commit("delToken", "token");// 退出登录时,删除缓存的路由this.$store.commit("initRouters", []);// 退出登录时,跳转到登录页面this.$router.replace("/");
}

5、配置router.js

import { createRouter, createWebHashHistory } from 'vue-router'
/**
* 设置固定的路由,一般是登录页面的路由是固定的
*/
const routes = [{path: "/",name: "login",component: () => import("../components/LoginPage.vue")},{path: "/home",name: "home",component: () => import("../components/HomePage.vue")}
];/**
* 路由配置,比如设置路由模式为hash
*/
const router = createRouter({history: createWebHashHistory(),routes
});export default router;

6、配置store.js

import Vuex from 'vuex'
/**
* vuex是一个状态管理器,比如我们的一些项目信息可以用vuex来管理。
*/
export default new Vuex.Store({
state: {routes: [],// 缓存动态路由token: '' // 缓存token},// 同步执行。
mutations: {// 初始化动态路由initRouters(state, data) {state.routes = data;},// 设置token
setToken(state, token) {state.token = tokensessionStorage.token = token},// 删除token
delToken(state) {state.token = ''sessionStorage.removeItem('token')}
},// 异步执行
actions: {}
})

7、配置menuUtils.js(动态路由重点)

import axios from 'axios'
/**
* 初始化菜单,从后台获取动态菜单
*
* @param {登录ID} logId
* @param {路由} router
* @param {缓存} store
*/
const initMenu = function (logId, router, store) {axios.post("/test/api/menu", { logId: logId }).then((resp) => {console.log(resp);if (resp.status == "200" && resp.data && resp.data.code == "200" && resp.data.data.legth != 0) {// 动态路由请求成功后,将路由格式化成vue能识别的路由形式var fmtRouters = formatRouters(resp.data.data);// 将格式化好的路由添加到router中fmtRouters.forEach(fmtRouter => router.addRoute(fmtRouter));// 缓存格式化好的路由store.commit('initRouters', fmtRouters);}});
}/**
* 格式化动态路由
*
* @param menus 动态路由
*/
const formatRouters = (menus) => {if (menus.legth == 0) {return;}let fmtRouters = [];menus.forEach(menu => {let {name, path, compent, children} = menu;// 递归格式化children路由if (children && children instanceof Array) {children = formatRouters(children);}let fmtRouter = {name: name,path: '/' + path,// 重点,从后台返回的component实际上的一个字符串,vue不认识,需要转化成vue能认识的component,才能跳转页面component: () => import(`@/components/${compent}.vue`), children: children};fmtRouters.push(fmtRouter);});return fmtRouters;
}export default initMenu;

8、配置main.js

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import { ElMessage } from 'element-plus'
// 导入elementUI图标
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// 导入elementUI样式
import 'element-plus/dist/index.css'
// 导入路由
import router from './router/router'
// 导入store缓存
import store from './store/sotre';
// 导入axios,用于发送请求
import axios from 'axios'
// 导入vuex,状态管理
import Vuex from 'vuex'
// 导入自定义的菜单工具
import initMenu from './utils/menuUtils'
// 导入mock
import './mock/mock'const app = createApp(App);
app.use(ElementPlus)
app.use(router)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)
}// 设置全局侗剧,比如在组件中可以使用this.$axios等
app.config.globalProperties.$axios = axios;
app.config.globalProperties.$store = store;
app.config.globalProperties.$message = ElMessage;
app.config.globalProperties.$vuex = Vuex;
app.mount('#app')/**
* 路由守卫,每一次路由跳转都会进入这里。
*/
router.beforeEach((to, from, next) => {// 如果token不存在,也就是没登录,那么直接跳转到登录页const token = window.sessionStorage.getItem("token");if (null == token || !token || token.length == 0) {next();return;}// 如果token存在,就说明登录成功,去初始化菜单initMenu("toney", router, store);next();
});

9、编写mock.js

import Mock from 'mockjs'/**
* 登录验证
*/
Mock.mock("/test/api/login","post",(options)=>{console.log("mock--/test/api/login",options)return Mock.mock({"code":"200","message":"登录成功","data|1":[{"id|+1":334,"name":"@cname","logId":"toney","image":"@image","token":"YUGXSIBXISBXI468327943849OONONON"}]})
})/**
* 获取动态路由
*/
Mock.mock("/test/api/menu","post",(options)=>{console.log("mock--/test/api/menu",options)return Mock.mock({"code":"200","message":"初始化菜单菜单成功!","data":[{"id|+1":100000247,"userId":"1","name":"home","path":"home","compent":"HomePage","children":[{"id|+1":100000247,"userId":"1","name":"name1","path":"compent1Page","compent":"Compent1Page"},{"id|+1":100000247,"userId":"2","name":"name2","path":"compent2Page","compent":"Compent2Page"},{"id|+1":100000247,"userId":"2","name":"name3","path":"compent3Page","compent":"Compent3Page"},{"id|+1":100000247,"userId":"2","name":"name4","path":"compent4Page","compent":"Compent4Page"},{"id|+1":100000247,"userId":"1","name":"name5","path":"compent5Page","compent":"Compent5Page"},{"id|+1":100000247,"userId":"2","name":"name6","path":"compent6Page","compent":"Compent6Page"}]}]})
})Mock.setup({timeout:300})

10、项目结构

VUE3项目实现动态路由demo

11、启动:

VUE3项目实现动态路由demo