# DarkM.UI 核心框架
DarkM.UI (opens new window) 是 DarkM 框架的前端核心库,基于 Vue 2.x 和 Element-UI 构建,提供完整的组件体系、状态管理、路由系统和工具函数。
# 📋 框架概述
| 属性 | 说明 |
|---|---|
| 框架名称 | DarkM.UI |
| 版本 | 1.5.0-beta-2.0 |
| 基于 | Vue 2.6 + Element-UI 2.15 |
| 组件数量 | 50+ 个业务组件 |
| Git 仓库 | Woowis/DarkM.UI (opens new window) |
| NPM 包 | darkm-ui |
# 🎯 核心特性
| 特性 | 说明 |
|---|---|
| 丰富的业务组件 | 内置表单、表格、弹窗、选择器、工具栏等 50+ 组件 |
| 基于 Element-UI | 深度集成并扩展,风格统一 |
| 多语言国际化 | 支持中文、英文、日文等多种语言 |
| 灵活的皮肤系统 | 支持多套皮肤切换(Pretty 等) |
| 权限指令体系 | 内置权限指令、全局混入、辅助工具 |
| 高扩展性 | 支持按需引入、二次封装 |
| 完善的表单体系 | 表单校验、弹窗表单、动态表单等 |
| 现代化工程体系 | Vue CLI 4、Sass 主题、ESLint/Prettier |
# 📦 技术栈
# 核心依赖
{
"vue": "^2.6.12",
"vue-router": "^3.4.9",
"vuex": "^3.6.0",
"vue-i18n": "8.9.0",
"element-ui": "^2.15.13"
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 工具库
{
"axios": "^0.21.1",
"dayjs": "^1.10.2",
"lodash": "^4.17.21",
"qs": "^6.9.4",
"store": "^2.0.12",
"screenfull": "^5.1.0",
"nprogress": "^0.2.0"
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 开发工具
{
"@vue/cli-service": "^4.5.10",
"@vue/cli-plugin-babel": "^4.5.10",
"sass": "^1.32.13",
"sass-loader": "^8.0.2",
"eslint": "^6.8.0",
"prettier": "^2.2.1"
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 📁 项目结构
DarkM.UI/
├── packages/
│ ├── components/ # 50+ 业务组件
│ ├── mixins/ # 全局混入
│ ├── skins/ # 主题皮肤
│ ├── locale/ # 多语言配置
│ └── directive/ # 自定义指令
├── src/
│ ├── api/ # API 接口
│ ├── components/ # 应用组件
│ ├── views/ # 页面视图
│ ├── utils/ # 工具函数
│ ├── router/ # 路由配置
│ └── store/ # Vuex 状态
└── public/ # 静态资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 🚀 快速开始
# 安装
npm install -S darkm-ui
1
# 引入
// main.js
import Vue from 'vue'
import DarkMUI from 'darkm-ui'
import 'darkm-ui/dist/darkm-ui.css'
Vue.use(DarkMUI)
1
2
3
4
5
6
2
3
4
5
6
# 使用组件
<template>
<NmButton type="primary" @click="handleClick">点击</NmButton>
<NmForm :model="form" :rules="rules">
<NmForm.Item label="用户名" prop="username">
<NmInput v-model="form.username" />
</NmForm.Item>
</NmForm>
<NmList :data="list" :columns="columns" />
</template>
<script>
export default {
data() {
return {
form: { username: '' },
rules: {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }]
},
list: [],
columns: []
}
},
methods: {
handleClick() {
this.$message.success('点击成功')
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 🎨 组件体系
# 组件命名规范
所有组件统一使用 Nm 前缀,支持两种写法:
Nm + 组件名 = NmButton, NmForm, NmList...
1
# 别名规则
组件名支持驼峰格式和连字符格式两种写法,系统建议使用连字符格式:
| 驼峰格式 | 连字符格式(推荐) | 说明 |
|---|---|---|
NmButton | nm-button | 按钮组件 |
NmDatePicker | nm-date-picker | 日期选择器 |
NmFormDialog | nm-form-dialog | 表单弹窗 |
NmTreeSelect | nm-tree-select | 树形选择器 |
NmColorPicker | nm-color-picker | 颜色选择器 |
转换规则:驼峰命名的大写字母前添加 - 并转小写
<template>
<!-- 两种写法都支持,推荐使用连字符格式 -->
<NmButton>按钮</NmButton>
<nm-button>按钮</nm-button> <!-- 推荐 -->
<NmDatePicker />
<nm-date-picker /> <!-- 推荐 -->
</template>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 组件分类
# 1. 基础组件
| 驼峰格式 | 连字符格式(推荐) | 说明 |
|---|---|---|
NmButton | nm-button | 按钮组件 |
NmInput | nm-input | 输入框 |
NmSelect | nm-select | 选择器 |
NmCheckbox | nm-checkbox | 复选框 |
NmRadio | nm-radio | 单选框 |
NmDatePicker | nm-date-picker | 日期选择器 |
NmUpload | nm-upload | 上传组件 |
# 2. 布局组件
| 驼峰格式 | 连字符格式(推荐) | 说明 |
|---|---|---|
NmBox | nm-box | 布局盒 |
NmFlex | nm-flex | 弹性布局 |
NmContainer | nm-container | 页面容器 |
# 3. 表单组件
| 驼峰格式 | 连字符格式(推荐) | 说明 |
|---|---|---|
NmForm | nm-form | 表单容器 |
NmForm.Item | nm-form-item | 表单项 |
NmFormDialog | nm-form-dialog | 表单弹窗 |
NmFormPage | nm-form-page | 表单页 |
# 4. 列表组件
| 驼峰格式 | 连字符格式(推荐) | 说明 |
|---|---|---|
NmList | nm-list | 数据列表 |
NmListDialog | nm-list-dialog | 列表弹窗 |
NmListPage | nm-list-page | 列表页 |
# 5. 反馈组件
| 驼峰格式 | 连字符格式(推荐) | 说明 |
|---|---|---|
NmDialog | nm-dialog | 对话框 |
NmDrawer | nm-drawer | 抽屉 |
NmMessage | nm-message | 消息提示 |
# 6. 业务组件
| 驼峰格式 | 连字符格式(推荐) | 说明 |
|---|---|---|
NmTreeSelect | nm-tree-select | 树形选择器 |
NmDragSort | nm-drag-sort | 拖拽排序 |
NmColorPicker | nm-color-picker | 颜色选择器 |
NmExcelImport | nm-excel-import | Excel 导入 |
NmFileExport | nm-file-export | 文件导出 |
NmToolbar | nm-toolbar | 工具栏 |
# 🌍 国际化(i18n)
# 支持的语言
| 语言 | 代码 |
|---|---|
| 中文(简体) | zh-CN |
| 英文 | en-US |
| 日文 | ja-JP |
| 中文繁体 | zh-TW |
# 配置语言
import VueI18n from 'vue-i18n'
import zhLocale from 'darkm-ui/lib/locale/lang/zh-CN'
import enLocale from 'darkm-ui/lib/locale/lang/en-US'
const i18n = new VueI18n({
locale: 'zh-CN',
messages: {
'zh-CN': zhLocale,
'en-US': enLocale
}
})
Vue.use(DarkMUI, { i18n: (key, value) => i18n.t(key, value) })
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 切换语言
// 切换为英文
this.$i18n.locale = 'en-US'
1
2
2
# 🎭 皮肤系统
# 内置皮肤
| 皮肤 | 说明 |
|---|---|
pretty | 精美皮肤(默认) |
classics | 经典皮肤 |
# 切换皮肤
// 方法一:使用 API
this.$darkm.setSkin('pretty')
// 方法二:使用组件
<NmSkinToggle />
1
2
3
4
5
2
3
4
5
# 🔐 权限系统
# 权限指令
<template>
<!-- 有权限才显示 -->
<NmButton v-permission="'user:add'">添加用户</NmButton>
<!-- 多个权限之一 -->
<NmButton v-permission="['user:add', 'user:edit']">操作</NmButton>
</template>
1
2
3
4
5
6
7
2
3
4
5
6
7
# 权限判断
export default {
computed: {
canAdd() {
return this.$hasPermission('user:add')
}
},
methods: {
handleAdd() {
if (!this.$hasPermission('user:add')) {
this.$message.error('无权限')
return
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 📡 HTTP 请求
# 封装的 HTTP 方法
import http from 'darkm-ui/src/utils/http'
// GET 请求
http.get('/api/user/list', { params: { page: 1 } })
// POST 请求
http.post('/api/user/add', { name: '张三' })
// PUT 请求
http.put('/api/user/update', { id: 1, name: '李四' })
// DELETE 请求
http.delete('/api/user/delete', { id: 1 })
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# JWT 认证
// 自动添加 Token
http.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 🔧 工具函数
# Assist 辅助函数
import assist from 'darkm-ui/src/utils/assist'
// 类型判断
assist.isString('test')
assist.isNumber(123)
assist.isArray([])
assist.isObject({})
// 深拷贝
const copy = assist.deepClone(obj)
// 防抖
const debouncedFn = assist.debounce(() => {}, 300)
// 节流
const throttledFn = assist.throttle(() => {}, 1000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Day.js 日期处理
import dayjs from 'dayjs'
// 格式化
dayjs().format('YYYY-MM-DD HH:mm:ss')
// 相对时间
dayjs('2022-08-07').fromNow() // "2 天前"
1
2
3
4
5
6
7
2
3
4
5
6
7
# 📊 状态管理(Vuex)
# Store 结构
// src/store/index.js
export default new Vuex.Store({
state: {
user: null,
token: '',
menus: [],
permissions: []
},
mutations: {
SET_USER(state, user) {
state.user = user
},
SET_TOKEN(state, token) {
state.token = token
}
},
actions: {
async login({ commit }, credentials) {
const res = await loginApi(credentials)
commit('SET_TOKEN', res.data.token)
commit('SET_USER', res.data.userInfo)
}
},
getters: {
userId: state => state.user?.id,
userName: state => state.user?.name,
isLoggedIn: state => !!state.token
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 使用 State
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['userId', 'userName', 'isLoggedIn'])
},
methods: {
async handleLogin() {
await this.$store.dispatch('login', {
username: 'admin',
password: '123456'
})
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 🛠️ 开发环境
# Node 版本管理
# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# 安装 Node 14
nvm install 14
# 使用 Node 14
cd DarkM.UI
nvm use
# 验证版本
node -v # v14.x
npm -v # 6.14.18
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 开发命令
# 安装依赖
npm install
# 本地开发
npm run serve
# 构建生产
npm run build
# 代码检查
npm run lint
# 发布到 NPM
npm run pub
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 📚 相关文档
# 🔗 参考链接
最后更新: 2022-08-07