afn-basic-components 1.0.0 → 1.1.0

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
@@ -15,26 +15,26 @@ npm install afn-basic-components
15
15
  在 main.js 中引入:
16
16
 
17
17
  ```javascript
18
- import Vue from 'vue'
19
- import AfnBasicComponents from 'afn-basic-components'
20
- import 'afn-basic-components/src/styles/index.scss'
18
+ import Vue from "vue";
19
+ import AfnBasicComponents from "afn-basic-components";
20
+ import "afn-basic-components/styles/index.scss";
21
21
 
22
- Vue.use(AfnBasicComponents)
22
+ Vue.use(AfnBasicComponents);
23
23
  ```
24
24
 
25
25
  ### 按需引入
26
26
 
27
27
  ```javascript
28
- import { GlobalDrawer, MessagePopUp, ProTable } from 'afn-basic-components'
29
- import 'afn-basic-components/src/styles/index.scss'
28
+ import { GlobalDrawer, MessagePopUp, ProTable } from "afn-basic-components";
29
+ import "afn-basic-components/styles/index.scss";
30
30
 
31
31
  export default {
32
32
  components: {
33
33
  GlobalDrawer,
34
34
  MessagePopUp,
35
- ProTable
36
- }
37
- }
35
+ ProTable,
36
+ },
37
+ };
38
38
  ```
39
39
 
40
40
  ## 📚 组件列表
@@ -44,6 +44,7 @@ export default {
44
44
  一个功能强大的抽屉组件,支持标题、内容、宽度、方向等配置。
45
45
 
46
46
  **Props:**
47
+
47
48
  - `visible` (Boolean) - 是否显示抽屉,默认 false
48
49
  - `title` (String) - 抽屉标题
49
50
  - `width` (String) - 抽屉宽度,默认 '50%'
@@ -51,10 +52,12 @@ export default {
51
52
  - `beforeClose` (Function) - 关闭前的回调函数
52
53
 
53
54
  **Events:**
55
+
54
56
  - `close` - 抽屉关闭时触发
55
57
  - `open` - 抽屉打开时触发
56
58
 
57
59
  **示例:**
60
+
58
61
  ```vue
59
62
  <global-drawer
60
63
  :visible.sync="drawerVisible"
@@ -71,6 +74,7 @@ export default {
71
74
  一个美观的消息提示组件,支持多种类型和配置。
72
75
 
73
76
  **Props:**
77
+
74
78
  - `visible` (Boolean) - 是否显示弹窗,默认 false
75
79
  - `type` (String) - 消息类型,可选 'success' | 'warning' | 'info' | 'error',默认 'info'
76
80
  - `title` (String) - 弹窗标题
@@ -79,9 +83,11 @@ export default {
79
83
  - `showClose` (Boolean) - 是否显示关闭按钮,默认 true
80
84
 
81
85
  **Events:**
86
+
82
87
  - `close` - 弹窗关闭时触发
83
88
 
84
89
  **示例:**
90
+
85
91
  ```vue
86
92
  <message-pop-up
87
93
  :visible.sync="messageVisible"
@@ -97,6 +103,7 @@ export default {
97
103
  一个功能强大的表格组件,支持搜索、分页、排序等功能。
98
104
 
99
105
  **Props:**
106
+
100
107
  - `tableData` (Array) - 表格数据
101
108
  - `columns` (Array) - 表格列配置
102
109
  - `loading` (Boolean) - 是否加载中,默认 false
@@ -105,12 +112,14 @@ export default {
105
112
  - `showPagination` (Boolean) - 是否显示分页,默认 true
106
113
 
107
114
  **Events:**
115
+
108
116
  - `search` - 搜索时触发
109
117
  - `reset` - 重置时触发
110
118
  - `page-change` - 页码变化时触发
111
119
  - `size-change` - 每页条数变化时触发
112
120
 
113
121
  **示例:**
122
+
114
123
  ```vue
115
124
  <pro-table
116
125
  :table-data="tableData"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "afn-basic-components",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "基础公共组件库 - 包含GlobalDrawer、MessagePopUp、ProTable等组件和样式",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -0,0 +1,249 @@
1
+ <template>
2
+ <el-drawer
3
+ :title="title"
4
+ :visible.sync="visible"
5
+ direction="rtl"
6
+ :size="computedWidth"
7
+ class="global-drawer"
8
+ :wrapper-closable="!showCancel"
9
+ :modal-click-close="false"
10
+ >
11
+ <!-- 头部 -->
12
+ <div class="drawer-header" :style="{ width: computedWidth }">
13
+ <span class="title">{{ title }}</span>
14
+ <!-- <i class="el-icon-close close-btn" @click="close" /> -->
15
+ <svg-icon
16
+ icon-class="simulation-close"
17
+ class="el-icon-close close-btn"
18
+ @click="close"
19
+ style="width: 32px; height: 32px; cursor: pointer"
20
+ />
21
+ </div>
22
+
23
+ <!-- 内容区域 -->
24
+ <div class="drawer-content">
25
+ <slot></slot>
26
+ </div>
27
+
28
+ <!-- 底部 -->
29
+ <div class="drawer-footer" :style="{ width: computedWidth }">
30
+ <el-button
31
+ v-if="showCancel"
32
+ class="cancel-btn"
33
+ style="background-color: #f2f2f2; color: #333; font-weight: medium"
34
+ @click="handleCancel"
35
+ >{{ cancelText }}</el-button
36
+ >
37
+ <el-button type="primary" @click="handleConfirm">{{
38
+ computedConfirmText
39
+ }}</el-button>
40
+ </div>
41
+ </el-drawer>
42
+ </template>
43
+
44
+ <script>
45
+ export default {
46
+ name: 'GlobalDrawer',
47
+ props: {
48
+ title: {
49
+ type: String,
50
+ default: '标题'
51
+ },
52
+ visible: {
53
+ type: Boolean,
54
+ required: true
55
+ },
56
+ size: {
57
+ type: [String, Number], // 支持字符串和数字类型
58
+ default: '600px'
59
+ },
60
+ cancelText: {
61
+ type: String,
62
+ default: '取消'
63
+ },
64
+ confirmText: {
65
+ type: String,
66
+ default: null
67
+ },
68
+ showCancel: {
69
+ type: Boolean,
70
+ default: true
71
+ }
72
+ },
73
+ data() {
74
+ return {
75
+ // 移除设备类型判断,改为使用媒体查询
76
+ }
77
+ },
78
+ computed: {
79
+ computedWidth() {
80
+ // 直接返回size属性,不再根据设备类型判断
81
+ return typeof this.size === 'number' ? `${this.size}px` : this.size
82
+ },
83
+ computedConfirmText() {
84
+ // 如果传入了confirmText,使用传入的值
85
+ if (this.confirmText) {
86
+ return this.confirmText
87
+ }
88
+ // 否则根据showCancel的值返回默认文本
89
+ return this.showCancel ? '确定' : '关闭'
90
+ }
91
+ },
92
+ methods: {
93
+ close() {
94
+ this.$emit('update:visible', false)
95
+ this.$emit('cancel')
96
+ },
97
+ // 防抖函数 - 支持立即执行模式
98
+ debounce(fn, delay = 300, immediate = true) {
99
+ if (this._debounceTimer) {
100
+ clearTimeout(this._debounceTimer)
101
+ this._debounceTimer = null
102
+ return // 如果在延迟期间再次调用,直接返回不执行
103
+ }
104
+
105
+ if (immediate) {
106
+ // 立即执行模式:第一次调用立即执行
107
+ fn()
108
+ }
109
+
110
+ // 设置延迟期间
111
+ this._debounceTimer = setTimeout(() => {
112
+ this._debounceTimer = null
113
+ }, delay)
114
+ },
115
+ // 添加防抖处理的确认方法
116
+ handleConfirm() {
117
+ this.debounce(
118
+ () => {
119
+ this.$emit('confirm')
120
+ },
121
+ 300,
122
+ true
123
+ )
124
+ },
125
+ handleCancel() {
126
+ this.$emit('cancel')
127
+ }
128
+ }
129
+ }
130
+ </script>
131
+
132
+ <style scoped lang="scss">
133
+ .global-drawer {
134
+ --header-height: 70px;
135
+ --footer-height: 70px;
136
+ }
137
+
138
+ .drawer-header {
139
+ position: fixed;
140
+ top: 0;
141
+ right: 0;
142
+ height: var(--header-height);
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: space-between;
146
+ padding: 0 24px;
147
+ border-bottom: 1px solid #f2f2f2;
148
+ background: white;
149
+ z-index: 2000;
150
+ }
151
+ .title {
152
+ text-align: center;
153
+ color: #333;
154
+ margin: 0;
155
+ font-family: PingFangSC, PingFang SC;
156
+ font-weight: 500;
157
+ font-size: 16px;
158
+ }
159
+
160
+ .drawer-content {
161
+ height: calc(100vh - var(--header-height) - var(--footer-height));
162
+ overflow-y: auto;
163
+ padding: 30px 24px;
164
+ color: #333;
165
+ font-family: PingFangSC, PingFang SC;
166
+ font-size: 16px;
167
+ /* 换行显示 */
168
+ ::v-deep .el-form-item {
169
+ width: 100% !important;
170
+ display: block !important;
171
+
172
+ &__label {
173
+ display: block !important;
174
+ width: 100% !important;
175
+ text-align: left;
176
+ font-size: 14px;
177
+ line-height: 16px;
178
+ margin-bottom: 8px;
179
+ font-family: PingFangSC, PingFang SC;
180
+ }
181
+
182
+ &__content {
183
+ margin-left: 0 !important;
184
+ width: 100% !important;
185
+ display: block !important;
186
+ font-family: PingFangSC, PingFang SC;
187
+ }
188
+ }
189
+
190
+ /* 必填星号换到后面 */
191
+ ::v-deep .el-form-item.is-required:not(.is-no-asterisk) {
192
+ .el-form-item__label {
193
+ &::before {
194
+ content: none !important;
195
+ }
196
+ &::after {
197
+ content: '•' !important;
198
+ color: #f56c6c !important;
199
+ margin-left: 4px !important;
200
+ display: inline !important;
201
+ /* vertical-align: middle; */
202
+ line-height: 1;
203
+ }
204
+ }
205
+ }
206
+ }
207
+
208
+ .drawer-footer {
209
+ position: fixed;
210
+ bottom: 0;
211
+ right: 0;
212
+ height: var(--footer-height);
213
+ display: flex;
214
+ align-items: center;
215
+ justify-content: flex-end;
216
+ padding: 0 24px;
217
+ border-top: 1px solid #f2f2f2;
218
+ background: white;
219
+ z-index: 2000;
220
+ color: #333;
221
+ font-family: PingFangSC, PingFang SC;
222
+ .el-button {
223
+ font-family: PingFangSC, PingFang SC;
224
+ border: none;
225
+ font-weight: 500;
226
+ font-size: 14px;
227
+ }
228
+
229
+ .cancel-btn:hover {
230
+ color: #4a7ff8 !important;
231
+ }
232
+ }
233
+
234
+ // 使用媒体查询实现移动端适配
235
+ @media (max-width: 768px) {
236
+ ::v-deep .el-drawer {
237
+ width: 100% !important;
238
+ }
239
+
240
+ .drawer-header,
241
+ .drawer-footer {
242
+ width: 100% !important;
243
+ }
244
+
245
+ .drawer-content {
246
+ padding: 20px 16px;
247
+ }
248
+ }
249
+ </style>
@@ -0,0 +1,220 @@
1
+ <template>
2
+ <el-dialog
3
+ :visible.sync="visible"
4
+ :width="width"
5
+ :custom-class="'custom-dialog ' + type"
6
+ :close-on-click-modal="!closeOnModalClick"
7
+ :show-close="!closeOnModalClick"
8
+ @close="handleCancel"
9
+ >
10
+ <!-- 标题区域 -->
11
+ <template #title>
12
+ <div class="dialog-header">
13
+ <svg-icon style="width: 24px; height: 24px" :icon-class="type" />
14
+ <span class="header-title">{{ title }}</span>
15
+ </div>
16
+ <div
17
+ class="custom-close"
18
+ @mouseover="isHover = true"
19
+ @mouseleave="isHover = false"
20
+ @click="handleCancel"
21
+ >
22
+ <svg-icon
23
+ :icon-class="isHover ? 'close-hover' : 'close'"
24
+ class="close-icon"
25
+ />
26
+ </div>
27
+ </template>
28
+
29
+ <!-- 内容区域 -->
30
+ <div class="dialog-content">
31
+ <slot>{{ content }}</slot>
32
+ </div>
33
+
34
+ <!-- 按钮区域 -->
35
+ <template #footer>
36
+ <el-button
37
+ v-if="type === 'danger'"
38
+ class="custom-btn"
39
+ style="color: #333333; background-color: #f1f1f1; border: none"
40
+ @click="handleCancel"
41
+ >取消</el-button
42
+ >
43
+ <el-button type="primary" @click="handleConfirm">{{
44
+ confirmText
45
+ }}</el-button>
46
+ </template>
47
+ </el-dialog>
48
+ </template>
49
+
50
+ <script>
51
+ export default {
52
+ name: 'MessagePopUp',
53
+ props: {
54
+ type: {
55
+ type: String,
56
+ default: 'info',
57
+ validator: (v) => ['info', 'success', 'error', 'danger'].includes(v)
58
+ },
59
+ title: {
60
+ type: String,
61
+ default: '提示信息'
62
+ },
63
+ width: {
64
+ type: String,
65
+ default: '500px'
66
+ },
67
+ content: {
68
+ type: String,
69
+ default: ''
70
+ },
71
+ //是否禁止取消
72
+ closeOnModalClick: {
73
+ type: Boolean,
74
+ default: false
75
+ },
76
+ conFirmText: {
77
+ type: String,
78
+ default: ''
79
+ }
80
+ },
81
+ computed: {
82
+ confirmText() {
83
+ // 优先使用传入的confirmText
84
+ return this.conFirmText || (this.type === 'danger' ? '确定' : '我知道了')
85
+ }
86
+ },
87
+ data() {
88
+ return {
89
+ visible: false,
90
+ isHover: false
91
+ }
92
+ },
93
+ methods: {
94
+ open() {
95
+ this.visible = true
96
+ },
97
+ handleConfirm() {
98
+ this.$emit('confirm', 'confirm')
99
+ this.visible = false
100
+ },
101
+ handleCancel() {
102
+ if (this.closeOnModalClick) return
103
+ this.$emit('confirm', 'cancel')
104
+ this.visible = false
105
+ }
106
+ }
107
+ }
108
+ </script>
109
+
110
+ <style scoped lang="scss">
111
+ ::v-deep .el-dialog {
112
+ border-radius: 12px;
113
+ margin: 35% auto;
114
+ }
115
+ ::v-deep .el-dialog:not(.is-fullscreen) {
116
+ margin-top: 33vh !important;
117
+ }
118
+ ::v-deep .el-dialog__header {
119
+ padding: 24px;
120
+ }
121
+ ::v-deep .el-dialog__body {
122
+ padding: 0 24px 24px 60px;
123
+ }
124
+ /* 添加圆角 */
125
+ :deep(.custom-dialog) {
126
+ border-radius: 8px !important;
127
+ margin: 20px !important;
128
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !important;
129
+ }
130
+
131
+ /* 移动端适配 */
132
+ @media (max-width: 768px) {
133
+ ::v-deep .el-dialog {
134
+ width: 90% !important;
135
+ margin: 20% auto !important;
136
+ }
137
+ ::v-deep .el-dialog__header {
138
+ padding: 16px;
139
+ }
140
+ ::v-deep .el-dialog__body {
141
+ padding: 0 16px 16px 40px;
142
+ }
143
+ ::v-deep .el-dialog__footer {
144
+ padding: 0 16px 16px;
145
+ text-align: end;
146
+ }
147
+ .dialog-header {
148
+ padding-bottom: 8px;
149
+ .header-title {
150
+ font-size: 15px;
151
+ }
152
+ }
153
+ .dialog-content {
154
+ font-size: 13px;
155
+ line-height: 20px;
156
+ }
157
+ .custom-close {
158
+ right: 16px;
159
+ top: 16px;
160
+ }
161
+ .el-button {
162
+ min-width: 80px;
163
+ padding: 8px 15px;
164
+ }
165
+ }
166
+
167
+ .dialog-header {
168
+ display: flex;
169
+ align-items: center;
170
+ padding-bottom: 10px;
171
+ font-family: PingFangSC, PingFang SC;
172
+ font-weight: 500;
173
+ font-size: 16px;
174
+ color: #333333;
175
+ line-height: 22px;
176
+ text-align: left;
177
+ font-style: normal;
178
+ .header-title {
179
+ margin-left: 12px;
180
+ }
181
+ }
182
+ .header-icon {
183
+ font-size: 20px;
184
+ margin-right: 8px;
185
+ }
186
+
187
+ .dialog-content {
188
+ font-family: PingFangSC, PingFang SC;
189
+ font-weight: 400;
190
+ font-size: 14px;
191
+ color: #333333;
192
+ line-height: 22px;
193
+ text-align: left;
194
+ font-style: normal;
195
+ }
196
+ .el-button {
197
+ min-width: 88px;
198
+ }
199
+ ::v-deep .el-dialog__header {
200
+ position: relative; /* 为绝对定位提供参考 */
201
+ }
202
+ ::v-deep .el-dialog__headerbtn {
203
+ display: none !important;
204
+ }
205
+
206
+ .custom-close {
207
+ position: absolute;
208
+ right: 24px;
209
+ top: 24px;
210
+ cursor: pointer;
211
+ z-index: 2000;
212
+ transition: transform 0.3s;
213
+
214
+ .close-icon {
215
+ width: 18px;
216
+ height: 18px;
217
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
218
+ }
219
+ }
220
+ </style>
@@ -0,0 +1,352 @@
1
+ <template>
2
+ <div class="pro-table">
3
+ <!-- 搜索区域card -->
4
+ <div class="pro-search-card" v-if="showSearch" ref="searchRef">
5
+ <div class="pro-search">
6
+ <div class="title-container">
7
+ <div class="title-text">
8
+ <slot name="title">
9
+ {{ showTitle || $route.name }}
10
+ </slot>
11
+ </div>
12
+ </div>
13
+ <slot name="search"></slot>
14
+ </div>
15
+ </div>
16
+
17
+ <!-- 表格区域card -->
18
+ <div class="pro-content-card">
19
+ <div class="pro-tool" v-if="toolbarConfig" ref="toolbarRef">
20
+ <div class="pro-xTool">
21
+ <div class="toolbar">
22
+ <div class="toolbar-left">
23
+ <slot name="tools"></slot>
24
+ </div>
25
+ <div class="toolbar-right">
26
+ <el-tooltip
27
+ v-if="toolbarConfig.search"
28
+ class="search-tooltip"
29
+ effect="dark"
30
+ :content="showSearch ? '隐藏搜索' : '显示搜索'"
31
+ placement="top"
32
+ >
33
+ <el-button
34
+ size="mini"
35
+ circle
36
+ icon="el-icon-search"
37
+ @click="showSearch = !showSearch"
38
+ />
39
+ </el-tooltip>
40
+ <slot name="toolButton"></slot>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <div ref="remainingRef" style="flex: 1; overflow: hidden">
46
+ <slot :remainingHeight="remainingHeight"></slot>
47
+ <div ref="footerRef">
48
+ <slot name="footer"></slot>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </template>
54
+
55
+ <script>
56
+ export default {
57
+ name: 'ProTable',
58
+ props: {
59
+ // 显示工具栏相关项
60
+ toolbarConfig: {
61
+ type: [Object, Boolean],
62
+ default: () => {
63
+ return {
64
+ custom: true,
65
+ refresh: true,
66
+ search: true
67
+ }
68
+ }
69
+ },
70
+ fixedHeightOffset: {
71
+ type: Number,
72
+ default: 93
73
+ }
74
+ },
75
+ data() {
76
+ return {
77
+ showSearch: true,
78
+ searchHeight: 0,
79
+ toolbarHeight: 0,
80
+ footerHeight: 0
81
+ }
82
+ },
83
+ computed: {
84
+ refresh() {
85
+ if (this.$listeners.refresh) {
86
+ return { query: () => this.$emit('refresh') }
87
+ } else {
88
+ return false
89
+ }
90
+ },
91
+ showTitle() {
92
+ return this.title || this.$route.meta?.title
93
+ },
94
+ remainingHeight() {
95
+ const total = this.searchHeight + this.toolbarHeight + this.footerHeight
96
+ return `calc(100vh - ${93 + total}px)` // 当前总和231 → 100vh-324px
97
+ }
98
+ },
99
+ mounted() {
100
+ this.calcHeights()
101
+ window.addEventListener('resize', this.calcHeights)
102
+ },
103
+ beforeDestroy() {
104
+ window.removeEventListener('resize', this.calcHeights)
105
+ },
106
+ watch: {
107
+ showSearch() {
108
+ this.$nextTick(() => {
109
+ this.calcHeights()
110
+ })
111
+ }
112
+ },
113
+ methods: {
114
+ calcHeights() {
115
+ this.searchHeight = this.showSearch
116
+ ? this.$refs.searchRef?.clientHeight || 0
117
+ : 0
118
+ this.toolbarHeight = this.$refs.toolbarRef?.clientHeight || 0
119
+ this.footerHeight = this.$refs.footerRef?.clientHeight || 0
120
+ }
121
+ }
122
+ }
123
+ </script>
124
+
125
+ <style lang="scss" scoped>
126
+ .pro-table {
127
+ height: 100%;
128
+ display: flex;
129
+ flex-direction: column;
130
+ color: #333;
131
+ font-family: PingFangSC, PingFang SC;
132
+ }
133
+
134
+ // 搜索区域card
135
+ .pro-search-card {
136
+ width: 100%;
137
+ background-color: #fff;
138
+ border-radius: 12px;
139
+ padding: 24px;
140
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.02);
141
+ margin-bottom: 16px;
142
+ display: flex;
143
+ color: #333;
144
+
145
+ .title-container {
146
+ width: 100%;
147
+ height: 44px;
148
+ border-bottom: 1px solid #f2f2f2;
149
+ margin-bottom: 9px;
150
+
151
+ .title-text {
152
+ display: inline-block;
153
+ height: 100%;
154
+ font-size: 16px;
155
+ font-weight: 500;
156
+ color: #333;
157
+ border-bottom: 2px solid #4a7ff8;
158
+ }
159
+ }
160
+ ::v-deep .el-select-dropdown.el-popper {
161
+ border: none;
162
+ }
163
+ }
164
+
165
+ // 表格区域card
166
+ .pro-content-card {
167
+ flex: 1;
168
+ background-color: #fff;
169
+ border-radius: 12px;
170
+ padding: 24px;
171
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.02);
172
+ display: flex;
173
+ flex-direction: column;
174
+ overflow: hidden;
175
+ color: #333;
176
+ font-weight: normal;
177
+ ::v-deep .el-table__body-wrapper {
178
+ /* max-height: #{v-bind(remainingHeight)};
179
+ height: auto !important;
180
+ overflow-y: auto; */
181
+ &::-webkit-scrollbar {
182
+ width: 6px;
183
+ height: 6px;
184
+ }
185
+ &::-webkit-scrollbar-thumb {
186
+ background: #c1c1c1;
187
+ border-radius: 3px;
188
+ }
189
+ }
190
+ }
191
+
192
+ .pro-search {
193
+ width: 100%;
194
+
195
+ ::v-deep .el-form-item {
196
+ margin-top: 15px;
197
+ margin-bottom: 0px;
198
+ }
199
+ /* ::v-deep .el-form-item:last-child {
200
+ margin-bottom: 0 !important;
201
+ } */
202
+ ::v-deep .el-button {
203
+ font-family: PingFangSC, PingFang SC;
204
+ font-weight: 500;
205
+ font-size: 14px;
206
+ height: 34px;
207
+ min-width: 88px;
208
+ }
209
+ }
210
+
211
+ .pro-tool {
212
+ margin-bottom: 24px;
213
+ }
214
+ .toolbar {
215
+ display: flex;
216
+ justify-content: space-between;
217
+ /* align-items: center;
218
+ margin-bottom: 12px; */
219
+ height: 34px;
220
+ /* ::v-deep .el-button {
221
+ font-size: 14px;
222
+ height: 34px;
223
+ } */
224
+ .toolbar-left {
225
+ ::v-deep .el-button {
226
+ font-family: PingFangSC, PingFang SC;
227
+
228
+ font-weight: 500;
229
+ font-size: 14px;
230
+ height: 34px;
231
+ min-width: 88px;
232
+ }
233
+ }
234
+ }
235
+
236
+ .toolbar-right {
237
+ display: flex;
238
+ gap: 8px;
239
+ align-items: center;
240
+ }
241
+
242
+ .search-tooltip {
243
+ margin-right: 8px;
244
+ }
245
+
246
+ // 移动端适配 (≤768px)
247
+ @media (max-width: 768px) {
248
+ /* .pro-search-card {
249
+ padding: 16px;
250
+ margin-bottom: 12px;
251
+
252
+ .title-container {
253
+ height: 36px;
254
+ margin-bottom: 8px;
255
+
256
+ .title-text {
257
+ font-size: 14px;
258
+ }
259
+ }
260
+ } */
261
+
262
+ .pro-content-card {
263
+ padding: 16px;
264
+ }
265
+
266
+ .pro-tool {
267
+ margin-bottom: 16px;
268
+ }
269
+
270
+ .toolbar {
271
+ flex-direction: row;
272
+ height: auto;
273
+ gap: 12px;
274
+
275
+ .toolbar-left {
276
+ display: flex;
277
+ flex-wrap: wrap;
278
+ gap: 8px;
279
+ width: 85%;
280
+ justify-content: flex-start;
281
+
282
+ ::v-deep .el-button {
283
+ height: 32px;
284
+ min-width: 76px;
285
+ font-size: 13px;
286
+ margin-left: 0px;
287
+ }
288
+
289
+ ::v-deep .el-button--mini {
290
+ height: 28px;
291
+ min-width: 60px;
292
+ font-size: 12px;
293
+ }
294
+ }
295
+
296
+ .toolbar-right {
297
+ width: 15%;
298
+ justify-content: flex-end;
299
+ align-items: self-start;
300
+
301
+ ::v-deep .el-button--mini.is-circle {
302
+ width: 28px;
303
+ height: 28px;
304
+ }
305
+ }
306
+ }
307
+
308
+ .pro-search {
309
+ ::v-deep .el-form-item {
310
+ margin-top: 12px !important;
311
+ }
312
+
313
+ ::v-deep .el-button {
314
+ height: 32px !important;
315
+ min-width: 76px !important;
316
+ font-size: 13px !important;
317
+ }
318
+ }
319
+ }
320
+
321
+ // 平板端适配 (769px-1024px)
322
+ @media (min-width: 769px) and (max-width: 1024px) {
323
+ .pro-search-card {
324
+ padding: 20px !important;
325
+ }
326
+
327
+ .pro-content-card {
328
+ padding: 20px !important;
329
+ }
330
+
331
+ .toolbar {
332
+ .toolbar-left {
333
+ display: flex !important;
334
+ flex-wrap: wrap !important;
335
+ gap: 8px !important;
336
+
337
+ ::v-deep .el-button {
338
+ height: 33px !important;
339
+ min-width: 80px !important;
340
+ font-size: 13px !important;
341
+ }
342
+ }
343
+
344
+ .toolbar-right {
345
+ ::v-deep .el-button--mini.is-circle {
346
+ width: 30px !important;
347
+ height: 30px !important;
348
+ }
349
+ }
350
+ }
351
+ }
352
+ </style>
package/src/index.js ADDED
@@ -0,0 +1,50 @@
1
+ // 导入组件
2
+ import GlobalDrawer from './components/GlobalDrawer/index.vue'
3
+ import MessagePopUp from './components/MessagePopUp/index.vue'
4
+ import ProTable from './components/ProTable/index.vue'
5
+
6
+ // 导入样式
7
+ import './styles/variables.scss'
8
+ import './styles/btn.scss'
9
+ import './styles/element-ui.scss'
10
+ import './styles/index.scss'
11
+ import './styles/sidebar.scss'
12
+ import './styles/tags-view.scss'
13
+ import './styles/transition.scss'
14
+ import './styles/utils.scss'
15
+
16
+ // 组件列表
17
+ const components = [
18
+ GlobalDrawer,
19
+ MessagePopUp,
20
+ ProTable
21
+ ]
22
+
23
+ // 定义 install 方法,接收 Vue 作为参数
24
+ const install = function(Vue) {
25
+ // 判断是否安装
26
+ if (install.installed) return
27
+ install.installed = true
28
+
29
+ // 遍历注册所有组件
30
+ components.forEach(component => {
31
+ Vue.component(component.name, component)
32
+ })
33
+ }
34
+
35
+ // 判断是否是直接引入文件,如果是,就不用调用 Vue.use()
36
+ if (typeof window !== 'undefined' && window.Vue) {
37
+ install(window.Vue)
38
+ }
39
+
40
+ // 导出组件
41
+ export {
42
+ GlobalDrawer,
43
+ MessagePopUp,
44
+ ProTable
45
+ }
46
+
47
+ // 导出 install 方法
48
+ export default {
49
+ install
50
+ }
@@ -20,6 +20,11 @@ $base-logo-light-title-color: #001529; // 🌅 浅色主题Logo标题颜色 -
20
20
 
21
21
  $base-sub-menu-background: transparent; // 🎨 子菜单背景色
22
22
  $base-sub-menu-hover: rgba(202, 210, 228, 0.3); // 🖱️ 子菜单悬停背景色
23
+ $base-menu-hover: rgba(202, 210, 228, 0.3); // 🖱️ 菜单悬停背景色
24
+ $base-sub-menu-active: rgba(202, 210, 228, 0.5); // ✨ 子菜单激活背景色
25
+ $base-sub-menu-active-text: rgb(74, 127, 248); // 💫 子菜单激活文字颜色
26
+ $base-menu-active: rgba(202, 210, 228, 0.5); // ✨ 菜单激活背景色
27
+ $base-menu-active-color: rgb(74, 127, 248); // 💫 菜单激活文字颜色
23
28
 
24
29
  //自定义新增
25
30
  $base-menu-active-background: #fff; // 🌟 新增:菜单选中背景色 -