⚡个人资料
v3-admin 是中后端管理系统的基本解决方案,基于 Vue3、TypeScript、Element-Plus 和 Vue-Cli 4.5
1️⃣ 功能
- 用户管理
- 登录
- 注销
- 权限验证
- 页面权限
- 指令权限
- 多环境
- dev
- stage
- prod
- 全局功能
- svg
- 国际化多语言
- 多种动态换肤
- 动态侧边栏(支持多级路由嵌套)
- 动态面包屑
- 快捷导航(标签页)
- Screenfull 全屏
- 自适应收缩侧边栏
- 错误页面
- 401
- 404
- Dashboard
- admin
- editor
2️⃣ 内容
# v3-admin
├─ .env.dev # 开发环境
├─ .env.prod # 生产环境
├─ .env.stage # 预发布环境
├─ .eslintrc.js # eslint
├─ public # 静态资源
│ ├─ favicon.ico # favicon 图标
│ ├─ index.html # html模板
├─ src # 源码
│ ├─ @types # ts 声明
│ ├─ api-inject # 接口(全局注入的方式)
│ ├─ api-import # 接口(import/export 的方式)
│ ├─ assets # 主题、字体、svg等静态资源
│ ├─ components # 全局公用组件
│ ├─ config # 全局配置
│ ├─ constant # 常量/枚举
│ ├─ directives # 全局指令
│ ├─ layout # 全局 layout
│ ├─ locales # 国际化
│ ├─ model # 全局 model
│ ├─ plugins # 插件
│ ├─ router # 路由
│ ├─ store # 全局 store 管理
│ ├─ styles # 全局样式
│ ├─ utils # 全局公共方法
│ └─ views # 所有页面
├─ tsconfig.json # ts 编译配置
└─ vue.config.js # vue-cli 配置
3️⃣ 安装
# 克隆项目
git clone https://github.com/v3-projects/v3-admin
# 进入项目目录
cd v3-admin
# 安装依赖
yarn
# 启动项目
yarn dev
?基础知识
1️⃣路线
配置项
// 默认false,设置 true 的时候该路由不会在侧边栏出现
hidden: true
// 设置 noRedirect 的时候该路由在面包屑导航中不可被点击
redirect: 'noRedirect'
// 设定路由的名字,一定要填写不然重置路由可能会出问题
name: 'router-name'
meta: {
// 设置该路由进入的权限,支持多个权限叠加
roles: ['admin', 'editor']
// 设置该路由在侧边栏和面包屑中展示的名字
title: 'title'
// 设置该路由的图标,记得将 svg 导入 @/assets/svg-icons/icons
icon: 'svg-name'
// 默认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
动态添加。
添加动态路由方式:
案例:例如permission.ts
文件
@/router/asyncModules
下
import { RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
const permissionRouter: Array<RouteRecordRaw> = [
{
path: '/permission',
component: Layout,
name: 'Permission',
redirect: '/permission/directive',
meta: {
title: 'permission',
icon: 'lock',
roles: ['admin', 'editor'], // 可以在根路由中设置角色
alwaysShow: true // 将始终显示根菜单
},
children: [
{
path: 'page',
component: () => import(/* webpackChunkName: "permission-page" */ '@/views/permission/page.vue'),
name: 'PagePermission',
meta: {
title: 'pagePermission',
roles: ['admin'] // 或者在子导航中设置角色
}
},
{
path: 'directive',
component: () => import(/* webpackChunkName: "permission-directive" */ '@/views/permission/directive.vue'),
name: 'DirectivePermission',
meta: {
title: 'directivePermission' // 如果未设置角色,则表示:该页面不需要权限,但会继承根路由的角色
}
}
]
}
]
export default permissionRouter
2️⃣ 发送 HTTP 请求
大致流程如下:
graph LR
页面/交互 --> 统一管理的API --> 封装的service.ts --> 服务器
统一管理API
导入表格
@/api-import/login.ts
/**
* api-import
* 实现:采用 import/export 的方式
* 优点:拥有 TypeScript 类型提示
* 缺点:使用时需要 "import { accountLogin } from '@/api-import/login'" 来导入指导的api
* @see:暂无
*/
import { request } from '@/utils/service'
interface UserRequestData {
username: string
password: string
}
export function accountLogin(data: UserRequestData) {
return request({
url: 'user/login',
method: 'post',
data
})
}
inject形态
@/api-inject/index.ts
/**
* api-inject
* 实现:采用全局注入的方式
* 优点:使用时只需 "import $api from '@/api-inject'" 或者 const $api = inject('$api') 即可方便的通过 $api 调用所有api
* 缺点:丢失了 TypeScript 类型提示
* @see:'@/store/modules/user/actions.ts'
* @see:'@/views/login/index.vue'
*/
import { assign, map } from 'lodash'
import { request } from '@/utils/service'
const files = require.context('./modules', true, /\.ts$/)
const generators = files.keys().map(key => files(key).default)
export default assign({}, ...map(generators, generator => generator(request)))
@/api-inject/modules/sys.api.login.ts
import { AxiosAdapter } from 'axios'
interface UserRequestData {
username: string
password: string
}
export default (request: AxiosAdapter) => {
return {
accountLogin(data: UserRequestData) {
return request({
url: 'user/login',
method: 'post',
data
})
}
}
}
封装服务.ts
@/utils/service.ts
基于axio封装,封装了全局请求拦截器、响应拦截器、统一错误处理、统一超时处理、baseURL设置等。
3️⃣ 更多环境
建筑物
项目开发完成。打包代码时,会嵌入两个环境:
变量
在.env.prod
等.env.xxx
文件中,配置了该环境对应的变量:
# 当前运行的环境
NODE_ENV=production
# 当前环境对应接口的 baseURL
VUE_APP_BASE_API = 'https://www.xxx.com'
获取方式:
console.log(process.env.NODE_ENV)
console.log(process.env.VUE_APP_BASE_API)
4️⃣ 跨域
@/config
文件夹存放一些内置的配置项,如white-list
路由白名单、vue.custom.config
vue.config文件配置等。
vue.custom.config
中有proxy
用于反向代理。
对应的生产环境,可以使用nginx
作为反向代理。
反向代理
const vueDefaultConfig = {
publicPath: './',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: false,
transpileDependencies: ['vue-echarts', 'resize-detector'],
// webpack 配置的项目名称
title: 'v3-admin',
titleSeparator: ' - ',
titleReverse: false,
abbreviation: 'vt2at',
providePlugin: {},
build7z: false,
startMessage:'欢迎使用 v3-admin',
devServer: {
publicPath: '/',
hot: true,
port: '9999',
open: true,
noInfo: false,
overlay: {
warnings: true,
errors: true,
},
// 反向代理
proxy: {
'/api/': {
target: 'http://xxxxxx/api/',
ws: true,
pathRewrite: {
'^/api/': ''
},
changeOrigin: true,
secure: false
}
}
}
}
module.exports = vueDefaultConfig
CORS
该方案对接口的工作量要求不高。和普通的发送请求的写法没有什么区别。工作量基本上都在后端。
实现CORS后,无论是开发环境还是生产环境都可以轻松调用接口。
✈️进阶
标准化代码很重要!
1️⃣ ESLint
- 配置元素:在
.eslintrc.js
文件 - 取消自动验证:
@/config/vue.custom.config.ts
中将lintOnSave
设置为false
- 推荐 VSCode 的 ESlint 插件。它可以在你编写代码时将不符合规范的代码标记为红色,并在保存代码时自动修复一些简单的红色标记代码(VSCode配置ESlint教程可以自行Google一下)
- 手动验证:
yarn lint
(在提交代码之前执行此命令,特别是当 lintOnSave 为 false 时)
2️⃣ Git 挂钩
gitHooks在package.json
中配置,每次使用
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"vue-cli-service lint",
"git add"
]
}
❓常见问题
1️⃣全部错误
Google 可以解决 99% 的错误!
剩下的1%可以进群问我,然后我就偷偷去Google一下!
2️⃣ 依赖失败
- 不要使用cnpm
- 尝试删除node_modules并再次信任它
- Google 一下
3️⃣ 切换路线模式到浏览器历史记录后,刷新后出现空白页面
将@/config/vue.custom.config.ts
文件中publicPath
的值从./
更改为/
☕其他
1️⃣ 站在巨人的肩膀上
- vue-element-admin
- vue3-composition-admin
- d2-admin
- vue-vben-admin
2️⃣交流组(鼓风机)
没人关心的交流群:1014374415
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。