matrix_components 2.0.441 → 2.0.460

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.
Files changed (2) hide show
  1. package/README.md +680 -166
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,5 +1,16 @@
1
- # **组件库2.0**
2
- 组件使用示例参考dist/ComponentDemo
1
+ # Matrix Components 组件库
2
+
3
+ ## 简介
4
+
5
+ Matrix Components 是一个功能丰富的 Vue 3 企业级组件库,提供办公文档预览、动态表单、视频播放、权限控制等完整解决方案。
6
+
7
+ 组件使用示例参考 `dist/ComponentDemo`
8
+
9
+ ## 📸 组件预览
10
+
11
+ 以下是组件库的架构和功能概览图:
12
+
13
+ <iframe src="https://www.processon.com/embed/695db575faec1a656002a2ae" width="100%" height="80vh" frameborder="0" scrolling="no" style="min-height: 400px; max-height: 800px;"></iframe>
3
14
 
4
15
  ```
5
16
  version:2.0.440
@@ -152,7 +163,6 @@ version:2.0.308
152
163
  1.增加Demo示例目录:组件使用示例在dist/ComponentDemo
153
164
  ```
154
165
 
155
-
156
166
  ```
157
167
  version:2.0.305
158
168
  2025年10月21日15:05:11
@@ -240,6 +250,40 @@ version:2.0.292
240
250
  1.NsPdf预览组件支持搜索功能
241
251
  ```
242
252
 
253
+
254
+ ## 📊 功能特性总结
255
+
256
+ ### 组件功能
257
+
258
+ - ✅ **NsOffice**: 办公文档统一预览(Excel/PDF/Word)
259
+ - ✅ **NsForm**: 动态表单生成和管理
260
+ - ✅ **NsVideo**: 专业视频播放器
261
+ - ✅ **NsDialog**: 灵活弹窗对话框
262
+ - ✅ **NsPdf**: PDF文档预览和搜索
263
+ - ✅ **NsExcel**: Excel预览和编辑
264
+ - ✅ **NsWord**: Word文档预览
265
+ - ✅ **NsImage**: 图片预览
266
+ - ✅ **NsMD**: Markdown编辑器
267
+ - ✅ **NsSaturationline**: 浸润线
268
+ - ✅ **NsAutoScreen**: 自适应屏幕工具
269
+
270
+ ### 指令功能
271
+
272
+ - ✅ **v-permission**: 按钮权限控制
273
+ - ✅ **v-length**: 输入长度和格式限制
274
+ - ✅ **v-sline**: 单行文本省略
275
+ - ✅ **v-event-unuse/use**: 事件穿透控制
276
+
277
+ ### 工具函数
278
+
279
+ - ✅ **HTTP请求**: 完整的RESTful API封装
280
+ - ✅ **资源加载**: 动态JS/CSS资源管理
281
+ - ✅ **表格排序**: 表格排序功能
282
+ - ✅ **SM2加密**: 国密算法加密
283
+ - ✅ **CSS变量**: 主题样式管理
284
+ - ✅ **通用工具**: 常用工具函数
285
+
286
+
243
287
  ## 创建公共组件库步骤
244
288
 
245
289
  - npm create vue@latest
@@ -264,7 +308,6 @@ version:2.0.292
264
308
  // 全局导入
265
309
  export default NsComponents
266
310
  ```
267
-
268
311
  - 子目录:NsXX目录,创建独立导出index.ts
269
312
 
270
313
  ```
@@ -277,7 +320,6 @@ version:2.0.292
277
320
  // 导出子组件
278
321
  export default NsXX
279
322
  ```
280
-
281
323
  - 配置package.json
282
324
 
283
325
  ```
@@ -305,7 +347,6 @@ version:2.0.292
305
347
  ...
306
348
  }
307
349
  ```
308
-
309
350
  - 配置vite.config.ts
310
351
 
311
352
  ```
@@ -344,13 +385,11 @@ version:2.0.292
344
385
  },
345
386
  }
346
387
  ```
347
-
348
388
  - 打包
349
389
 
350
390
  ```
351
391
  npm run build
352
392
  ```
353
-
354
393
  - 当前项目main.ts使用
355
394
 
356
395
  ```
@@ -363,7 +402,6 @@ version:2.0.292
363
402
  // app.use(NsXX)
364
403
 
365
404
  ```
366
-
367
405
  - 当前项目Test.vue使用
368
406
 
369
407
  ```
@@ -399,217 +437,693 @@ version:2.0.292
399
437
 
400
438
  ```
401
439
 
402
- ### 1. 视频组件(NsVideo)
440
+ ## 📋 组件列表
441
+
442
+ ### 1. NsOffice - 办公文档统一预览组件
443
+
444
+ 支持格式:Excel(.xlsx/.xls)、PDF(.pdf)、Word(.docx/.doc)
445
+
446
+ ```vue
447
+ <template>
448
+ <!-- 基础使用 -->
449
+ <NsOffice :url="fileUrl" />
450
+
451
+ <!-- Excel编辑模式 -->
452
+ <NsOffice :url="excelUrl" :isEdit="true" />
453
+
454
+ <!-- 获取组件引用 -->
455
+ <NsOffice ref="officeRef" :url="fileUrl" />
456
+ </template>
457
+
458
+ <script setup>
459
+ import { ref } from 'vue'
460
+ import { NsOffice } from 'matrix_components'
461
+
462
+ const officeRef = ref()
463
+
464
+ // 获取文件类型
465
+ const fileType = officeRef.value?.getFileType() // 'excel' | 'pdf' | 'word' | 'unsupported'
466
+
467
+ // 获取当前激活的组件实例
468
+ const activeComponent = officeRef.value?.getActiveComponent()
469
+
470
+ // 刷新组件
471
+ officeRef.value?.refresh()
472
+ </script>
473
+ ```
474
+
475
+ ### 2. NsForm - 动态表单组件
476
+
477
+ ```vue
478
+ <template>
479
+ <NsForm :rows="formConfig" ref="formRef" />
480
+ </template>
481
+
482
+ <script setup>
483
+ import { ref } from 'vue'
484
+ import { NsForm } from 'matrix_components'
485
+
486
+ const formRef = ref()
487
+ const formConfig = [
488
+ {
489
+ key: 'name',
490
+ label: '姓名',
491
+ component: 'el-input',
492
+ props: { placeholder: '请输入姓名' }
493
+ },
494
+ {
495
+ key: 'age',
496
+ label: '年龄',
497
+ component: 'el-input-number',
498
+ props: { min: 0, max: 100 }
499
+ }
500
+ ]
501
+
502
+ // 获取表单数据
503
+ const formData = formRef.value?.getFormData()
504
+
505
+ // 重置表单
506
+ formRef.value?.resetForm()
507
+
508
+ // 验证表单
509
+ const isValid = formRef.value?.validate()
510
+ </script>
511
+ ```
512
+
513
+ ### 3. NsVideo - 视频播放组件
514
+
515
+ ```vue
516
+ <template>
517
+ <NsVideo
518
+ ref="nsVideoRef"
519
+ v-bind="videoData"
520
+ v-on="videoEvent"
521
+ @changeSplit='changeSplitHandler'
522
+ >
523
+ <!-- 自定义插槽 -->
524
+ <template #video-tree><span>左侧树-自定义插槽</span></template>
525
+ <template #video-player-head><span>播放区域头部-自定义插槽</span></template>
526
+ <template #video-player-view><span>播放区域主体-自定义插槽</span></template>
527
+ <template #video-player-foot><span>播放区域底部控制按钮-自定义插槽</span></template>
528
+ <template #video-player-cover><span>播放器canvas画布区域(除head+foot+tree区域)</span></template>
529
+ </NsVideo>
530
+ </template>
531
+
532
+ <script setup>
533
+ import { ref } from 'vue'
534
+ import { NsVideo } from 'matrix_components'
535
+
536
+ const nsVideoRef = ref()
537
+
538
+ // 视频配置数据
539
+ const videoData = {
540
+ // 显示视频关闭按钮
541
+ showClose: true,
542
+ // 是否支持全屏
543
+ hasFullScreen: true,
544
+ // 显示树
545
+ showTree: true,
546
+ // 树数据
547
+ treeData: [
548
+ {
549
+ id: '1',
550
+ label: '分组1',
551
+ children: [
552
+ {
553
+ videoModel: 'easyplayer',
554
+ id: '111',
555
+ label: '视频A',
556
+ url: 'ws://example.com/rtp/video.live.flv',
557
+ deviceId: 'a1',
558
+ channelId: 'a11',
559
+ icontype: 'on',
560
+ }
561
+ ]
562
+ }
563
+ ],
564
+ // 树节点对应的key
565
+ treeNodeKey: 'id',
566
+ // 树节点展开的key
567
+ treeExpandedKeys: ['11'],
568
+ // 树节点属性
569
+ treeOptions: {
570
+ icontype: 'icontype',
571
+ background: 'background',
572
+ videoUrlKey: 'url',
573
+ children: 'children',
574
+ label: 'label',
575
+ },
576
+ // 获取、设置打开的播放视频信息
577
+ videoInfos: [
578
+ {
579
+ index: 0,
580
+ url: 'https://example.com/video.flv',
581
+ info: {
582
+ videoModel: 'easyplayer',
583
+ id: 'video1',
584
+ url: 'https://example.com/video.flv',
585
+ deviceId: 'c1',
586
+ channelId: 'c11',
587
+ },
588
+ }
589
+ ],
590
+ // 单点播放
591
+ videoSingleUrl: false,
592
+ // 已经在播放的是否关闭后再点击打开
593
+ videoSingleClose: false,
594
+ // 播放模式: 1: 单击,2: 双击
595
+ videoPlayModel: 1,
596
+ // 分屏模式: 1: 单屏, 2: 四屏, 3: 九屏
597
+ videoSplitType: 1,
598
+ // 显示分屏按钮
599
+ showVideoSplit: true,
600
+ // 显示方向控制按钮
601
+ showVideoCtrls: false,
602
+ // 禁止控制按钮默认请求行为
603
+ stopVideoCtrlMethods: true,
604
+ // 单个视频错误最大次数
605
+ videoErrorMaxCount: 3,
606
+ // easyplayer配置
607
+ videoConfig: {
608
+ MSE: true,
609
+ WCS: true,
610
+ WASM: true,
611
+ WASMSIMD: true,
612
+ isLive: true,
613
+ hasAudio: false,
614
+ stretch: false
615
+ },
616
+ // 事件回调
617
+ treeClick: () => { console.log('点击树节点') },
618
+ treeDBClick: () => { console.log('双击树节点') },
619
+ treeRightMenu: () => { console.log('右键树菜单') },
620
+ treeExpand: () => { console.log('展开树节点') },
621
+ videoError: () => { console.log('视频错误') },
622
+ }
623
+
624
+ // 视频操作事件
625
+ const videoEvent = {
626
+ videoOriginalInfo: (info) => { console.log('视频原始信息:', info) },
627
+ up: () => { console.log('向上移动') },
628
+ down: () => { console.log('向下移动') },
629
+ left: () => { console.log('向左移动') },
630
+ right: () => { console.log('向右移动') },
631
+ zoomin: () => { console.log('放大') },
632
+ zoomout: () => { console.log('缩小') },
633
+ stop: () => { console.log('停止') },
634
+ speed: () => { console.log('设置速度') },
635
+ speak: () => { console.log('开始说话') },
636
+ scan: () => { console.log('扫描') },
637
+ cruise: () => { console.log('巡航') },
638
+ call: () => { console.log('调用') },
639
+ }
403
640
 
641
+ // 获取原始视频信息
642
+ const videoInfo = nsVideoRef.value?.getOriginalInfo()
643
+
644
+ // 设置视频URL
645
+ nsVideoRef.value?.setVideoUrl('ws://example.com/rtp/video.live.flv', false, 1, {
646
+ videoModel: 'easyplayer'
647
+ })
648
+
649
+ // 移除视频
650
+ nsVideoRef.value?.removeVideo(1, true)
651
+
652
+ // 分屏变化回调
653
+ function changeSplitHandler(num) {
654
+ console.log('分屏模式:', num)
655
+ }
656
+ </script>
404
657
  ```
405
- // 1. 复制播放器资源
406
- js文件夹 到 public/目录中
407
- cdn文件夹 到 public/目录中
408
658
 
409
- // 2. index.html中引入
659
+ **前置准备:**
660
+
661
+ 1. 复制播放器资源:`js文件夹` 到 `public/` 目录中
662
+ 2. 复制播放器资源:`cdn文件夹` 到 `public/` 目录中
663
+ 3. 在 `index.html` 中引入:
664
+
665
+ ```html
410
666
  <script src="./js/EasyPlayer-pro.js"></script>
411
667
  <script src="./cdn/h5player/h5player.min.js"></script>
668
+ ```
412
669
 
413
- // 3.安装公共组件库 (安装过则无需安装)
414
- //@ts-ignore
415
- import NsComponents from 'matrix_components'
416
- import 'matrix_components/dist/matrix_components.css'
417
- app.use(NsComponents)
670
+ ### 4. NsDialog - 弹出框组件
671
+
672
+ ```javascript
673
+ import { NsDialog, closeAllNsDialog } from 'matrix_components'
674
+
675
+ // 打开对话框
676
+ NsDialog({
677
+ title: '测试',
678
+ // 任何组件添加 $emit('close') 时,会触发关闭弹出框事件
679
+ dom: VideoDemo, // 也可以通过异步方式:import("@/views/VideoDemo.vue") 和 () => import("@/views/VideoDemo.vue")
680
+ option: {
681
+ // dom对应的自定义组件props属性
682
+ ...data,
683
+ },
684
+ events: {
685
+ // dom组件内部自定义事件emit('btnClick', xxx)
686
+ btnClick: () => {
687
+ console.log("点击中间区域内容");
688
+ },
689
+ },
690
+ modalColor: 'rgb(0 21 115 / 20%)', // 遮罩层颜色
691
+ width: '800px', // 宽度, 整个弹出框的高度,非内容高度
692
+ height: '450px', // 高度, 不配置则默认为内容高度
693
+ dialogPadding: [10, 20], // 弹窗内padding
694
+ showFooter: true, // 默认显示底部按钮
695
+ immediately: false, // true立即取消弹出框, false异步请求后取消弹出框,默认false
696
+ draggable: true, // 是否可拖拽,默认false
697
+
698
+ confirm: async (closeFn, componentRef, footerLoading) => { // 底部确认按钮回调事件
699
+ // componentRef可以调用内部函数,前提需要defineExpose
700
+ try{
701
+ const selectRows = componentRef?.value?.getSelectedRows();
702
+ console.log("点击确认,选择数据:", selectRows);
703
+ } catch(e) {
704
+ console.log(e)
705
+ await new Promise(resolve => setTimeout(resolve, 1000))
706
+ }
707
+ // footerLoading可以控制底部loading状态
708
+ if(footerLoading) {
709
+ footerLoading.value = false
710
+ }
711
+ // 请求数据,再关闭
712
+ if(closeFn) {
713
+ closeFn()
714
+ }
715
+ },
716
+ close: () => { // 关闭弹出时立即出发
717
+ console.log("点击关闭");
718
+ },
719
+ closed: () => { // 弹窗销毁时触发
720
+ console.log("完成关闭");
721
+ },
722
+ // 头部+底部自定义配置
723
+ headerDom: xxx,
724
+ headerOption: {},
725
+ headerEvents: {},
726
+ footerDom: yyy,
727
+ footerOption: {},
728
+ footerEvents: {},
729
+ // 底部按钮名称
730
+ footerTitle: {
731
+ close: "取消",
732
+ confirm: "确定",
733
+ },
734
+ }, true, '#app') // true为是否遮罩(非必填), '#app'为挂载点(非必填)
735
+
736
+ // 关闭所有对话框
737
+ closeAllNsDialog()
738
+ ```
739
+
740
+ ### 5. NsPdf - PDF预览组件
741
+
742
+ ```vue
743
+ <template>
744
+ <NsPdf ref="pdfRef" :url="pdfUrl"></NsPdf>
745
+ </template>
746
+
747
+ <script setup>
748
+ import { ref } from 'vue'
749
+ import { NsPdf } from 'matrix_components'
750
+
751
+ const pdfRef = ref()
752
+
753
+ // 搜索关键词
754
+ function searchKeyword() {
755
+ pdfRef.value?.search('关键词')
756
+ }
757
+ </script>
758
+ ```
759
+
760
+ ### 6. NsExcel - Excel预览/编辑组件
418
761
 
419
- // 4. 项目组件中引入视频组件, NsVideo组件配置参考NsVideo目录ReadMe.md和VideoDemo.vue
762
+ ```vue
420
763
  <template>
421
- <NsVideo class="nsvideo" ref="nsVideoRef" v-bind="videoData" v-on="videoEvent" @changeSplit='changeSplitHandler'>
422
- <!-- 自定义插槽
423
- <template #video-tree><span>左侧树-自定义插槽</span></template>
424
- <template #video-player-head><span>播放区域头部-自定义插槽</span></template>
425
- <template #video-player-view><span>播放区域主体-自定义插槽</span></template>
426
- <template #video-player-foot><span>播放区域底部控制按钮-自定义插槽</span></template>
427
- -->
428
- </NsVideo>
764
+ <NsExcel :url="excelUrl" :isEdit="true" />
429
765
  </template>
430
766
  ```
431
767
 
432
- ### 2. 自适应函数(autoScaleInit)
768
+ ### 7. NsWord - Word预览组件
433
769
 
770
+ ```vue
771
+ <template>
772
+ <NsWord :url="wordUrl" />
773
+ </template>
774
+ ```
775
+
776
+ ### 8. NsImage - 图片预览组件
777
+
778
+ ```vue
779
+ <template>
780
+ <NsImage :src="imageUrl" :defaultImg="defaultImage" />
781
+ </template>
434
782
  ```
435
- // 1. 安装公共组件库 (安装过则无需安装)
436
- //@ts-ignore
437
- import NsComponents, { autoScaleInit } from 'matrix_components'
438
- import 'matrix_components/dist/matrix_components.css'
439
- app.use(NsComponents)
440
783
 
441
- // 2. 在main.t中初始化,建议在App创建之前
784
+ ### 9. NsMD - Markdown编辑器组件
785
+
786
+ ```vue
787
+ <template>
788
+ <NsMD v-model="markdownContent" />
789
+ </template>
790
+ ```
791
+
792
+ ### 10. NsSaturationline - 饱和度线组件
793
+
794
+ ```vue
795
+ <template>
796
+ <NsSaturationline :data="saturationData" />
797
+ </template>
798
+ ```
799
+
800
+ ### 11. NsAutoScreen - 自适应屏幕工具
801
+
802
+ ```javascript
803
+ import { autoScaleInit, sacle_x, sacle_y } from 'matrix_components'
804
+
805
+ // 初始化自适应
442
806
  autoScaleInit(document.querySelector('body'), {
443
- designWidth: 1920,
444
- designHeight: 920,
445
- mode: 'stretch', // 可选 horizontal/vertical/stretch
807
+ designWidth: 1920,
808
+ designHeight: 920,
809
+ mode: 'stretch', // 可选 horizontal/vertical/stretch
446
810
  });
447
811
 
812
+ // 获取缩放比例
813
+ const scaleX = sacle_x()
814
+ const scaleY = sacle_y()
448
815
  ```
449
816
 
450
- ### 3. 弹出框组件(NsDialog)
817
+
818
+
819
+ ## 🔧 自定义指令
820
+
821
+ ### 1. v-permission - 按钮权限控制
822
+
823
+ ```vue
824
+ <template>
825
+ <!-- 使用class控制权限,无权限时隐藏 -->
826
+ <el-button v-permission.class.display>查看</el-button>
827
+
828
+ <!-- 使用id控制权限,无权限时隐藏 -->
829
+ <el-button v-permission.id>编辑</el-button>
830
+
831
+ <!-- 默认使用id控制权限 -->
832
+ <el-button id="zuhu_list_add" v-permission>新增</el-button>
833
+ </template>
834
+
835
+ <script setup>
836
+ // 权限配置(需要在引入组件库之前设置)
837
+ import { createApp } from 'vue'
838
+
839
+ const app = createApp(App)
840
+ const btnsPermission = {
841
+ 'zuhu_list_add': true, // 有权限
842
+ 'zuhu_list_edit': false // 无权限
843
+ }
844
+
845
+ app.provide('btnsPermission', btnsPermission)
846
+ app.use(NsComponents) // 引入组件库
847
+ </script>
451
848
  ```
452
- import { NsDialog } from 'matrix_components'
453
- NsDialog({
454
- title: '测试',
455
- // 任何组件添加 $emit('close') 时,会触发关闭弹出框事件
456
- dom: VideoDemo, // 也可以通过异步方式:import("@/views/VideoDemo.vue") 和 () => import("@/views/VideoDemo.vue")
457
- option: {
458
- // dom对应的自定义组件props属性
459
- ...data,
460
- },
461
- events: {
462
- // dom组件内部自定义事件emit('btnClick', xxx)
463
- btnClick: () => {
464
- console.log("点击中间区域内容");
465
- },
466
- },
467
- modalColor: 'rgb(0 21 115 / 20%)', // 遮罩层颜色
468
- width: '800px', // 宽度, 整个弹出框的高度,非内容高度
469
- height: '450px', // 高度, 不配置则默认为内容高度
470
- dialogPadding: [10, 20], // 弹窗内padding
471
- showFooter: true, // 默认显示底部按钮
472
- immediately: false, // true立即取消弹出框, false异步请求后取消弹出框,默认false
473
- draggable: true, // 是否可拖拽,默认false
474
-
475
- confirm: async (closeFn: any, componentRef: any, footerLoading: any) => { // 底部确认按钮回调事件
476
- // 2.componentRef可以调用内部函数,前提需要defineExpose
477
- try{
478
- const selectRows = componentRef?.value?.getSelectedRows();
479
- console.log("点击确认,选择数据:", selectRows);
480
- } catch(e) {
481
- console.log(e)
482
- await new Promise(resolve => setTimeout(resolve, 1000))
483
- }
484
- // 3.footerLoading可以控制底部loading状态
485
- if(footerLoading) {
486
- footerLoading.value = false
487
- }
488
- // 1.请求数据,再关闭
489
- if(closeFn) {
490
- closeFn()
491
- }
492
- },
493
- close: () => { // 关闭弹出时立即出发
494
- console.log("点击关闭");
495
- },
496
- closed: () => { // 弹窗销毁时触发
497
- console.log("完成关闭");
498
- },
499
- // 头部+底部自定义配置
500
- // 任何组件添加 $emit('close') 时,会触发关闭弹出框事件
501
- headerDom: xxx,
502
- headerOption: {},
503
- headerEvents: {},
504
- // 任何组件添加 $emit('close') 时,会触发关闭弹出框事件
505
- footerDom: yyy,
506
- footerOption: {},
507
- footerEvents: {},
508
- // 底部按钮名称
509
- footerTitle: {
510
- close: "取消",
511
- confirm: "确定",
512
- },
513
- }, true, '#app') // true为是否遮罩(非必填), '#app'为挂载点(非必填)
849
+
850
+ ### 2. v-length - 输入长度限制
851
+
852
+ ```vue
853
+ <template>
854
+ <!-- 限制最大长度50(默认) -->
855
+ <el-input v-length placeholder="请输入用户名" />
856
+
857
+ <!-- 自定义长度限制 -->
858
+ <el-input v-length="100" placeholder="最多100字符" />
859
+
860
+ <!-- 仅允许输入数字 -->
861
+ <el-input v-length.number="11" placeholder="请输入手机号" />
862
+
863
+ <!-- 自定义正则表达式 -->
864
+ <el-input v-length.regex="{ maxLength: 10, pattern: /^[a-zA-Z]*$/ }" placeholder="仅允许字母" />
865
+
866
+ <!-- 数字范围限制 -->
867
+ <el-input v-length.range="{ min: 0, max: 100, int: true, maxLength: 10 }" placeholder="0-100整数" />
868
+ </template>
869
+ ```
870
+
871
+ ### 3. v-sline - 单行文本省略
872
+
873
+ ```vue
874
+ <template>
875
+ <span v-sline>这是一段很长的文本内容,超出部分会自动显示省略号...</span>
876
+ </template>
514
877
  ```
515
878
 
516
- ### 4. 指令集(v-permission / v-length / v-event-unuse / v-event-use / v-sline)
879
+ ### 4. v-event-unuse / v-event-use - 事件穿透控制
880
+
881
+ ```vue
882
+ <template>
883
+ <!-- 阻止事件穿透 -->
884
+ <div v-event-use>
885
+ <button>这个按钮可以点击</button>
886
+ </div>
887
+
888
+ <!-- 允许事件穿透 -->
889
+ <div v-event-unuse>
890
+ <div>这个区域的事件会穿透到下层</div>
891
+ </div>
892
+ </template>
517
893
  ```
518
- // 使用方法
519
- // 1. 按钮权限 v-permission.class.display / v-permission.id.display / v-permission.class / v-permission.id(默认)
520
- <button id="zuhu_list_add" v-permission>新增</button>
521
894
 
522
- // 使用按钮权限时,需要在外部项目中通过注入权限数据实现(注意:需要在引入公共组件库之前!!!)
523
- app.provide('btnsPermission', btnsPermission)
524
- // NsComponents为引入公共组件库
525
- app.use(NsComponents)
895
+ ## 🔧 工具函数
526
896
 
527
- // 2. 长度限制(默认50位):v-length[.number][="100"], 如:v-length.number="11" / v-length
528
- // .number 修饰符会限制只能输入数字(通过输入事件过滤非数字字符)
529
- <el-input placeholder="请输入手机号" v-length.number="11"/>
530
- <el-input placeholder="请输入用户名" v-length />
897
+ ### 1. 通用工具函数
531
898
 
532
- // 3. span单行显示并隐藏溢出文本: 'v-sline'
533
- <span v-sline >xxxx</span>
899
+ ```javascript
900
+ import { isNotNull } from 'matrix_components'
901
+
902
+ // 检查值是否非空
903
+ const result = isNotNull(value) // 返回布尔值
904
+ ```
534
905
 
535
- // 4. 用在能点击下层事件时:event-use (阻止穿透事件) / event-unuse (穿透事件)
536
- <div v-event-use></div>
537
- <div>无法点击到</div>
906
+ ### 2. 动态资源加载
538
907
 
539
- <div v-event-unuse></div>
540
- <div>可以点击到</div>
908
+ ```javascript
909
+ import { loadAccess, removeDynamicAccess } from 'matrix_components'
541
910
 
911
+ // 加载JS/CSS资源
912
+ await loadAccess('https://example.com/script.js', 'script-tag', false)
913
+
914
+ // 移除动态加载的资源
915
+ removeDynamicAccess('script-tag')
542
916
  ```
543
917
 
918
+ ### 3. CSS变量管理
919
+
920
+ ```javascript
921
+ import { loadCssVars } from 'matrix_components'
544
922
 
545
- ### 5. sm2加密(getEncryptSm2)
923
+ // 获取所有CSS变量
924
+ const cssVars = loadCssVars()
925
+ console.log(cssVars['--matrix-primary-color'])
546
926
  ```
547
- // 使用方法
548
- import NsComponents, { getEncryptSm2 } from 'matrix_components'
549
- app.use(NsComponents)
550
- const encrypArrs = getEncryptSm2(publicKey, ["xxx", "yyy"], isAdd04=false, cipherMode=1)
551
927
 
928
+ ### 4. 表格排序工具
929
+
930
+ ```javascript
931
+ import { handleSortChange, headerClick, handleHeaderCellClass } from 'matrix_components'
932
+
933
+ // 在表格组件中使用
934
+ <el-table
935
+ @sort-change="(sort) => handleSortChange(sort, searchForm, getList)"
936
+ @header-click="headerClick"
937
+ :header-cell-class-name="(params) => handleHeaderCellClass(params, searchForm)"
938
+ >
939
+ <!-- 表格内容 -->
940
+ </el-table>
552
941
  ```
553
942
 
554
- ### 6. get/post请求(http/get)
943
+ ### 5. SM2加密工具
944
+
945
+ ```javascript
946
+ import { getEncryptSm2 } from 'matrix_components'
947
+
948
+ // 使用SM2加密
949
+ const encrypted = getEncryptSm2(publicKey, ["xxx", "yyy"], isAdd04=false, cipherMode=1)
555
950
  ```
556
- // 使用方法
557
- // 1. main.ts中引入, 并指定app.config.globalProperties.$BaseUrl全局请求地址
951
+
952
+ ### 6. 动态表单工具函数
953
+
954
+ ```javascript
955
+ import {
956
+ useFileUpload,
957
+ getAllFormNodeByKey,
958
+ getAllFormKvData,
959
+ getAllFormNodeRefByKey
960
+ } from 'matrix_components'
961
+
962
+ // 表单文件上传hook
963
+ const { uploadFile, deleteFile } = useFileUpload()
964
+
965
+ // 根据key获取表单节点信息
966
+ const formNode = getAllFormNodeByKey(formRows, 'username')
967
+
968
+ // 获取表单所有键值对数据
969
+ const formData = getAllFormKvData(formRows)
970
+
971
+ // 根据key获取表单节点引用
972
+ const nodeRef = getAllFormNodeRefByKey(formRows, 'username')
973
+ ```
974
+
975
+
976
+
977
+ ### 7. 屏幕自适应函数
978
+
979
+ ```javascript
980
+ import { sacle_x, sacle_y, autoScaleInit } from 'matrix_components'
981
+
982
+ // 初始化自适应
983
+ autoScaleInit(document.querySelector('body'), {
984
+ designWidth: 1920,
985
+ designHeight: 920,
986
+ mode: 'stretch' // 可选 horizontal/vertical/stretch
987
+ })
988
+
989
+ // 获取当前缩放比例
990
+ const scaleX = sacle_x()
991
+ const scaleY = sacle_y()
992
+ ```
993
+
994
+ ## 🌐 HTTP请求函数
995
+
996
+ ### 1. 基础HTTP请求方法
997
+
998
+ ```javascript
999
+ import { get, post, put, del, download, downLoadLocalFile, getTokenInfo } from 'matrix_components'
1000
+
1001
+ // GET请求
1002
+ const result = await get('/api/users', { page: 1, size: 10 })
1003
+
1004
+ // POST请求
1005
+ const result = await post('/api/users', { name: '张三', age: 25 })
1006
+
1007
+ // PUT请求
1008
+ const result = await put('/api/users/1', { name: '李四', age: 30 })
1009
+
1010
+ // DELETE请求
1011
+ const result = await del('/api/users/1')
1012
+
1013
+ // 文件下载
1014
+ await download('/api/export', 'report.xlsx', 'get', { type: 'excel' })
1015
+
1016
+ // 下载本地文件
1017
+ downLoadLocalFile('/public/', 'template.xlsx', 'template.xlsx')
1018
+
1019
+ // 获取token信息
1020
+ const tokenInfo = getTokenInfo()
1021
+ ```
1022
+
1023
+ ### 2. 初始化配置
1024
+
1025
+ ```javascript
1026
+ // main.ts中配置
1027
+ import { createApp } from 'vue'
558
1028
  import NsComponents from 'matrix_components'
559
1029
 
1030
+ const app = createApp(App)
1031
+
560
1032
  // 请求地址的baseUrl,建议在app.use(NsComponents)之前设置
561
- app.config.globalProperties.$BaseUrl = 'http://请求ip:端口/'
1033
+ app.config.globalProperties.$BaseUrl = 'http://api.example.com/'
1034
+
562
1035
  // 图片、文件请求地址的ImageBaseUrl,建议在app.use(NsComponents)之前设置
563
- app.config.globalProperties.$ImageBaseUrl = 'http://请求ip:端口/'
564
- app.use(NsComponents)
1036
+ app.config.globalProperties.$ImageBaseUrl = 'http://api.example.com/'
565
1037
 
566
1038
  // 【可选】401无权显示回调
567
- app.config.globalProperties.$LogoutCallback = logoutHandler // 无权显示回调
568
- // 【可选】请求添加的token头的key,默认为satoken。token的key和value需要在外部项目中自己设置
569
- sessionStorage.setItem('tokenName', 'xxx')
570
- sessionStorage.setItem('tokenValue', 'yyy')
1039
+ app.config.globalProperties.$LogoutCallback = logoutHandler
571
1040
 
572
- // 2. xx.vue / xx.ts 调用获取get、post请求
573
- import { get, post } from 'matrix_components'
574
- export const login = (data) => post('/mag/AccAdmin/doLogin', data);
575
- ```
1041
+ // 【可选】请求添加的token头的key,默认为satoken
1042
+ sessionStorage.setItem('tokenName', 'Authorization')
1043
+ sessionStorage.setItem('tokenValue', 'Bearer your-token-here')
576
1044
 
577
- ### 7. NsPdf组件
1045
+ app.use(NsComponents)
578
1046
  ```
579
- // 使用方法
580
- import { NsPdf } from 'matrix_components'
581
- <NsPdf ref="pdfRef" :url="pdfUrl"></NsPdf>
582
- const pdfRef = ref()
583
1047
 
584
- function searchKeyword() {
585
- pdfRef.value?.search('人')
586
- }
1048
+ ### 3. 实际使用示例
1049
+
1050
+ ```javascript
1051
+ // api/user.js
1052
+ import { get, post } from 'matrix_components'
1053
+
1054
+ export const getUserList = (params) => get('/api/users', params)
1055
+
1056
+ export const createUser = (data) => post('/api/users', data)
1057
+
1058
+ export const updateUser = (id, data) => put(`/api/users/${id}`, data)
1059
+
1060
+ export const deleteUser = (id) => del(`/api/users/${id}`)
1061
+
1062
+ export const exportUsers = () => download('/api/users/export', 'users.xlsx')
587
1063
  ```
588
1064
 
589
- ### 8. NsOffice组件
1065
+ ## 🚀 完整安装和使用
1066
+
1067
+ ### 1. 安装依赖
1068
+
1069
+ ```bash
1070
+ # 安装Element Plus
1071
+ pnpm i element-plus
1072
+
1073
+ # 安装组件库
1074
+ pnpm i matrix_components -S --registry=http://199.10.9.178:8081/repository/npm-group/
1075
+
1076
+ # 如果安装失败,使用备用地址
1077
+ pnpm i matrix_components --registry=http://199.10.9.178:8081/repository/npm-hosted/
590
1078
  ```
591
- // 统一的办公文档预览组件,根据文件URL自动选择合适的组件
592
- // 支持格式:Excel(.xlsx/.xls)、PDF(.pdf)、Word(.docx/.doc)
593
1079
 
594
- // 使用方法
595
- import { NsOffice } from 'matrix_components'
1080
+ ### 2. 全局引入
596
1081
 
597
- // 基础使用
598
- <NsOffice :url="fileUrl" />
1082
+ ```javascript
1083
+ // main.ts
1084
+ import { createApp } from 'vue'
1085
+ import App from './App.vue'
599
1086
 
600
- // Excel编辑模式(仅对Excel文件有效)
601
- <NsOffice :url="excelUrl" :isEdit="true" />
1087
+ // 安装 Element-Plus
1088
+ import 'element-plus/dist/index.css'
1089
+ import ElementPlus from 'element-plus'
1090
+ import zhCn from 'element-plus/es/locale/lang/zh-cn'
602
1091
 
603
- // 获取组件信息
604
- <NsOffice ref="officeRef" :url="fileUrl" />
605
- const officeRef = ref()
1092
+ // 安装组件库
1093
+ // @ts-ignore
1094
+ import NsComponents from 'matrix_components'
1095
+ import 'matrix_components/dist/matrix_components.css'
606
1096
 
607
- // 获取文件类型
608
- const fileType = officeRef.value?.getFileType() // 'excel' | 'pdf' | 'word' | 'unsupported'
1097
+ const app = createApp(App)
1098
+
1099
+ // 配置请求地址
1100
+ app.config.globalProperties.$BaseUrl = 'http://your-api-server/'
1101
+ app.config.globalProperties.$ImageBaseUrl = 'http://your-api-server/'
1102
+
1103
+ app.use(ElementPlus, {
1104
+ locale: zhCn,
1105
+ })
1106
+ app.use(NsComponents)
1107
+
1108
+ app.mount('#app')
1109
+ ```
1110
+
1111
+ ### 3. 按需引入
1112
+
1113
+ ```javascript
1114
+ // 按需引入组件和函数
1115
+ import { NsForm, NsVideo, get, post, autoScaleInit } from 'matrix_components'
1116
+
1117
+ // 在组件中使用
1118
+ const app = createApp(App)
1119
+ app.use(NsForm)
1120
+ app.use(NsVideo)
1121
+
1122
+ autoScaleInit(document.querySelector('body'), {
1123
+ designWidth: 1920,
1124
+ designHeight: 920,
1125
+ mode: 'stretch'
1126
+ })
1127
+ ```
609
1128
 
610
- // 获取当前激活的组件实例
611
- const activeComponent = officeRef.value?.getActiveComponent()
612
1129
 
613
- // 刷新组件
614
- officeRef.value?.refresh()
615
- ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matrix_components",
3
- "version": "2.0.441",
3
+ "version": "2.0.460",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "files": [