lw-cdp-ui 1.3.49 → 1.3.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,425 +1,90 @@
1
- # 使用
2
1
 
3
- > 组件库与脚手架项目相互依赖
2
+ # lw-ui 组件库文档
4
3
 
5
- - 脚手架地址: https://gitlabcode.lianwei.com.cn/dmcs/imf/ui/lw-ui.git 分支 3.1.x
6
- - 代码说明文档可能更新不及时, 可直接查看源码,获取所有功能。路径: node_modules\lw-cdp-ui\dist\components
4
+ ## 项目简介
7
5
 
6
+ lw-ui是一套基于Vue.js的企业级中后台UI组件库,提供丰富的业务组件和工具,帮助开发者快速构建中后台管理系统。
8
7
 
9
- ## 组件库
10
- ```javascript
8
+ ## 主要特性
9
+
10
+ - 🏗️ **丰富的业务组件**:包含表单、表格、图表、流程设计等业务场景组件
11
+ - 🎨 **主题定制**:支持灵活的主题配置和样式覆盖
12
+ - 🚀 **开箱即用**:提供完整的安装指南和示例代码
13
+ - 📦 **按需加载**:支持组件级按需引入
14
+ - 🌍 **国际化**:内置多语言支持
15
+
16
+ ## 快速开始
17
+
18
+ ### 安装
19
+
20
+ ```bash
11
21
  npm install lw-cdp-ui
12
- // or
22
+ #
13
23
  yarn add lw-cdp-ui
14
24
  ```
15
25
 
16
- ### 重点说明
17
- > src\components 在这个目录下添加组件并且在src\index.js中进行导出
26
+ ### 引入组件
18
27
 
19
- #### src\index.js 全局挂载
20
28
  ```javascript
21
- // 前置在组件库前面的全局变量无需注入 手动注入以便于在组件中使用脚手架项目定义内容
22
- if (options) {
23
- for (const key in options) {
24
- if (options.hasOwnProperty(key)) {
25
- app.config.globalProperties[`$${key.toUpperCase()}`] = options[key]
26
- }
27
- }
28
- }
29
- ```
30
- #### vite.config.js 打包配置
31
- > 理论上组件库是不引用其余组件库 只有在初始化时使用了必要外部组件库,并且打包排除在外,后面尽量定义干净的组件无外部引入
32
- ```js
33
- rollupOptions: {
34
- external: ['vue', 'jsencrypt', 'vuedraggable', 'dayjs', 'element-plus', '@logicflow/core', '@logicflow/extension'], // 外部依赖
35
- output: {
36
- exports: 'named',
37
- globals: {
38
- vue: 'Vue',
39
- jsencrypt: 'JSEncrypt',
40
- vuedraggable: 'Vuedraggable',
41
- dayjs: 'dayjs',
42
- 'element-plus': 'ElementPlus',
43
- '@logicflow/core': 'LogicFlowCore',
44
- '@logicflow/extension': 'LogicFlowExtension'
45
- },
46
- assetFileNames: (assetInfo) => {
47
- if (assetInfo.name === 'style.css') {
48
- return 'style.css'
49
- }
50
- return assetInfo.name
51
- }
52
- }
53
- }
29
+ // 全局引入
30
+ import lwCdpUi from 'lw-cdp-ui';
31
+ import 'lw-cdp-ui/dist/style.css';
32
+ Vue.use(lwCdpUi);
54
33
 
34
+ // 按需引入
35
+ import { lwTable, lwForm } from 'lw-cdp-ui';
55
36
  ```
56
37
 
57
- #### package.json 版本管理
58
- ```js
59
- "version": "1.0.9", // 每次打包发布需要升级版本
60
- "type": "module",
61
- "main": "dist/lw-cdp-ui.umd.js",
62
- "module": "dist/lw-cdp-ui.esm.js",
63
- "exports": { // 导出必要的文件
64
- ".": {
65
- "import": "./dist/lw-cdp-ui.esm.js",
66
- "require": "./dist/lw-cdp-ui.umd.js"
67
- },
68
- "./style.css": "./dist/style.css"
69
- },
70
- ```
38
+ ### 使用示例
71
39
 
72
- ## 通用方法
73
- ### 关闭当前页面跳转
74
- ```js
75
- const store = useStore()
76
- /**
77
- *lw-cdp-ui >= 1.0.61
78
- * path 跳转路径
79
- * keep 需要刷新缓存刷新的页面的 name
80
- */
81
- store.state.viewTags.closeTagAndJump('/demo', 'DemoList')
82
- ```
83
- ### 按钮权限
84
40
  ```vue
85
- <el-button type="primary"
86
- icon="el-icon-plus"
87
- v-auth="'ec.goods.locate'">单一权限</el-button>
88
- <el-button type="primary"
89
- icon="el-icon-plus"
90
- v-auth="['ec.goods.locate', 'ec.goods.create']">组合权限</el-button>
91
- ```
92
- ### 更新菜单自定义菜单内容
93
- ```js
94
- import { getCurrentInstance } from 'vue'
95
- import { useRouter } from 'vue-router'
96
- export default {
97
- setup() {
98
- const router = useRouter()
99
- const {
100
- proxy: { $bus }
101
- } = getCurrentInstance()
102
- // 添加菜单
103
- const addMenu = () => {
104
- let menu = router.sc_getMenu()
105
-
106
- // 处理自己的业务
107
- menu.push({
108
- name: 'demoId',
109
- path: '/demo/2222',
110
- component: 'demo/list',
111
- meta: {
112
- icon: 'el-icon-tickets',
113
- type: 'menu',
114
- title: '测试新增菜单1'
115
- },
116
- sort: 0
117
- })
118
-
119
- // 发布
120
- $bus.$emit('setMenu', menu)
121
- }
122
- }
123
- }
124
-
41
+ <template>
42
+ <lw-table :data="tableData" :columns="columns" />
43
+ </template>
125
44
  ```
126
- ## 脚手架
127
- > 暂时通过git获取,后期可以打包成cli
128
-
129
- ### 项目结构
130
45
 
131
- ```csharp
132
- ├─public # 公共资源目录,通常包含不会被 Webpack 等工具处理的静态文件
133
- │ └─images # 静态图片文件,用于存放组件库lw-cdp-ui中所需要的资源
134
- └─src
135
- ├─api
136
- │ └─model # API 模块中的文件自动引入
137
- ├─assets
138
- │ ├─images # 项目中使用的图片资源
139
- │ ├─scss # SCSS 样式文件所有样式统一在index.scss引入
140
- │ └─svgIcon # SVG 图标文件目录,与lwSvgIcon组件配合使用
141
- ├─config # 配置文件
142
- ├─directives # 自定义指令目录,存放 Vue.js 的自定义指令
143
- ├─layout # 布局组件目录直接使用 lwLayout 组件
144
- │ └─other # 其他布局相关的子组件或布局配置
145
- ├─locales # 国际化文件目录,每种语言统一在 zh-cn.js 定义 统一翻译成其他语言
146
- │ └─lang
147
- ├─router # 路由配置目录
148
- ├─store # 状态管理目录
149
- │ └─modules # Vuex 模块目录,存放各个功能模块的状态管理逻辑
150
- ├─utils # 工具函数目录
151
- └─views # 视图组件目录
152
- ├─demo # 示例页面,通常用于演示项目功能或组件使用
153
- ├─initialization # 初始化页面,可能用于系统初始化或首次加载时的页面
154
- ├─login # 登录页面,使用 lwLogin 组件
155
- └─service # 示例页面,通常用于演示项目功能或组件使用
46
+ ## 文档目录
156
47
 
157
48
  ```
158
-
159
- ### 关键文件说明
160
-
161
- #### src/api 接口
162
- - 说明
163
- ```js
164
- import config from '@/config'
165
- import request from '@/utils/request'
166
-
167
- export default {
168
- // 分页
169
- page: async (params) => {
170
- let url = `${config.API_URL}/platform-tenant/tenant_business_unit`
171
- return await request.get(url, params)
172
- },
173
- // 列表
174
- list: async (params) => {
175
- let url = `${config.API_URL}/platform-tenant/tenant_business_unit/list`
176
- return await request.get(url, params)
177
- },
178
- // 详情
179
- info: async (params) => {
180
- let url = `${config.API_URL}/platform-tenant/tenant_business_unit/${params.id}`
181
- return await request.get(url)
182
- },
183
- // 修改
184
- edit: async (data = {}) => {
185
- let url = `${config.API_URL}/platform-tenant/tenant_business_unit`
186
- return await request.put(url, data)
187
- },
188
- // 新增
189
- add: async (data = {}) => {
190
- let url = `${config.API_URL}/platform-tenant/tenant_business_unit`
191
- return await request.post(url, data)
192
- },
193
- // 删除
194
- delete: async (id) => {
195
- let url = `${config.API_URL}/platform-tenant/tenant_business_unit/${id}`
196
- return await request.delete(url)
197
- }
198
- }
199
-
200
- ```
201
- - 直接在文件中定义方法会自定引入到全局
202
- - 全局使用时 直接this.$api.mock.page() mock文件夹名称 page方法名称
203
-
204
- #### src/assets 静态配置
205
- - svgIcon直接将要的svg文件放在里面
206
- ```vue
207
- <!-- 项目中使用 -->
208
- <lwSvgIcon name="这里就是svg文件名称" />
209
- ```
210
-
211
- #### src/config 配置
212
- ```js
213
- // 在这里合并动态的APP_CONFIG 可根据项目需求定义更多环境类型
214
- if (process.env.NODE_ENV === 'production') {
215
- Object.assign(DEFAULT_CONFIG, APP_CONFIG)
216
- }
217
-
49
+ docs/
50
+ ├── components/ # 组件文档
51
+ │ ├── bi-chart/ # 图表组件
52
+ │ ├── flow/ # 流程设计器
53
+ │ ├── form/ # 表单组件
54
+ │ └── table/ # 表格组件
55
+ └── guide/ # 使用指南
56
+ ├── theme.md # 主题定制
57
+ └── i18n.md # 国际化
218
58
  ```
219
59
 
60
+ ## 开发环境
220
61
 
221
- #### src/locales 国际化配置
222
- ```js
223
- import sysConfig from '@/config'
224
- import tool from '@/utils/tool'
225
- import { createI18n } from 'vue-i18n'
226
- import store from '@/store'
227
- import el_zh_cn from 'element-plus/es/locale/lang/zh-cn'
228
- import el_en from 'element-plus/es/locale/lang/en'
229
-
230
- // 静态加载的基础翻译文件
231
- import zh_cn from './lang/zh-cn.js'
232
- import en_us from './lang/en-us.js'
233
-
234
- // 挂载在线组件库国际化内容
235
- import { uiI18n } from 'lw-cdp-ui'
62
+ - Node.js 12+
63
+ - Vue 2.6+
64
+ - Webpack 4+
65
+ - npm/yarn
236
66
 
237
- // 获取本地语言并初始化 i18n 实例
238
- const localMessages = tool.data.get(`${sysConfig.APP_NAME}Message`) || {}
67
+ ## 构建项目
239
68
 
240
- // 初始化静态翻译内容
241
- const messages = {
242
- 'zh-cn': {
243
- el: el_zh_cn,
244
- ...localMessages['zh_cn'],
245
- ...zh_cn
246
- },
247
- 'en-us': {
248
- el: el_en,
249
- ...localMessages['en_us'],
250
- ...en_us
251
- }
252
- }
69
+ ```bash
70
+ # 开发模式
71
+ npm run dev
253
72
 
254
- // 使用 import.meta.globEager 进行静态导入
255
- const locales = import.meta.globEager('../views/**/locale/*.js')
73
+ # 生产构建
74
+ npm run build
256
75
 
257
- // 遍历所有翻译文件并按语言合并内容
258
- Object.keys(locales).forEach((path) => {
259
- const matched = path.match(/locale\/([a-z-]+)\.js$/)
260
- if (matched && matched[1]) {
261
- const locale = matched[1].toLowerCase()
262
- if (!messages[locale]) {
263
- messages[locale] = {}
264
- }
265
- Object.assign(messages[locale], locales[path].default)
266
- }
267
- })
268
-
269
- // 合并深层对象
270
- const deepMerge = (target, source) => {
271
- for (const key in source) {
272
- if (source.hasOwnProperty(key)) {
273
- if (source[key] instanceof Object && target[key] instanceof Object) {
274
- target[key] = deepMerge({ ...target[key] }, source[key])
275
- } else {
276
- target[key] = source[key]
277
- }
278
- }
279
- }
280
- return target
281
- }
282
-
283
- const allMessages = deepMerge(messages, uiI18n)
284
- tool.data.set(`${sysConfig.APP_NAME}Message`, allMessages)
285
- store.commit('setRouteShow', false)
286
-
287
- // 创建 i18n 实例
288
- const i18n = createI18n({
289
- locale: tool.data.get('APP_LANG') || sysConfig.LANG, // 默认语言
290
- fallbackLocale: 'en', // 回退语言
291
- globalInjection: true, // 允许在全局使用 $t 函数
292
- messages: allMessages // 合并后的翻译内容
293
- })
294
-
295
- export default i18n
296
-
297
-
298
- ```
299
-
300
- - 使用
301
- - js 中使用
302
- ```js
303
- import { getCurrentInstance} from 'vue'
304
-
305
- export default {
306
- name: 'DemoList',
307
- setup() {
308
- const {
309
- proxy: { t }
310
- } = getCurrentInstance()
311
-
312
- let typeObject = {
313
- increase: t('demoList.eventTypes.increase'),
314
- }
315
- }
316
- }
317
- ```
318
- - html 中使用
319
- ```vue
320
- <el-tooltip :content="$t('lwTable.tools.fullScreen')">
321
- <el-icon class="icon-fullscreen"
322
- @click="tableToggleFullScreen"><el-icon-full-screen /></el-icon>
323
- </el-tooltip>
324
- ```
325
-
326
-
327
- #### src/router 路由配置
328
- ```
329
- ├─router
330
- │ └─index.js # 统一处理
331
- │ └─route.js # 页面路由 挂载在layout上
332
- │ └─scrollBehavior.js # tag 标签页处理
333
- │ └─systemRouter.js # 系统路由 一级路由
334
- ```
335
- - 1、index.js 具体细节
336
- - 判断当前挂载项目是否是入口项目 不是的化将页面挂载在一级路由上 以便于嵌入入口项目中
337
- ```js
338
- menuRouter.forEach((item) => {
339
- // 判断是否需要挂载在UI框架上
340
- let MENUCOMBINEDNMAE = tool.data.get('MENUCOMBINEDNMAE')
341
- if (MENUCOMBINEDNMAE == config.APP_NAME) {
342
- router.addRoute('layout', item)
343
- } else {
344
- router.addRoute(item)
345
- }
346
- })
347
- ```
348
- - 挂载外部链接 主要有将多个项目菜单集成在一起显示
349
- ```js
350
- if (item.meta.type === 'iframe') {
351
- item.meta.url = item.path
352
- item.path = `/i/${item.name}`
353
- }
354
- ```
355
- - 2、route.js 参数说明
356
- ```js
357
- name: 'demo',
358
- path: '/demo',
359
- component: 'demo',
360
- meta: {
361
- icon: 'el-icon-monitor', // 现在使用的是element官方图标库
362
- type: 'menu', // 默认menu 菜单 iframe 外链
363
- title: 'menu.demo', // 国际化 对应locales/lang/zh-cn.js的数据结构
364
- roles: ['task.subedit.modify'] // 权限标志 不写这个参数默认显示 写了就会鉴别对应权限
365
- hidden: true // 是否显示在左侧菜单上
366
- }
76
+ # 文档构建
77
+ npm run docs:build
367
78
  ```
368
79
 
80
+ ## 贡献指南
369
81
 
370
- #### src/utils 工具
371
- - request.js 请求封装
372
- ```js
373
- // 替换请求路径中的占位符
374
- const tenantId = tool.data.get('tenantId')
375
- const buCode = tool.data.get('buCode')
376
- if (tenantId) {
377
- config.url = config.url.replace(/{tenantId}/g, tenantId)
378
- }
379
- if (buCode) {
380
- config.url = config.url.replace(/{buCode}/g, buCode)
381
- }
382
- ```
383
-
384
- #### src/lwui.js入口配置
385
- ```javascript
386
- import config from './config'
387
- import api from './api'
388
- import tool from './utils/tool'
389
- import bus from './utils/bus'
390
- import http from './utils/request'
391
- import { expression } from './utils/common'
392
-
393
- import 'virtual:svg-icons-register'
82
+ 欢迎提交Pull Request或Issue。在提交前请确保:
394
83
 
395
- import * as elIcons from '@element-plus/icons'
396
- // 挂载在线组件库 需要放在全局对象后 便于注入全局状态
397
- import lwCdpUi from 'lw-cdp-ui'
398
- import 'lw-cdp-ui/style.css'
399
- // 挂载本地组件库
400
- // import lwCdpUi from '@/lw-ui/src/index'
401
- // import '@/lw-ui/src/assets/scss/index'
84
+ 1. 通过ESLint检查
85
+ 2. 添加相应的单元测试
86
+ 3. 更新相关文档
402
87
 
403
- export default {
404
- install(app) {
405
- //挂载全局对象
406
- app.config.globalProperties.$config = config
407
- app.config.globalProperties.$tool = tool
408
- app.config.globalProperties.$http = http
409
- app.config.globalProperties.$api = api
410
- app.config.globalProperties.$bus = bus
411
- app.config.globalProperties.$expression = expression
412
-
413
- // 注册私有组件库
414
- app.use(lwCdpUi)
415
-
416
- //统一注册el-icon图标
417
- for (let icon in elIcons) {
418
- app.component(`ElIcon${icon}`, elIcons[icon])
419
- }
420
- }
421
- }
422
-
423
-
424
- ```
88
+ ## 许可证
425
89
 
90
+ MIT © 2023 lw-ui团队
@@ -0,0 +1,142 @@
1
+ <template>
2
+ <!-- 动态组件 -->
3
+ <component :is="componentMap[item.component]"
4
+ v-model="defaultValue"
5
+ @change="handleChange"
6
+ :size="size"
7
+ :disabled="disabled"
8
+ v-bind="getComponentProps(item)">
9
+ <!-- 处理组件插槽 -->
10
+ <template v-if="item.component === 'select'">
11
+ <el-option v-for="option in item.options.items"
12
+ :key="option.value"
13
+ :disabled="option.disabled"
14
+ :label="option.label"
15
+ :value="option.value" />
16
+ </template>
17
+ <template v-if="item.component === 'checkboxGroup'">
18
+ <el-checkbox v-for="_item in item.options.items"
19
+ :key="_item.value"
20
+ :label="_item.value">{{_item.label}}</el-checkbox>
21
+ </template>
22
+ <template v-if="item.component === 'number' && item?.options?.suffix"
23
+ #suffix>
24
+ {{ item.options.suffix }}
25
+ </template>
26
+ <template v-if="item.component === 'input' && item?.options?.prepend"
27
+ #prepend>
28
+ {{ item.options.prepend }}
29
+ </template>
30
+ <template v-if="item.component === 'input' && item?.options?.append"
31
+ #append>
32
+ {{ item.options.append }}
33
+ </template>
34
+ </component>
35
+
36
+ </template>
37
+
38
+ <script>
39
+ export default {
40
+ props: {
41
+ modelValue: {
42
+ type: null,
43
+ default: ''
44
+ },
45
+ item: {
46
+ type: Object,
47
+ default: () => {}
48
+ },
49
+ size: {
50
+ type: String,
51
+ default: 'default'
52
+ },
53
+ disabled: {
54
+ type: Boolean,
55
+ default: false
56
+ }
57
+ },
58
+ data() {
59
+ return {
60
+ defaultValue: '',
61
+ // 组件映射表
62
+ componentMap: {
63
+ input: 'el-input',
64
+ checkbox: 'el-checkbox',
65
+ checkboxGroup: 'el-checkbox-group',
66
+ switch: 'el-switch',
67
+ select: 'el-select',
68
+ cascader: 'el-cascader',
69
+ date: 'el-date-picker',
70
+ number: 'el-input-number',
71
+ radio: 'el-radio-group',
72
+ color: 'el-color-picker',
73
+ rate: 'el-rate',
74
+ slider: 'el-slider'
75
+ }
76
+ }
77
+ },
78
+ watch: {
79
+ modelValue: {
80
+ handler(val) {
81
+ this.defaultValue = val
82
+ },
83
+ immediate: true
84
+ }
85
+ },
86
+ methods: {
87
+ handleChange(value) {
88
+ this.$emit('update:modelValue', value)
89
+ },
90
+ // 获取组件属性
91
+ getComponentProps(item) {
92
+ let props = {}
93
+ if (item?.options) {
94
+ // 通用属性
95
+ props.placeholder = item.options.placeholder || ''
96
+ props.clearable = item.options.clearable || true
97
+ if (item.options.type) props.type = item.options.type
98
+ if (item.options?.maxlength) {
99
+ props.maxlength = item.options.maxlength
100
+ props.showWordLimit = true // 正确启用字数统计
101
+ }
102
+ if (item.options?.activeText) {
103
+ props.maxlength = item.options.maxlength
104
+ props.inlinePrompt = true
105
+ }
106
+
107
+ // 组件特有属性
108
+ switch (item.component) {
109
+ case 'select':
110
+ props.filterable = true
111
+ break
112
+ case 'date':
113
+ props.type = item.options.type || 'date'
114
+ props.startPlaceholder = item.options.startPlaceholder || '开始日期'
115
+ props.endPlaceholder = item.options.endPlaceholder || '结束日期'
116
+ break
117
+ case 'number':
118
+ props.controlsPosition = item.options.controlsPosition || 'right'
119
+ break
120
+ case 'treeSelect':
121
+ props.data = item?.options?.items || []
122
+ break
123
+ case 'treeSelect':
124
+ props.options = item?.options?.items || []
125
+ break
126
+ }
127
+ }
128
+
129
+ props = {
130
+ ...item.options,
131
+ ...props
132
+ }
133
+ // 清除
134
+ delete props.disabled
135
+ return props
136
+ }
137
+ }
138
+ }
139
+ </script>
140
+
141
+ <style>
142
+ </style>