返回

Vue搭建用户验证+权限验证+动态路由(侧边栏菜单)

前端

项目初始化

  1. 安装Vue.js和相关依赖项
npm install vue vue-router vuex element-ui
  1. 创建项目目录结构
├── package.json
├── src
│   ├── App.vue
│   ├── main.js
│   ├── router
│   │   ├── index.js
│   │   ├── routes.js
│   ├── store
│   │   ├── index.js
│   │   ├── modules
│   │   │   ├── user.js
│   │   │   └── permission.js
│   ├── components
│   │   ├── Sidebar.vue
│   │   └── Login.vue
│   ├── views
│   │   ├── Home.vue
│   │   ├── About.vue
│   │   └── Admin.vue
│   ├── assets
│   │   ├── logo.png
│   │   └── style.css
│   ├── index.html
  1. 配置Vuex
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    user: null,
    permissions: []
  },
  mutations: {
    setUser (state, user) {
      state.user = user
    },
    setPermissions (state, permissions) {
      state.permissions = permissions
    }
  },
  actions: {
    login ({ commit }, user) {
      // 模拟登录请求
      setTimeout(() => {
        commit('setUser', user)
        commit('setPermissions', ['admin'])
      }, 1000)
    },
    logout ({ commit }) {
      // 模拟登出请求
      setTimeout(() => {
        commit('setUser', null)
        commit('setPermissions', [])
      }, 1000)
    }
  },
  getters: {
    isLoggedIn: state => !!state.user,
    hasPermission: state => permission => state.permissions.includes(permission)
  }
})

用户验证实现

// components/Login.vue
<template>
  <div class="login-form">
    <form @submit.prevent="onSubmit">
      <div class="form-group">
        <label for="username">Username</label>
        <input type="text" id="username" v-model="username">
      </div>
      <div class="form-group">
        <label for="password">Password</label>
        <input type="password" id="password" v-model="password">
      </div>
      <button type="submit">Login</button>
    </form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    onSubmit() {
      this.$store.dispatch('login', {
        username: this.username,
        password: this.password
      })
    }
  }
}
</script>

权限验证实现

// router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const router = new VueRouter({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/about',
      name: 'About',
      component: About
    },
    {
      path: '/admin',
      name: 'Admin',
      component: Admin,
      meta: {
        requiresAuth: true,
        permissions: ['admin']
      }
    }
  ]
})

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !store.getters.isLoggedIn) {
    next('/')
  } else if (to.meta.permissions && !to.meta.permissions.every(permission => store.getters.hasPermission(permission))) {
    next('/')
  } else {
    next()
  }
})

export default router

动态路由实现

// router/routes.js
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import Admin from '../views/Admin.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  {
    path: '/admin',
    name: 'Admin',
    component: Admin,
    meta: {
      requiresAuth: true,
      permissions: ['admin']
    }
  }
]

export default routes
// store/modules/permission.js
import Vue from 'vue'

export default {
  state: {
    routes: []
  },
  mutations: {
    setRoutes (state, routes) {
      state.routes = routes
    }
  },
  actions: {
    generateRoutes ({ commit }, permissions) {
      // 模拟获取路由请求
      setTimeout(() => {
        const routes = [
          {
            path: '/',
            name: 'Home',
            component: Home
          },
          {
            path: '/about',
            name: 'About',
            component: About
          }
        ]

        if (permissions.includes('admin')) {
          routes.push({
            path: '/admin',
            name: 'Admin',
            component: Admin
          })
        }

        commit('setRoutes', routes)
      }, 1000)
    }
  },
  getters: {
    getRoutes: state => state.routes
  }
}

侧边栏菜单实现

// components/Sidebar.vue
<template>
  <nav class="sidebar">
    <ul>
      <li v-for="route in routes" :key="route.name">
        <router-link :to="route.path">{{ route.name }}</router-link>
      </li>
    </ul>
  </nav>
</template>

<script>
export default {
  computed: {
    routes() {
      return this.$store.getters['permission/getRoutes']
    }
  }
}
</script>

完整代码示例

// App.vue
<template>
  <div id="app">
    <Sidebar />

    <div class="main-content">
      <router-view />
    </div>
  </div>
</template>

<script>
import Sidebar from './components/Sidebar.vue'

export default {
  components: {
    Sidebar
  }
}
</script>

// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

总结和参考

本文介绍了如何使用Vue.js构建用户验证、权限验证和动态路由(侧边栏菜单)的功能。这篇文章涵盖了技术栈说明、项目初始化、用户验证实现、权限验证实现、动态路由实现、侧边栏菜单实现、完整代码示例以及总结和参考,提供了一个清晰且全面的指南,帮助您轻松实现Vue中的用户验证、权限验证和动态路由功能。

参考: