V3 Admin 中文文档

V3 Admin 中文文档V3-Admin 是一个中后台管理系统基础解决方案,基于 Vue3、TypeScript、Element-Plus 和 Pinia

✨ 新版

强烈推荐:基于 vite 的新版本 v3-admin-vite

⚡ 简介

v3-admin 是一个中后台管理系统基础解决方案,基于 Vue3、TypeScript、Element-Plus 和 Pinia。

1️⃣ 功能

- 用户管理
  - 登录
  - 注销
	
- 权限验证
  - 页面权限
  - 指令权限

- 多环境
  - development
  - test
  - production
  
- 全局功能
  - svg
  - 多主题切换(内置黑暗主题)
  - 动态侧边栏
  - 动态面包屑
  - 标签页快捷导航
  - Screenfull 全屏
  - 自适应收缩侧边栏
  - 前端监控(基于 mitojs)

- 错误页面
  - 401
  - 404

- Dashboard
  - admin
  - editor

- 自动部署

2️⃣ 目录

# v3-admin
├─ .env.development   # 开发环境
├─ .env.production    # 生产环境
├─ .env.test          # 测试环境
├─ .eslintrc.js       # eslint
├─ deploy             # 脚本部署
├─ public
│  ├─ favicon.ico
│  ├─ index.html
├─ src
│  ├─ @types          # ts 声明
│  ├─ api             # api 接口
│  ├─ assets          # 静态资源
│  ├─ components      # 全局组件
│  ├─ config          # 全局配置
│  ├─ constant        # 常量/枚举
│  ├─ directives      # 全局指令
│  ├─ icons           # svg icon
│  ├─ layout          # 布局
│  ├─ model           # 全局 model
│  ├─ plugins         # 插件
│  ├─ router          # 路由
│  ├─ store           # pinia store
│  ├─ styles          # 全局样式
│  ├─ utils           # 全局公共方法
│  └─ views           # 所有页面
│  ├─ App.vue         # 入口页面
│  ├─ main.ts         # 入口文件
│  └─ shims.d.ts      # 模块注入
├─ tsconfig.json      # ts 编译配置
└─ vue.config.js      # vue-cli 配置

3️⃣ 安装

# 配置
1. 安装 eslint 插件
2. 安装 volar 插件
3. node v16.x
4. pnpm v6.x

# 克隆项目
git clone https://github.com/un-pany/v3-admin.git

# 进入项目目录
cd v3-admin

# 安装依赖
pnpm i

# 启动项目
pnpm dev

📚 基础

1️⃣ 路由

配置项

// 设置 noRedirect 的时候该路由在面包屑导航中不可被点击
redirect: 'noRedirect'

// 动态路由:必须设定路由的名字,一定要填写不然重置路由可能会出问题
// 如果要在 tags-view 中展示,也必须填 name
name: 'router-name'

meta: {
  // 设置该路由在侧边栏和面包屑中展示的名字
  title: 'title'
  // 设置该路由的图标,记得将 svg 导入 @/icons/svg
  icon: 'svg-name'
  // 默认 false,设置 true 的时候该路由不会在侧边栏出现
  hidden: true
  // 设置该路由进入的权限,支持多个权限叠加
  roles: ['admin', 'editor']
  // 默认 true,如果设置为 false,则不会在面包屑中显示
  breadcrumb: false
  // 默认 false,如果设置为 true,它则会固定在 tags-view 中
  affix: true
  
  // 当一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式
  // 只有一个时,会将那个子路由当做根路由显示在侧边栏
  // 若想不管路由下面的 children 声明的个数都显示你的根路由
  // 可以设置 alwaysShow: true,这样就会忽略之前定义的规则,一直显示根路由
  alwaysShow: true

  // 当设置了该属性,进入路由时,则会高亮 activeMenu 属性对应的侧边栏
  activeMenu: '/dashboard'
}

动态路由

constantRoutes 把不需要判断权限的路由放置在常驻路由里面,如 /login/dashboard

asyncRoutes 放置需要动态判断权限并通过 addRoute 动态添加的路由。

注意:动态路由必须配置 name 属性,不然重置路由时,会漏掉没有该属性的动态路由,可能会导致业务 BUG

2️⃣ 侧边栏和面包屑

侧边栏

sidebar1.png sidebar2.png

侧边栏 @/layout/components/sidebar 是通过读取路由并结合权限判断而动态生成的(换句话说就是常驻路由 + 有权限的路由)

侧边栏外链

可以在侧边栏中配置一个外链,只要你在 path 中填写了合法的 url 路径,当你点击侧边栏的时候就会帮你新开这个页面

{
    path: '/link',
    component: Layout,
    children: [
      {
        path: 'https://github.com/un-pany/v3-admin',
        redirect: '/',
        name: 'Link',
        meta: {
          title: '外链',
          icon: 'link'
        }
      }
    ]
  }

面包屑

breadcrumb.png

面包屑 @/layout/components/bread-crumb 也是根据路由动态生成的,为路由设置 breadcrumb: false 时该路由将不会出现在面包屑中,设置 redirect: 'noRedirect' 时该路由在面包屑中不能被点击

3️⃣ 权限

登录时通过获取当前用户的权限(角色)去比对路由表,生成当前用户具有的权限可访问的路由表,通过 addRoute 动态挂载到 router 上

角色控制权限

控制代码都在 @/router/permission.ts 中,这里可根据具体的业务做响应的修改:

import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import router from '@/router'
import { RouteLocationNormalized } from 'vue-router'
import { useUserStoreHook } from '@/store/modules/user'
import { usePermissionStoreHook } from '@/store/modules/permission'
import { ElMessage } from 'element-plus'
import { whiteList } from '@/config/white-list'
import rolesSettings from '@/config/roles'
import { getToken } from '@/utils/cookies'

const userStore = useUserStoreHook()
const permissionStore = usePermissionStoreHook()
NProgress.configure({ showSpinner: false })

router.beforeEach(async(to: RouteLocationNormalized, _: RouteLocationNormalized, next: any) => {
  NProgress.start()
  // 判断该用户是否登录
  if (getToken()) {
    if (to.path === '/login') {
      // 如果登录,并准备进入 login 页面,则重定向到主页
      next({ path: '/' })
      NProgress.done()
    } else {
      // 检查用户是否已获得其权限角色
      if (userStore.roles.length === 0) {
        try {
          if (rolesSettings.openRoles) {
            // 注意:角色必须是一个数组! 例如: ['admin'] 或 ['developer', 'editor']
            await userStore.getInfo()
            // 获取接口返回的 roles
            const roles = userStore.roles
            // 根据角色生成可访问的 routes
            permissionStore.setRoutes(roles)
          } else {
            // 没有开启角色功能,则启用默认角色
            userStore.setRoles(rolesSettings.defaultRoles)
            permissionStore.setRoutes(rolesSettings.defaultRoles)
          }
          // 动态地添加可访问的 routes
          permissionStore.dynamicRoutes.forEach((route) => {
            router.addRoute(route)
          })
          // 确保添加路由已完成
          // 设置 replace: true, 因此导航将不会留下历史记录
          next({ ...to, replace: true })
        } catch (err: any) {
          // 删除 token,并重定向到登录页面
          userStore.resetToken()
          ElMessage.error(err.message || 'Has Error')
          next('/login')
          NProgress.done()
        }
      } else {
        next()
      }
    }
  } else {
    // 如果没有 token
    if (whiteList.indexOf(to.path) !== -1) {
      // 如果在免登录的白名单中,则直接进入
      next()
    } else {
      // 其他没有访问权限的页面将被重定向到登录页面
      next('/login')
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

取消角色

假如你的业务场景中没有 角色 的概念,那么在 @/config/roles 里可以关闭角色功能,关闭后系统将启用默认角色(一般为最高权限的 admin 角色),即每个登录的用户都可见所有路由

interface RolesSettings {
  // 是否开启角色功能(开启后需要后端配合,在查询用户详情接口返回当前用户的所属角色)
  openRoles: boolean
  // 当角色功能关闭时,当前登录用户的默认角色将生效(默认为admin,拥有所有权限)
  defaultRoles: Array<string>
}

const rolesSettings: RolesSettings = {
  openRoles: true,
  defaultRoles: ['admin']
}

export default rolesSettings

指令权限

简单快速的实现按钮级别的权限判断(已注册到全局,可直接使用):

<el-tag v-permission="['admin']">admin可见</el-tag>
<el-tag v-permission="['editor']">editor可见</el-tag>
<el-tag v-permission="['admin','editor']">admin和editor都可见</el-tag>

但在某些情况下,不适合使用 v-permission。例如:element-plus 的 el-tab 或 el-table-column 以及其它动态渲染 dom 的场景。你只能通过手动设置 v-if 来实现。

这时候可以使用权限判断函数

import { checkPermission } from '@/utils/permission'
<el-tab-pane v-if="checkPermission(['admin'])" label="Admin">admin可见</el-tab-pane>
<el-tab-pane v-if="checkPermission(['editor'])" label="Editor">editor可见</el-tab-pane>
<el-tab-pane v-if="checkPermission(['admin','editor'])" label="AdminEditor">admin和editor都可见</el-tab-pane>

4️⃣ 发送HTTP请求

大致的流程如下:

graph LR
页面/交互 --> 统一管理的API --> 封装的service.ts --> 服务器

统一管理的 API

import 形式

@/api/login.ts

import { request } from '@/utils/service'

interface UserRequestData {
  username: string
  password: string
}

export function accountLogin(data: UserRequestData) {
  return request({
    url: 'user/login',
    method: 'post',
    data
  })
}

封装的 service.ts

@/utils/service.ts 是基于 axios 的封装,封装了全局 request 拦截器、response 拦截器、统一的错误处理、统一做了超时处理、baseURL 设置等。

5️⃣ 多环境

构建

项目开发完成,打包代码时,内置两种环境:

# 打包测试环境
pnpm build:test

# 打包正式环境
pnpm build:prod

变量

.env.production.env.xxx 文件中,配置了该环境对应的变量:

# 当前环境对应接口的 baseURL
VUE_APP_BASE_API = 'https://www.xxx.com'

获取方式:

console.log(process.env.VUE_APP_BASE_API)

✈️ 进阶

1️⃣ ESLint

规范代码很重要!

  • 配置项:在 .eslintrc.js 文件中
  • 取消自动校验:vue.config.js 中将 lintOnSave 设置为 false
  • 推荐 VSCode 的 ESlint 插件,它可在写代码时,将不符合规范的代码标红,并且在你保存代码是自动修复一些简单的标红的代码(VSCode 配置 ESlint 教程可自行 Google)
  • 手动校验:pnpm lint(提交代码前执行该命令,特别是在你 lintOnSave 为 false 的情况下)

2️⃣ Git Hooks

package.json 中配置了 gitHooks,每次 commit 时都将检测代码

"gitHooks": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*.{js,jsx,vue,ts,tsx}": [
      "vue-cli-service lint",
      "git add"
    ]
  }

3️⃣ 跨域

vue.config 里就有 proxy 进行反向代理。

与之对应的生产环境,则可以使用 nginx 来做反向代理。

反向代理

proxy: {
  '/api/': {
     target: 'http://xxxxxx/api/',
     ws: true,
     pathRewrite: {
       '^/api/': ''
     },
     changeOrigin: true,
     secure: false
  }
}

CORS

这种方案对于前端来说没有什么工作量,和正常发送请求写法上没有任何区别,工作量基本都在后端这里。

实现 CORS 之后,不管是开发环境还是生产环境,都能方便的调用接口。

4️⃣ SVG

有全局 @/components/svg-icon 组件,图标存放在 @/icons/svg 即可。

使用方式

无需在页面中引入组件,可直接使用

<!-- name 为 svg 文件名 -->
<!-- class 可修改默认样式 -->
<svg-icon name="user" font-size="20px" class="icon" />

下载 icon

推荐 iconfont

5️⃣ 自动部署

deploy/index.js 文件里填写服务器的 IP、端口、用户名、密码等信息,再执行 pnpm deploy 命令即可自动发布打包好的 dist 文件到对应的服务器

注意:该文件中的用户名密码等信息为敏感信息,勿上传到远程仓库,这一点很重要!

6️⃣ 新增主题(黑暗主题为例)

新增主题样式文件

  • src/style/theme/dark/index.scss
  • src/style/theme/dark/setting.scss

注册新的主题

  • src/style/theme/register.scss
  • src/config/theme.ts

❓ 常见问题

1️⃣ 所有的报错

Google 一下可以解决 99% 的报错

2️⃣ 依赖失败/依赖慢

  • 不要使用 cnpm
  • 推荐用 pnpm
  • 国内用户可以设置最新的淘宝源加快依赖速度
  • 尝试删除 node_modules 和 .lock 文件后再次依赖
  • Google 一下

3️⃣ 路由模式切换为 browserHistory 后,刷新出现空白页面

@/config/vue.custom.config.ts 文件中 publicPath 的值从 ./ 修改为 /

4️⃣ 可有可无的群

QQ群:1014374415

qq.png

今天的文章V3 Admin 中文文档分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/23104.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注