Vue2动态路由

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

应用场景:

 

一般管理端的菜单栏是根据登录用户角色不同,动态生成的,在vue中我们不止菜单栏需要动态生成,同时我们路由也需要动态生成。

使用到的组件:

组件名称 组件版本 组件作用
axios 1.3.4 用于发送请求获取数据
element-ui 2.15.13 前端ui组件库,制作页面使用
vue-router 3.5.1 vue路由组件
vuex 3.6.2 路由状态管理
mockjs 1.1.0 模拟后台返回数据接口

代码实现:

项目结构:

vue2动态路由,vue.js,javascript,前端,ui,ecmascript

axios相关代码

http.js

import axios from 'axios'
import router from '@/router/index.js'
import ElementUI from 'element-ui'
const request = axios.create({
  // baseURL: 'http://192.168.1.150:8888/'
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
})

request.interceptors.response.use(config => {
  const code = config.data.code
  if (code === 200) {
    return config
  } else {
    ElementUI.Message('服务忙')
    return Promise.reject
  }
}, error => {
  switch (error.response.status) {
    case 404:
      router.push('/404')
      break
    case 500:
      ElementUI.Message('error')
  }
  return Promise.reject
})
export default request

login.js

import request from '@/utils/http.js'

/**
 * 获取验证码
 */
export function code () {
  return request({
    url: '/getCode',
    method: 'get'
  })
}
/**
 * 登录
 */
export function loginAPI (loginInfo) {
  return request({
    url: '/login',
    method: 'post',
    data: {
      loginInfo
    }
  })
}

/**
 * 获取菜单
 */
export function getMenu () {
  return request({
    url: '/sys/getMenu',
    method: 'post'
  })
}

mock.js

import Mock from 'mockjs'

const Random = Mock.Random
const R = {
  code: 200,
  message: '执行成功',
  data: null
}
// 获取验证码
Mock.mock('/getCode', 'get', () => {
  R.data = {
    token: Random.string(32),
    imageUri: Random.dataImage('100x100', '8878')
  }
  return R
})
// 登录
Mock.mock('/login', 'post', (value) => {
  console.log(value)
  R.data = {
    token: 'token'
  }
  return R
})
// 获取菜单栏信息
Mock.mock('/sys/getMenu', 'post', () => {
  const menu = [{
    id: 1,
    title: '系统设置',
    name: 'settings',
    path: '/sys',
    icon: 'el-icon-setting',
    component: '/sys/SysSettings.vue',
    children: [
      {
        id: 2,
        title: '用户管理',
        name: 'user',
        path: '/sys/user',
        component: '/sys/UserInfo.vue',
        icon: 'el-icon-user'
      },
      {
        id: 3,
        title: '角色管理',
        name: 'role',
        path: '/sys/role',
        component: '/sys/RoleInfo.vue',
        icon: 'el-icon-menu'
      },
      {
        id: 4,
        title: '权限管理',
        name: 'menu',
        path: '/sys/menu',
        component: '/sys/MenuInfo.vue',
        icon: 'el-icon-menu'
      }
    ]
  }]
  const role = []
  R.data = { menu, role }
  return R
})

vuex相关代码

menu.js

import Vue from 'vue'
import Vuex from 'vuex'
import { getMenu } from '@/api/login.js'

Vue.use(Vuex)

export default {
  state: {
    menuList: [],
    flag: false
  },
  getters: {
  },
  mutations: {
    updateMenu (state, value) {
      state.menuList = value
    },
    updateFlag (state, value) {
      state.flag = value
    }
  },
  actions: {
    async httpGetMenu (store) {
      const { data } = await getMenu()
      store.commit('updateMenu', data.data.menu)
      store.commit('updateFlag', true)
    }
  }
}

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import menu from '@/store/modules/Menu.js'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    token: ''
  },
  getters: {
  },
  mutations: {
    updateToken (state, value) {
      state.token = value
      localStorage.setItem('token', value)
    },
    restState (stste) {
      stste.token = ''
    }
  },
  actions: {
  },
  modules: {
    namespaced: true,
    menu
  }
})

vue-router

import Vue from 'vue'
import VueRouter from 'vue-router'
import UserLogin from '@/views/UserLogin.vue'
import HomeIndex from '@/views/HomeIndex.vue'
import store from '@/store/index.js'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/login',
    name: 'login',
    component: UserLogin
  },
  {
    path: '/home',
    name: 'home',
    component: HomeIndex,
    children: []
  }

]

const router = new VueRouter({
  routes
})
router.beforeEach(async (to, form, next) => {
  const flag = store.state.menu.flag
  if (!flag) {
    await store.dispatch('httpGetMenu')
    const menuList = store.state.menu.menuList
    for (const i in menuList) {
      if (menuList[i].children) {
        for (let j = 0; j < menuList[i].children.length; j++) {
          const childrenMenu = {
            path: menuList[i].children[j].path,
            name: menuList[i].children[j].name,
            children: []
          }
          childrenMenu.component = () => import('@/views' + menuList[i].children[j].component)
          router.addRoute('home', childrenMenu)
          next({ ...to, replace: true })
        }
      }
    }
  }
  next()
})

// 获取原型对象push函数
const originalPush = VueRouter.prototype.push

// 获取原型对象replace函数
const originalReplace = VueRouter.prototype.replace

// 修改原型对象中的push函数
VueRouter.prototype.push = function push (location) {
  return originalPush.call(this, location).catch(err => err)
}

// 修改原型对象中的replace函数
VueRouter.prototype.replace = function replace (location) {
  return originalReplace.call(this, location).catch(err => err)
}
export default router

home.vue文章来源地址https://www.toymoban.com/news/detail-828484.html

<template>
  <div class="home_root">
    <el-container>
      <el-header
        >物业管理
        <el-dropdown :hide-on-click="false">
          <span class="el-dropdown-link">
            设置<i class="el-icon-arrow-down el-icon--right"></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>个人中心</el-dropdown-item>
            <el-dropdown-item @click.native="loginOut()">退出</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </el-header>
      <el-container>
        <el-aside width="200px">
          <el-col>
            <el-menu
              default-active="2"
              class="el-menu-vertical-demo"
              background-color="#545c64"
              text-color="#fff"
              active-text-color="#ffd04b"
            >
              <el-submenu
                :index="menu.id + ''"
                v-for="menu in menuList"
                :key="menu.id"
              >
                <template slot="title">
                  <i :class="menu.icon"></i>
                  <span>{{ menu.title }}</span>
                </template>
                <el-menu-item
                  :index="children.id + ''"
                  v-for="children in menu.children"
                  :key="children.id"
                >
                  <template slot="title">
                    <div @click="openUri(children.path)">
                      <i :class="children.icon"></i>
                      <span slot="title">{{ children.title }}</span>
                    </div>
                  </template>
                </el-menu-item>
              </el-submenu>
            </el-menu>
          </el-col>
        </el-aside>
        <el-main>
          <router-view></router-view>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
export default {
  computed: {
    menuList () {
      return this.$store.state.menu.menuList
    }
  },
  methods: {
    handleClose (tag) {
      this.tags.splice(this.tags.indexOf(tag), 1)
    },
    openUri (uri) {
      this.$router.push(uri)
    },
    loginOut () {
      console.log('loginOut')
      localStorage.clear()
      sessionStorage.clear()
      this.$store.commit('restState')
      this.$router.push('/')
    }
  }
}
</script>

<style lang="less" scoped>
.home_root {
  padding: 0;
  margin: 0;
  height: 100vh;
}
.el-container {
  padding: 0;
  margin: 0;
  height: 100%;
}
.el-header,
.el-footer {
  background-color: #b3c0d1;
  color: #333;
  text-align: center;
  line-height: 60px;
}

.el-aside {
  background-color: #d3dce6;
  color: #333;
  text-align: center;
  line-height: 200px;
}

.el-main {
  background-color: #e9eef3;
  color: #333;
  // text-align: center;
  // line-height: 160px;
  padding: 0;
}

body > .el-container {
  margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
  line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
  line-height: 320px;
}
.el-dropdown {
  float: right;
}
.el-dropdown-link {
  cursor: pointer;
  color: #060606;
}
.el-icon-arrow-down {
  font-size: 12px;
}
.el-col-24 {
  height: 100%;
  .el-menu {
    height: 100%;
  }
}
</style>

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

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

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

相关文章

  • vue2+antd——实现动态菜单路由功能——基础积累

    最近在写后台管理系统,遇到一个需求就是要将之前的静态路由改为动态路由,使用的后台框架是: vue-antd-admin 然后通过 loadRoutes 方法来实现异步动态路由。 如上图所示,需要在登录接口调用成功后,书写以下的代码: import { loadRoutes } from \\\'@/utils/routerUtil.js\\\'; import { getCodeL

    2024年02月08日
    浏览(27)
  • 前端vue2、vue3去掉url路由“ # ”号——nginx配置

    大家好,我是yma16,本文分享关于vue2、vue3去掉url路由 # 号——nginx配置。 html的 hash模式 HTML的hash模式指的是URL中的锚点部分(#后面的内容)被用于在单个页面中显示不同的内容,而不是导航到不同的页面。例如: 在这个示例中, #about 部分是一个锚点,用于在页面上显示关

    2024年02月11日
    浏览(46)
  • Vue2 +Element-ui实现前端页面

    以一个简单的前端页面为例。主要是利用vue和element-ui实现。 里面涉及的主要包括:新建vue项目、一行多个输入框、页面实现等。   ①首先安装nodejs,这部分在此就不讲啦。 ②然后安装vue-cli: 查看是否安装成功: 安装成功之后就输出vue的版本 ③在cmd窗口新建一个vue2脚手架

    2024年02月16日
    浏览(33)
  • 管理系统的前端模板(vue2+Element UI)

    目录 前言 一、模板展示图 二、获取的方式及操作运行步骤  (一)获取方式 (二)操作步骤  1.下载安装node.js  2.下载完成解压缩后在idea的里面打开终端。 3.输入下载相关依赖的命令 4.运行项目的命令 5.然后把给到的地址浏览器打开就可以了  三、代码的展示(这个点的内

    2024年02月05日
    浏览(42)
  • 【Vue框架】Vue2中Vue.js路由—路由介绍、路由控制组件切换、路由重定向、路由传参、嵌套路由、路由布局(附源码详解)

    Vue Router官方文档 :https://router.vuejs.org/zh/installation.html 使用路由文件: 1.引用vue-router路由js文件 2.创建router对象 3.在vm对象中注册router对象 4.在视图中使用 router-view 标签 第一种传参形式——路由路径进行传参,如:/login?id=20 第二种传参形式——路由占位符进行传参,如:/

    2023年04月08日
    浏览(77)
  • 【前端vue升级】vue2+js+elementUI升级为vue3+ts+elementUI plus

    gogo code 是一个基于 AST (源代码的抽象语法结构树状表现形式)的 JavaScript/Typescript/HTML 代码转换工具,可以用它来构建一个代码转换程序来帮助自动化完成如框架升级、代码重构、多平台转换等工作。 当前 GoGoCode 支持解析和操作如下类型的代码: ○JavaScript(JSX) ○Typescript

    2024年02月12日
    浏览(38)
  • vue2创建项目的两种方式,配置路由vue-router,引入element-ui

    提示:vue2依赖node版本8.0以上 使用@vue/cli脚手架vue create创建 使用vue-cli脚手架vue init webpack创建 1、查看nodejs版本 2、全局安装vue脚手架和webpack脚手架 3、新建vue2项目 创建选项除了,Install vue-router??选择是,其他选择的否 4、安装依赖并启动文件 5、预览 6、目录结构 1、如果安

    2024年04月14日
    浏览(30)
  • 前端2023最全面试题(javaScript、typeScript、vue2、vue3、html、css、uniapp、webpack、vite、react)

    答案:JavaScript中的闭包是一种函数,它有权访问其词法环境的变量和其它函数。这意味着,即使其包含它的函数已经执行完毕,其词法环境仍然存在,因此可以访问其作用域内的变量。 答案:回调函数是在某个特定事件之后执行的函数。在JavaScript中,通常使用回调函数来处

    2024年02月06日
    浏览(40)
  • Vue2路由:手动配置使用路由&路由嵌套、路由动态传参(:参数,query、props)、编程式导航(back、go)、导航守卫

    过了一遍vue2的router,整理一下小结 目录 一、前端路由的概念与原理 1.1 什么是路由 1.2 路由的工作方式 二、vue-router的基本使用 2.1 安装、配置、使用router 2.2 redirect重定向 三、嵌套路由 3.1 声明子路由的规则 3.2 默认子路由 四、动态路由 4.1 动态路由的概念 4.2 动态路由取参方

    2024年02月05日
    浏览(31)
  • 【手机号验证/前端】Vue2+elementUI编写一个手机号验证码登录页面,路由式开发(附完整代码)

    目录 效果图: 一、template部分 二、style样式 三、script部分 1.先对手机号的格式进行一个判断 2.接下来就是表单验证规则rules 3.最后就是methods了 (1)首先我们给获取验证码绑定一个方法 (2)然后封装一个axios接口,方便后面测试联调(这部分每个人封装的都不一样) (3)然

    2024年02月17日
    浏览(33)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包