# Vue开发菜单权限与按钮权限管理

### 1.修改国际化语言为中文

```js
//     main.js
Vue.use(ElementUI)
```

### 2.去除多余路由

```js
// # router/index.js
// # 保留 login, dashboard
```

### 3.关闭 Eslint 校验

```js
// vue.config.js
lintOnSave: false,
```

### 4.配置为自己的接口

```js
// vue.config.js 中注释掉 mock接口， 添加自己的接口地址(跨域模式)

    proxy: {
      //配置跨域
      '/api': {
        // target: "https://demo.it98k.cn",
        target: "http://localhost:8000",
        // ws:true,
        changOrigin: true,
        pathRewrite: {
          '^/api': '/'
        }
      }
    },
    // before: require('./mock/mock-server.js')



// .env.development  修改 VUE_APP_BASE_API 为代理地址
VUE_APP_BASE_API = '/api'
```

### 4.配置为自己的请求路径

* src/api 目录下新建 index.js

```js
import request from '@/utils/request'

// 账号密码登陆接口
export function login(data) {
    return request({
        url: '/api/v1.0/auth/login',
        method: 'post',
        data
    })
}
// 获取用户详情
export function getInfo(data) {
    return request({
        url: '/api/v1.0/user/info',
        method: 'get',
        data
    })
}


// 获取所有的菜单接口
export function getMenusRouter() {
    return request({
        url: '/api/v1.0/menus',
        method: 'get',
    })
}
```

```js
// src/store/modules/user.js 文件内
// import { logout,getInfo, logout } from '@/api/user' 注释
import { login, getInfo, getMenusRouter } from '@/api/index'
```

### 5.修改状态码和 Token 方式

```js
// src/utils/requests.js
config.headers['X-Token'] = getToken()
2000 ---> 200
```

### 6.登录接口数据

```js
{
    "code": 200,
    "data": {
        "token": "eyJhbGciOiJIUzUxMiIsImlhdCI6MTY0OTI0MDc0MSwiZXhwIjoxNjQ5MjUwNzQwfQ.eyJpZCI6MX0.g8o6EJ24MaXTJflX2PKlrMhytbEx3tqsfAHKy8j4cd5ATEA2quz2Z5dw71avAZCV-yTV_uOtHOMeIc6GF3OGFg"
    },
    "msg": "ok"
}
```

### 7.个人信息接口数据

```js
{
    "code": 200,
    "data": {
        "avatar": "http://r9uo1b8p9.hn-bkt.clouddn.com/20220405142630802.jpg",
        "description": "超级管理员",
        "id": 1,
        "username": "admin"
    },
    "msg": "ok"
}
```

### 8.菜单渲染接口数据

```js
{
    "code": 200,
    "data": [
        {
            "children": [
                {
                    "component": "system/menus/index",
                    "icon": "el-icon-platform-eleme",
                    "id": 2,
                    "is_enabled": true,
                    "is_show": true,
                    "meta": {
                        "icon": "el-icon-platform-eleme",
                        "title": "菜单管理"
                    },
                    "name": "menus",
                    "path": "/system/menus",
                    "pid": 1,
                    "roles": [
                        {
                            "icon": "el-icon-platform-eleme",
                            "id": 5,
                            "is_enabled": true,
                            "is_show": true,
                            "permissions": "add",
                            "pid": 2,
                            "sort": 1,
                            "title": "新增",
                            "type": 3
                        },
                        {
                            "icon": "el-icon-platform-eleme",
                            "id": 6,
                            "is_enabled": true,
                            "is_show": true,
                            "permissions": "edit",
                            "pid": 2,
                            "sort": 2,
                            "title": "编辑",
                            "type": 3
                        }
                    ],
                    "sort": "1",
                    "title": "菜单管理",
                    "type": 2
                },
                {
                    "component": "system/users/index",
                    "icon": "el-icon-platform-eleme",
                    "id": 3,
                    "is_enabled": true,
                    "is_show": true,
                    "meta": {
                        "icon": "el-icon-platform-eleme",
                        "title": "用户管理"
                    },
                    "name": "users",
                    "path": "/system/users",
                    "pid": 1,
                    "roles": [],
                    "sort": "2",
                    "title": "用户管理",
                    "type": 2
                },
                {
                    "component": "system/roles/index",
                    "icon": "el-icon-platform-eleme",
                    "id": 4,
                    "is_enabled": true,
                    "is_show": true,
                    "meta": {
                        "icon": "el-icon-platform-eleme",
                        "title": "角色管理"
                    },
                    "name": "roles",
                    "path": "/system/roles",
                    "pid": 1,
                    "roles": [],
                    "sort": "3",
                    "title": "角色管理",
                    "type": 2
                }
            ],
            "component": "Layout",
            "icon": "el-icon-platform-eleme",
            "id": 1,
            "is_enabled": true,
            "is_show": true,
            "meta": {
                "icon": "el-icon-platform-eleme",
                "title": "系统管理"
            },
            "path": "/system",
            "pid": 0,
            "redirect": "0",
            "sort": "1",
            "title": "系统管理",
            "type": 1
        }
    ],
    "msg": "ok"
}
```

### 9.实现菜单渲染

#### 9.1 导入组件方式设置

* src/router 目录下创建两个文件

```js
[root@k3s-master router]# pwd
/usr/local/src/vue-admin-template/src/router
[root@k3s-master router]# tree
.
├── _import_development.js
├── _import_production.js
└── index.js
```

```js
// _import_development.js
// 开发环境导入组件
module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+


// _import_production.js
// 生产环境导入组件
module.exports = file => () => import('@/views/' + file + '.vue')
```

#### 9.2 设置请求菜单接口

```js
// src/store/modules/user.js
const mutations = {
'''略，添加如下存储
  SET_MENU: (state, menus) => {
    state.menus = menus
  }
}

// 获取菜单，调用的接口
  getMenusRouter({ commit, state }) {
    return new Promise((resolve, reject) => {
      getMenusRouter().then(response => {
        const { data } = response

        data.push({
          path: "/404",
          component: "404",
          hidden: true
        }, {
          path: "*",
          redirect: "/404",
          hidden: true
        })

        commit('SET_MENU', data)
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },


// src/permission.js ， 获取个人信息后，请求菜单数据
.....
          await store.dispatch('user/getInfo')

          // get user menus (下面新增)
          await store.dispatch('user/getMenusRouter')
          if (store.getters.menus < 1) {
            global.antRouter = []
            next()
          }

          const menus = filterAsyncRouter(store.getters.menus) //过滤路由
          router.addRoutes(menus) //动态添加路由
          global.antRouter = menus //将路由数据传递给全局变量，做侧边栏渲染的工作
          next({ ...to, replace: true }) //正常走
......
```

#### 9.3 处理后端返回的菜单数据

* 小计： 如果不知道数据渲染格式的话，可以去 \*\*router/index.js \*\* 里查看摸版路由的格式

```js
// src/permission.js 
//  遍历后台传来的路由菜单数据，转换为组件对象
import Layout from "@/layout";
const _import = require('./router/_import_' + process.env.NODE_ENV) // 获取组件的方法

function filterAsyncRouter(asyncRouterMap) {
  const accessedRouters = asyncRouterMap.filter(route => {
    if (route.component) {
      if (route.component === 'Layout') {
        route.component = Layout
      } else {
        try {
          route.component = _import(route.component) // 导入组件
        } catch (error) {
          // route.component = _import('system/menus/index') // 导入组件
          Message.error('请查看控制台修改或者删除不存在的组件路径') //弹出异常('请修改或者删除不存在的组件路径')
        }
      }
    }
     // 判断是否有子级目录和长度是否大于0， 并且不是按钮(type=3 代表按钮)
    if (route.children && route.children.length && route.children.type != 3) {
      route.children = filterAsyncRouter(route.children)
    }


    return true
  })

  return accessedRouters
}
```

#### 9.5 修改菜单渲染方式

```js
// src/layout/components/Sidebar/index.vue
      // return this.$router.options.routes 注释，修改为如下
      return this.$router.options.routes.concat(global.antRouter);
```

#### 9.6 添加组件

```js
// src/views/
[root@k3s-master views]# tree system
system
├── menus
│   └── index.vue
├── roles
│   └── index.vue
└── users
    └── index.vue

// index.vue 内容如下
<template>
  <div>menus roles users</div>
</template>

```

#### 9.7 效果如下

![](/files/g0E0oQhkun4nzwVHdaPa)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://close.gitbook.io/yun-wei-bi-ji/centos/vue/vue-kai-fa-cai-dan-quan-xian-yu-an-niu-quan-xian-guan-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
