npmapps 1.0.21 → 1.0.23

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 (105) hide show
  1. package/app/Wscats.vue-1.0.26.vsix +0 -0
  2. package/app/febean.vue-format-0.1.8.vsix +0 -0
  3. package/app/wujie-vue3-child/.claude/settings.local.json +8 -0
  4. package/app/wujie-vue3-child/.vscode/extensions.json +3 -0
  5. package/app/wujie-vue3-child/PROJECT_MEMORY.md +427 -0
  6. package/app/wujie-vue3-child/README.md +5 -0
  7. package/app/wujie-vue3-child/index.html +13 -0
  8. package/app/wujie-vue3-child/package-lock.json +5744 -0
  9. package/app/wujie-vue3-child/package.json +28 -0
  10. package/app/wujie-vue3-child/public/vite.svg +1 -0
  11. package/app/wujie-vue3-child/src/App.vue +130 -0
  12. package/app/wujie-vue3-child/src/assets/vue.svg +1 -0
  13. package/app/wujie-vue3-child/src/components/HelloWorld.vue +43 -0
  14. package/app/wujie-vue3-child/src/components/tags-view.vue +193 -0
  15. package/app/wujie-vue3-child/src/components/tags-view1.vue +131 -0
  16. package/app/wujie-vue3-child/src/hooks/useClickOutside.js +11 -0
  17. package/app/wujie-vue3-child/src/hooks/useTableDragSort.js +28 -0
  18. package/app/wujie-vue3-child/src/main.js +15 -0
  19. package/app/wujie-vue3-child/src/router/index.js +104 -0
  20. package/app/wujie-vue3-child/src/store/tagsViewStroe.js +34 -0
  21. package/app/wujie-vue3-child/src/style.css +4 -0
  22. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/README.md +836 -0
  23. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/REFLEX_EXAMPLES.md +728 -0
  24. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentPersonnelSelector.jsx +687 -0
  25. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentPersonnelSelector.module.scss +560 -0
  26. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelector.jsx +570 -0
  27. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelector.module.scss +330 -0
  28. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelectorV2.jsx +378 -0
  29. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelectorV2.module.scss +228 -0
  30. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/OptionsSelector.jsx +399 -0
  31. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/OptionsSelector.module.scss +252 -0
  32. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PersonnelSelector.jsx +585 -0
  33. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PersonnelSelector.module.scss +331 -0
  34. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PopoverSelector.jsx +392 -0
  35. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PopoverSelector.module.scss +39 -0
  36. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/README.md +248 -0
  37. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/SelectorTrigger.jsx +194 -0
  38. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/index.jsx +1459 -0
  39. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/mockData.js +301 -0
  40. package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/dialogueSegment/index.jsx +28 -4
  41. package/app/wujie-vue3-child/src/views/aiCoach/index.jsx +32 -0
  42. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ChartsPanel/index.jsx +121 -0
  43. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ChartsPanel/index.module.scss +76 -0
  44. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/DonutChart/index.jsx +104 -0
  45. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/PracticeTable/index.jsx +75 -0
  46. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/PracticeTable/index.module.scss +12 -0
  47. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankBarChart/index.jsx +62 -0
  48. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankBarChart/index.module.scss +43 -0
  49. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingGroup/index.jsx +29 -0
  50. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingGroup/index.module.scss +5 -0
  51. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingList/index.jsx +58 -0
  52. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingList/index.module.scss +85 -0
  53. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ScriptStatsPanel/index.jsx +92 -0
  54. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ScriptStatsPanel/index.module.scss +56 -0
  55. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/StatCardsRow/index.jsx +40 -0
  56. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/StatCardsRow/index.module.scss +53 -0
  57. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/echarts/EchartsDonut.jsx +106 -0
  58. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/echarts/EchartsRankBar.jsx +132 -0
  59. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/index.jsx +176 -0
  60. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/index.module.scss +96 -0
  61. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/CoachReport/index.jsx +162 -0
  62. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/CoachReport/index.module.scss +16 -0
  63. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ComprehensiveEvaluation/index.jsx +29 -0
  64. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ComprehensiveEvaluation/index.module.scss +25 -0
  65. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueBubble/index.jsx +106 -0
  66. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueBubble/index.module.scss +164 -0
  67. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueRecord/index.jsx +182 -0
  68. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueRecord/index.module.scss +203 -0
  69. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionDetail/index.jsx +145 -0
  70. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionDetail/index.module.scss +126 -0
  71. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionScores/index.jsx +67 -0
  72. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionScores/index.module.scss +105 -0
  73. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ReportHeader/index.jsx +81 -0
  74. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ReportHeader/index.module.scss +47 -0
  75. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/RoleInfo/index.jsx +64 -0
  76. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/RoleInfo/index.module.scss +85 -0
  77. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ScoreBadge/index.jsx +39 -0
  78. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ScoreBadge/index.module.scss +44 -0
  79. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/SubDimensionItem/index.jsx +83 -0
  80. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/SubDimensionItem/index.module.scss +101 -0
  81. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/index.jsx +50 -0
  82. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/index.module.scss +25 -0
  83. package/app/wujie-vue3-child/src/views/child-to-parent.vue +117 -0
  84. package/app/wujie-vue3-child/src/views/home.vue +53 -0
  85. package/app/wujie-vue3-child/src/views/jsx/btnSelect/btnSelect.vue +169 -0
  86. package/app/wujie-vue3-child/src/views/jsx/btnSelect/index.vue +69 -0
  87. package/app/wujie-vue3-child/src/views/jsx/com.vue +44 -0
  88. package/app/wujie-vue3-child/src/views/jsx/dialog.jsx +66 -0
  89. package/app/wujie-vue3-child/src/views/jsx/index.vue +72 -0
  90. package/app/wujie-vue3-child/src/views/jsx/props.vue +33 -0
  91. package/app/wujie-vue3-child/src/views/parent-to-child.vue +225 -0
  92. package/app/wujie-vue3-child/src/views/phone-code.vue +318 -0
  93. package/app/wujie-vue3-child/src/views/router-jump.vue +123 -0
  94. package/app/wujie-vue3-child/src/views/test.vue +192 -0
  95. package/app/wujie-vue3-child/vite.config.js +15 -0
  96. package/package.json +1 -1
  97. package/app/aiCoach/index.jsx +0 -20
  98. package/npmapps-1.0.20.tgz +0 -0
  99. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/collapseExpand/index.jsx +0 -0
  100. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/collapseExpand/index.module.scss +0 -0
  101. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/dialogueSegment/index.module.scss +0 -0
  102. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/index.jsx +0 -0
  103. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/index.module.scss +0 -0
  104. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/inputColumn/index.jsx +0 -0
  105. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/inputColumn/index.module.scss +0 -0
@@ -0,0 +1,101 @@
1
+ // 子维度项样式
2
+ .subDimensionItem {
3
+ background: #fafafa;
4
+ padding: 16px 20px;
5
+ border-radius: 8px;
6
+ margin-bottom: 16px;
7
+
8
+ &:last-child {
9
+ margin-bottom: 0;
10
+ }
11
+ }
12
+
13
+ .header {
14
+ display: flex;
15
+ justify-content: space-between;
16
+ align-items: center;
17
+ margin-bottom: 12px;
18
+ }
19
+
20
+ .name {
21
+ font-size: 14px;
22
+ font-weight: 600;
23
+ color: #52c41a;
24
+ }
25
+
26
+ .score {
27
+ font-size: 14px;
28
+ font-weight: 600;
29
+ color: #52c41a;
30
+ background: #f6ffed;
31
+ padding: 3px 14px;
32
+ border-radius: 12px;
33
+ }
34
+
35
+ // 进度条
36
+ .progressBar {
37
+ margin-bottom: 12px;
38
+ }
39
+
40
+ .progressTrack {
41
+ width: 100%;
42
+ height: 8px;
43
+ background: #e8e8e8;
44
+ border-radius: 4px;
45
+ overflow: hidden;
46
+ margin-bottom: 6px;
47
+ }
48
+
49
+ // 进度条填充 - 低分(红色)
50
+ .progressFillLow {
51
+ height: 100%;
52
+ background: linear-gradient(90deg, #f5222d 0%, #ff4d4f 100%);
53
+ border-radius: 4px;
54
+ transition: width 0.3s ease;
55
+ }
56
+
57
+ // 进度条填充 - 中等(黄色/橙色)
58
+ .progressFillMedium {
59
+ height: 100%;
60
+ background: linear-gradient(90deg, #fa8c16 0%, #ffa940 100%);
61
+ border-radius: 4px;
62
+ transition: width 0.3s ease;
63
+ }
64
+
65
+ // 进度条填充 - 高分(绿色)
66
+ .progressFillHigh {
67
+ height: 100%;
68
+ background: linear-gradient(90deg, #52c41a 0%, #73d13d 100%);
69
+ border-radius: 4px;
70
+ transition: width 0.3s ease;
71
+ }
72
+
73
+ .progressLabels {
74
+ display: flex;
75
+ justify-content: space-between;
76
+ font-size: 12px;
77
+ color: #8c8c8c;
78
+ }
79
+
80
+ // 评价内容
81
+ .comment {
82
+ display: flex;
83
+ align-items: flex-start;
84
+ gap: 8px;
85
+ padding: 12px 14px;
86
+ background: #fff;
87
+ border-radius: 6px;
88
+ border-left: 3px solid #52c41a;
89
+ }
90
+
91
+ .commentIcon {
92
+ font-size: 16px;
93
+ flex-shrink: 0;
94
+ }
95
+
96
+ .commentText {
97
+ flex: 1;
98
+ font-size: 13px;
99
+ color: #595959;
100
+ line-height: 1.7;
101
+ }
@@ -0,0 +1,50 @@
1
+ import { defineComponent, ref } from 'vue'
2
+ import styles from './index.module.scss'
3
+ import ReportHeader from './components/ReportHeader/index.jsx'
4
+ import CoachReport from './components/CoachReport/index.jsx'
5
+ import DialogueRecord from './components/DialogueRecord/index.jsx'
6
+
7
+ /**
8
+ * 报告详情页面
9
+ * @description 显示练习报告的完整详情,包括总览和各维度的详细评分
10
+ */
11
+ export default defineComponent({
12
+ name: 'ReportDetail',
13
+
14
+ setup() {
15
+ // 报告头部数据
16
+ const headerData = ref({
17
+ title: '银行理财推荐',
18
+ isQuit: true, // 是否中途退出
19
+ practiceTime: '2025-08-20 12:12',
20
+ rounds: 2,
21
+ duration: "23'23\"",
22
+ score: 55,
23
+ isPassed: false, // 是否达标
24
+ })
25
+
26
+ // 当前激活的标签页
27
+ const activeTab = ref('coachReport')
28
+
29
+ return () => {
30
+ return (
31
+ <div class={styles.reportDetail}>
32
+ {/* 报告头部 */}
33
+ <ReportHeader {...headerData.value} />
34
+
35
+ {/* 标签页 */}
36
+ <div class={styles.tabsContainer}>
37
+ <el-tabs v-model={activeTab.value} class={styles.tabs}>
38
+ <el-tab-pane label="陪练报告" name="coachReport">
39
+ <CoachReport />
40
+ </el-tab-pane>
41
+ <el-tab-pane label="对话记录" name="dialogueRecord">
42
+ <DialogueRecord />
43
+ </el-tab-pane>
44
+ </el-tabs>
45
+ </div>
46
+ </div>
47
+ )
48
+ }
49
+ },
50
+ })
@@ -0,0 +1,25 @@
1
+ // 报告详情页面样式
2
+ .reportDetail {
3
+ padding: 20px;
4
+ background: #fff;
5
+ min-height: 100vh;
6
+ }
7
+
8
+ // 标签页容器
9
+ .tabsContainer {
10
+ margin-top: 24px;
11
+ }
12
+
13
+ .tabs {
14
+ :global {
15
+ .el-tabs__header {
16
+ margin-bottom: 24px;
17
+ }
18
+
19
+ .el-tabs__item {
20
+ font-size: 16px;
21
+ font-weight: 500;
22
+ }
23
+ }
24
+ }
25
+
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <div class="child-to-parent">
3
+ <h1>子应用消息发送</h1>
4
+ <div class="form-container">
5
+ <div class="form-item">
6
+ <label>标题:</label>
7
+ <input type="text" v-model="formData.title" placeholder="请输入标题">
8
+ </div>
9
+ <div class="form-item">
10
+ <label>消息:</label>
11
+ <input type="text" v-model="formData.message" placeholder="请输入消息内容">
12
+ </div>
13
+ <div class="form-item">
14
+ <label>类型:</label>
15
+ <select v-model="formData.type">
16
+ <option value="success">成功</option>
17
+ <option value="warning">警告</option>
18
+ <option value="error">错误</option>
19
+ <option value="info">信息</option>
20
+ </select>
21
+ </div>
22
+ <div class="form-item">
23
+ <label>持续时间:</label>
24
+ <input type="number" v-model="formData.duration" placeholder="持续时间(ms)">
25
+ </div>
26
+ <button class="submit-btn" @click="sendToParent">发送消息</button>
27
+ </div>
28
+ </div>
29
+ </template>
30
+
31
+ <script setup>
32
+ import { reactive } from 'vue'
33
+
34
+ const formData = reactive({
35
+ title: 'vue3子应用测试title',
36
+ message: 'vue3子应用测试消息',
37
+ type: 'success',
38
+ duration: 3000
39
+ })
40
+
41
+ const sendToParent = () => {
42
+ window.$wujie?.bus.$emit('child-event', {
43
+ message: formData.message,
44
+ type: formData.type,
45
+ duration: formData.duration,
46
+ title: formData.title
47
+ },'vue3子应用')
48
+ }
49
+ </script>
50
+
51
+ <style scoped>
52
+ .child-to-parent {
53
+ padding: 20px;
54
+ max-width: 600px;
55
+ margin: 0 auto;
56
+ }
57
+
58
+ h1 {
59
+ color: #333;
60
+ margin-bottom: 30px;
61
+ text-align: center;
62
+ }
63
+
64
+ .form-container {
65
+ background: #fff;
66
+ padding: 24px;
67
+ border-radius: 8px;
68
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
69
+ }
70
+
71
+ .form-item {
72
+ margin-bottom: 20px;
73
+ display: flex;
74
+ align-items: center;
75
+ }
76
+
77
+ label {
78
+ width: 100px;
79
+ text-align: right;
80
+ padding-right: 12px;
81
+ color: #606266;
82
+ }
83
+
84
+ input, select {
85
+ flex: 1;
86
+ height: 36px;
87
+ line-height: 36px;
88
+ padding: 0 12px;
89
+ border: 1px solid #dcdfe6;
90
+ border-radius: 4px;
91
+ transition: border-color 0.2s;
92
+ }
93
+
94
+ input:focus, select:focus {
95
+ outline: none;
96
+ border-color: #409eff;
97
+ }
98
+
99
+ .submit-btn {
100
+ width: 100%;
101
+ height: 40px;
102
+ background-color: #409eff;
103
+ color: white;
104
+ border: none;
105
+ border-radius: 4px;
106
+ cursor: pointer;
107
+ transition: background-color 0.3s;
108
+ }
109
+
110
+ .submit-btn:hover {
111
+ background-color: #66b1ff;
112
+ }
113
+
114
+ .submit-btn:active {
115
+ background-color: #3a8ee6;
116
+ }
117
+ </style>
@@ -0,0 +1,53 @@
1
+ // 主页
2
+ <template>
3
+ <div class="home-container">
4
+ <h1 class="home-title">vue3子应用主页</h1>
5
+ <div class="home-content">
6
+ <p class="welcome-text">欢迎使用无界微前端框架</p>
7
+ <el-button @click="jumpToChild">跳转到测试页面</el-button>
8
+ </div>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup>
13
+ import { useRoute, useRouter } from 'vue-router'
14
+
15
+ // 可以在这里添加组件逻辑
16
+ // 获取路由参数
17
+ const router = useRouter()
18
+ const route = useRoute()
19
+ const jumpToChild = () => {
20
+ router.push('/test'+ '?name=123' )
21
+ }
22
+ </script>
23
+
24
+ <style scoped>
25
+ .home-container {
26
+ padding: 2rem;
27
+ max-width: 1200px;
28
+ margin: 0 auto;
29
+ min-height: 80vh;
30
+ }
31
+
32
+ .home-title {
33
+ color: #2c3e50;
34
+ font-size: 2.5rem;
35
+ margin-bottom: 2rem;
36
+ text-align: center;
37
+ }
38
+
39
+ .home-content {
40
+ background-color: #f8f9fa;
41
+ border-radius: 8px;
42
+ padding: 2rem;
43
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
44
+ }
45
+
46
+ .welcome-text {
47
+ font-size: 1.2rem;
48
+ color: #666;
49
+ text-align: center;
50
+ line-height: 1.6;
51
+ }
52
+ </style>
53
+
@@ -0,0 +1,169 @@
1
+ <script lang="jsx">
2
+ import { defineComponent, ref, computed, watch } from "vue";
3
+ import { ArrowDown } from "@element-plus/icons-vue";
4
+ export default defineComponent({
5
+ name: "BtnSelect",
6
+ props: {
7
+ options: { type: Array, default: () => [] },
8
+ modelValue: { type: [String, Number, Array, Object, Boolean], default: null },
9
+ multiple: { type: Boolean, default: false },
10
+ searchable: { type: Boolean, default: false },
11
+ label: { type: String, default: "" },
12
+ optionKeys: { type: Object, default: () => ({ label: "label", value: "value" }) },
13
+ maxLabelCount: { type: Number, default: 3 },
14
+ disabled: { type: Boolean, default: false },
15
+ collapseTags: { type: Boolean, default: false },
16
+ itemRender: { type: Function, default: null },
17
+ },
18
+ emits: ["update:modelValue", "change"],
19
+ setup(props, { emit }) {
20
+ const keyword = ref("");
21
+ const internal = ref(props.multiple ? ([]).concat(props.modelValue || []) : props.modelValue);
22
+ watch(
23
+ () => props.modelValue,
24
+ (v) => {
25
+ internal.value = props.multiple ? ([]).concat(v || []) : v;
26
+ }
27
+ );
28
+
29
+ const isChecked = (val) => {
30
+ const cur = internal.value;
31
+ return Array.isArray(cur) ? cur.includes(val) : cur === val;
32
+ };
33
+
34
+ const toggle = (val) => {
35
+ const list = props.options || [];
36
+ const { label: labelKey, value: valueKey } = props.optionKeys || { label: "label", value: "value" };
37
+ const found = list.find((i) => i[valueKey] === val);
38
+ if (found && found.disabled) return;
39
+ if (props.multiple) {
40
+ const set = new Set(internal.value || []);
41
+ if (set.has(val)) set.delete(val);
42
+ else set.add(val);
43
+ const next = Array.from(set);
44
+ internal.value = next;
45
+ emit("update:modelValue", next);
46
+ emit("change", next);
47
+ } else {
48
+ internal.value = val;
49
+ emit("update:modelValue", val);
50
+ emit("change", val);
51
+ }
52
+ };
53
+
54
+ const filtered = computed(() => {
55
+ const list = props.options || [];
56
+ const { label: labelKey, value: valueKey } = props.optionKeys || { label: "label", value: "value" };
57
+ if (!props.searchable || !keyword.value) return list;
58
+ const k = String(keyword.value).toLowerCase();
59
+ return list.filter((o) => String(o[labelKey]).toLowerCase().includes(k));
60
+ });
61
+
62
+ const displayMeta = computed(() => {
63
+ const list = props.options || [];
64
+ const { label: labelKey, value: valueKey } = props.optionKeys || { label: "label", value: "value" };
65
+ if (props.multiple) {
66
+ const vals = internal.value || [];
67
+ if (!vals.length) return { text: props.label || "请选择", rest: 0 };
68
+ const labels = vals.map((v) => {
69
+ const o = list.find((i) => i[valueKey] === v);
70
+ return o ? o[labelKey] : v;
71
+ });
72
+ if (props.collapseTags) {
73
+ const first = labels[0];
74
+ const rest = labels.length - 1;
75
+ return { text: `${props.label ? props.label + ":" : ""}${first}`, rest };
76
+ }
77
+ if (labels.length > props.maxLabelCount) return { text: (props.label ? props.label + ":" : "") + labels.slice(0, props.maxLabelCount).join("、") + ` 等${labels.length}项`, rest: 0 };
78
+ return { text: (props.label ? props.label + ":" : "") + labels.join("、"), rest: 0 };
79
+ } else {
80
+ const v = internal.value;
81
+ if (v === undefined || v === null || v === "") return { text: props.label || "请选择", rest: 0 };
82
+ const o = list.find((i) => i[valueKey] === v);
83
+ const text = o ? o[labelKey] : String(v);
84
+ return { text: props.label ? `${props.label}:${text}` : text, rest: 0 };
85
+ }
86
+ });
87
+
88
+ const clear = () => {
89
+ if (props.disabled) return;
90
+ internal.value = props.multiple ? [] : null;
91
+ emit("update:modelValue", internal.value);
92
+ emit("change", internal.value);
93
+ };
94
+
95
+ const hasValue = computed(() => (Array.isArray(internal.value) ? internal.value.length > 0 : internal.value !== null && internal.value !== undefined && internal.value !== "") );
96
+
97
+ return () => (
98
+ <el-dropdown hideOnClick={props.multiple ? false : true} disabled={props.disabled}>
99
+ {{
100
+ default: () => (
101
+ <el-button>
102
+ <span style="display:inline-flex;align-items:center;gap:6px;">
103
+ <span>{displayMeta.value.text}</span>
104
+ {props.collapseTags && displayMeta.value.rest > 0 ? (
105
+ <span style="display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 4px;border-radius:9px;background:rgba(64,158,255,0.15);color:#409EFF;font-size:12px;line-height:18px;">{`+${displayMeta.value.rest}`}</span>
106
+ ) : null}
107
+ {hasValue.value ? (
108
+ <span
109
+ title="清除"
110
+ style="display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background:rgba(0,0,0,0.06);cursor:pointer;margin-left:4px;"
111
+ onClick={(e) => {
112
+ e.stopPropagation();
113
+ clear();
114
+ }}
115
+ >
116
+ ×
117
+ </span>
118
+ ) : (
119
+ <span style="margin-left:4px;opacity:0.7;">
120
+ <el-icon><ArrowDown /></el-icon>
121
+ </span>
122
+ )}
123
+ </span>
124
+ </el-button>
125
+ ),
126
+ dropdown: () => (
127
+ <el-dropdown-menu>
128
+ {props.searchable ? (
129
+ <div style="padding:8px 12px;">
130
+ <el-input
131
+ modelValue={keyword.value}
132
+ onUpdate:modelValue={(v) => {
133
+ keyword.value = v;
134
+ }}
135
+ clearable={true}
136
+ placeholder="搜索"
137
+ size="small"
138
+ />
139
+ </div>
140
+ ) : null}
141
+ {filtered.value.map((opt) => (
142
+ <el-dropdown-item
143
+ key={opt[(props.optionKeys || {}).value || "value"]}
144
+ command={opt[(props.optionKeys || {}).value || "value"]}
145
+ disabled={Boolean(opt.disabled)}
146
+ onClick={() => toggle(opt[(props.optionKeys || {}).value || "value"])}
147
+ style={isChecked(opt[(props.optionKeys || {}).value || "value"]) ? "background: rgba(64,158,255,0.08);" : ""}
148
+ >
149
+ {props.itemRender ? (
150
+ props.itemRender(opt, {
151
+ checked: isChecked(opt[(props.optionKeys || {}).value || "value"]),
152
+ })
153
+ ) : (
154
+ <div style="display:flex;align-items:center;justify-content:space-between;min-width:180px;">
155
+ <span>{opt[(props.optionKeys || {}).label || "label"]}</span>
156
+ {isChecked(opt[(props.optionKeys || {}).value || "value"]) ? <span style="color:#67C23A;">✓ 已选</span> : null}
157
+ </div>
158
+ )}
159
+ </el-dropdown-item>
160
+ ))}
161
+ {!filtered.value.length ? <el-dropdown-item disabled={true}>无数据</el-dropdown-item> : null}
162
+ </el-dropdown-menu>
163
+ ),
164
+ }}
165
+ </el-dropdown>
166
+ );
167
+ },
168
+ });
169
+ </script>
@@ -0,0 +1,69 @@
1
+ <script lang="jsx">
2
+ import { defineComponent, ref } from "vue";
3
+ import BtnSelect from "./btnSelect.vue";
4
+
5
+ export default defineComponent({
6
+ name: "BtnSelectView",
7
+ setup() {
8
+ const options = ref([
9
+ { label: "选项一", value: "a" },
10
+ { label: "选项二", value: "b" },
11
+ { label: "选项三", value: "c" },
12
+ { label: "禁用项", value: "d", disabled: true },
13
+ ]);
14
+ const singleValue = ref(null);
15
+ const multiValue = ref([]);
16
+ const searchValue = ref(null);
17
+ return () => (
18
+ <>
19
+ <div style="display:flex; gap:16px; align-items:center; flex-wrap:wrap;">
20
+ <span>按钮下拉框(普通)</span>
21
+ <BtnSelect
22
+ label="名称"
23
+ options={options.value}
24
+ modelValue={singleValue.value}
25
+ onUpdate:modelValue={(v) => {
26
+ singleValue.value = v;
27
+ }}
28
+ />
29
+ <span>按钮下拉框(多选)</span>
30
+ <BtnSelect
31
+ label="名称"
32
+ options={options.value}
33
+ multiple={true}
34
+ modelValue={multiValue.value}
35
+ onUpdate:modelValue={(v) => {
36
+ multiValue.value = v;
37
+ }}
38
+ />
39
+ <span>按钮下拉框(带搜索)</span>
40
+ <BtnSelect
41
+ label="名称"
42
+ options={options.value}
43
+ searchable={true}
44
+ multiple={true}
45
+ collapseTags={true}
46
+ itemRender={(opt, { checked }) => (
47
+ <div style="display:flex;align-items:center;justify-content:space-between;min-width:200px;">
48
+ <span>
49
+ {opt.label}
50
+ {opt.disabled ? <span style="margin-left:8px;color:#F56C6C;">禁用</span> : null}
51
+ </span>
52
+ {checked ? (
53
+ <span style="color:#67C23A;">✓ 已选</span>
54
+ ) : (
55
+ <span style="color:#909399;">点击选择</span>
56
+ )}
57
+ </div>
58
+ )}
59
+ modelValue={searchValue.value}
60
+ onUpdate:modelValue={(v) => {
61
+ searchValue.value = v;
62
+ }}
63
+ />
64
+ </div>
65
+ </>
66
+ );
67
+ },
68
+ });
69
+ </script>
@@ -0,0 +1,44 @@
1
+ <script lang="jsx">
2
+ import { defineComponent, Fragment } from 'vue'
3
+ import { ElButton } from 'element-plus'
4
+ import { useRouter, useRoute } from 'vue-router'
5
+
6
+ export default defineComponent({
7
+ name: 'ComView',
8
+ setup(props, { slots, emit ,attrs}) {
9
+ console.log(props, 'props');
10
+ console.log(attrs, 'attrs');
11
+ const router = useRouter()
12
+ console.log(router, 'router');
13
+ const goHome = () => {
14
+ router.push('/')
15
+ }
16
+ const route = useRoute()
17
+ console.log(route, 'route');
18
+
19
+ return () => (
20
+ <>
21
+ <div>ComView</div>
22
+ <div>props: {attrs.count}</div>
23
+ <ElButton
24
+ type="primary"
25
+ onClick={() => {
26
+ attrs.dialog.close()
27
+ }}
28
+ >
29
+ close dialog
30
+ </ElButton>
31
+ <ElButton
32
+ type="primary"
33
+ onClick={() => {
34
+ goHome()
35
+ attrs.dialog.close()
36
+ }}
37
+ >
38
+ go home
39
+ </ElButton>
40
+ </>
41
+ )
42
+ }
43
+ })
44
+ </script>
@@ -0,0 +1,66 @@
1
+ import { defineComponent, ref, h, render } from 'vue'
2
+ import { ElDialog, ElButton } from 'element-plus'
3
+
4
+ export const openDialog = (options = {}, appContext) => {
5
+ const {
6
+ props = {},
7
+ events = {},
8
+ slots = {}
9
+ } = options
10
+
11
+ const container = document.createElement('div')
12
+ document.body.appendChild(container)
13
+
14
+ let vnode
15
+ const visible = ref(true)
16
+ const DialogHost = defineComponent({
17
+ name: 'FunctionDialogHost',
18
+ setup(props,{expose}) {
19
+ const handleSlot = () => {
20
+ const slotList = {}
21
+ for (const slotName in slots) {
22
+ if (slots.hasOwnProperty(slotName)) {
23
+ const slot = slots[slotName]
24
+ if (slot) {
25
+ slotList[slotName] = slot()
26
+ }
27
+ }
28
+ }
29
+ return slotList
30
+ }
31
+ const cleanup = () => {
32
+ try {
33
+ render(null, container)
34
+ } catch {}
35
+ if (container && container.parentNode) {
36
+ container.parentNode.removeChild(container)
37
+ }
38
+ }
39
+
40
+ // 返回 JSX 渲染函数
41
+ return () => (
42
+ <ElDialog
43
+ modelValue={visible.value}
44
+ onUpdate:modelValue={(v) => { visible.value = v }}
45
+ {...props}
46
+ {...events}
47
+ destroyOnClose={true}
48
+ onClosed={cleanup}
49
+ >
50
+ {handleSlot()}
51
+ </ElDialog>
52
+ )
53
+ }
54
+ })
55
+ vnode = h(DialogHost)
56
+ if (appContext) vnode.appContext = appContext
57
+ render(vnode, container)
58
+ const close = () => {
59
+ visible.value = false
60
+ }
61
+ return {
62
+ close,
63
+ }
64
+ }
65
+
66
+ export default openDialog