@suzhou-lab/page-components 1.0.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.
@@ -0,0 +1,296 @@
1
+ <template>
2
+ <div class="filter-form" ref="filterForm">
3
+ <el-form :inline="false" label-position="right">
4
+ <el-row type="flex" :gutter="16">
5
+ <el-col v-for="(item, idx) in visibleItems" :key="item.prop || idx" :span="item.span || 6"
6
+ :class="{ 'is-hidden': !getItemVisible(item) }">
7
+ <el-form-item :label="item.label" :label-width="labelWidth">
8
+ <el-input v-if="item.type === 'input'" v-model="internalModel[item.prop]"
9
+ :placeholder="item.placeholder || '请输入'" :clearable="item.clearable !== false"
10
+ :disabled="item.disabled" />
11
+
12
+ <el-select v-else-if="item.type === 'select'" v-model="internalModel[item.prop]"
13
+ :placeholder="item.placeholder || '请选择'" :clearable="item.clearable !== false"
14
+ :filterable="item.filterable !== false" :multiple="!!item.multiple" :disabled="item.disabled"
15
+ @change="handleItemChange(item)">
16
+ <el-option v-for="opt in resolvedOptions(item)" :key="opt.value" :label="opt.label" :value="opt.value" />
17
+ </el-select>
18
+
19
+ <el-date-picker v-else-if="item.type === 'yearpicker'" v-model="internalModel[item.prop]" type="year"
20
+ value-format="yyyy" :placeholder="item.placeholder || '选择年度'" :clearable="item.clearable !== false"
21
+ :disabled="item.disabled" style="width: 100%" @change="handleItemChange(item)" />
22
+
23
+ <el-date-picker v-else-if="item.type === 'monthpicker'" v-model="internalModel[item.prop]" type="month"
24
+ :value-format="item.valueFormat || 'yyyy-MM'" :placeholder="item.placeholder || '选择月份'"
25
+ :clearable="item.clearable !== false" :disabled="item.disabled" style="width: 100%"
26
+ @change="handleItemChange(item)" />
27
+
28
+ <el-date-picker v-else-if="item.type === 'datepicker'" v-model="internalModel[item.prop]" type="date"
29
+ :value-format="item.valueFormat || 'yyyy-MM-dd'" :placeholder="item.placeholder || '选择日期'"
30
+ :clearable="item.clearable !== false" :disabled="item.disabled" style="width: 100%"
31
+ @change="handleItemChange(item)" />
32
+
33
+ <el-date-picker v-else-if="item.type === 'daterange'" v-model="internalModel[item.prop]" type="daterange"
34
+ :value-format="item.valueFormat || 'yyyy-MM-dd'" range-separator="至" start-placeholder="开始日期"
35
+ end-placeholder="结束日期" :clearable="item.clearable !== false" :disabled="item.disabled" style="width: 100%"
36
+ @change="handleItemChange(item)" />
37
+
38
+ <el-cascader v-else-if="item.type === 'cascader'" v-model="internalModel[item.prop]"
39
+ :options="resolvedOptions(item)" :placeholder="item.placeholder || '请选择'"
40
+ :props="item.cascaderProps || { value: 'value', label: 'label', children: 'children' }"
41
+ :clearable="item.clearable !== false" :filterable="item.filterable !== false" :disabled="item.disabled"
42
+ style="width: 100%" @change="handleItemChange(item)" collapse-tags />
43
+
44
+ <component v-else-if="item.type === 'custom' && item.component" :is="item.component"
45
+ v-model="internalModel[item.prop]" v-bind="item.attrs || {}" @change="handleItemChange(item)" />
46
+ </el-form-item>
47
+ </el-col>
48
+ </el-row>
49
+ </el-form>
50
+
51
+ <div class="filter-actions">
52
+ <div class="filter-actions__collapse" v-if="hasCollapse" @click="toggleCollapse">
53
+ <span class="">{{ localCollapsed ? '展开内容' : '收起' }}</span>
54
+ <svg width="14" height="14" viewBox="0 0 48 48" fill="none" class="chevrons-down"
55
+ :class="localCollapsed ? '' : 'up'">
56
+ <path d="M9.9 22.456l14.142 14.142 14.142-14.142" stroke="#4E5969" stroke-width="2" />
57
+ <path d="M9.9 11.142l14.142 14.142 14.142-14.142" stroke="#4E5969" stroke-width="2" />
58
+ </svg>
59
+ </div>
60
+ <el-button type="primary" :loading="loading" icon="el-icon-search" @click="handleQuery">查询</el-button>
61
+ <el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
62
+ </div>
63
+ </div>
64
+ </template>
65
+
66
+ <script>
67
+ /**
68
+ * filter-form 组件
69
+ * 配置驱动的筛选表单,统一筛选区样式和布局
70
+ *
71
+ * 用法:
72
+ * <filter-form
73
+ * :items="filterItems"
74
+ * v-model="filters"
75
+ * @search="onSearch"
76
+ * @reset="onReset"
77
+ * />
78
+ */
79
+ export default {
80
+ name: 'FilterForm',
81
+ model: {
82
+ prop: 'model',
83
+ event: 'input'
84
+ },
85
+ props: {
86
+ items: {
87
+ type: Array,
88
+ default: () => []
89
+ },
90
+ model: {
91
+ type: Object,
92
+ default: () => ({})
93
+ },
94
+ collapsed: {
95
+ type: Boolean,
96
+ default: true
97
+ },
98
+ defaultRowCount: {
99
+ type: Number,
100
+ default: 1
101
+ },
102
+ loading: {
103
+ type: Boolean,
104
+ default: false
105
+ },
106
+ labelWidth: {
107
+ type: String,
108
+ default: '112px'
109
+ }
110
+ },
111
+ data() {
112
+ return {
113
+ localCollapsed: this.collapsed,
114
+ internalModel: { ...this.model }
115
+ }
116
+ },
117
+ computed: {
118
+ colsPerRow() {
119
+ return 24 / ((this.items[0] && this.items[0].span) || 6)
120
+ },
121
+ maxVisible() {
122
+ return this.defaultRowCount * this.colsPerRow
123
+ },
124
+ hasCollapse() {
125
+ return this.items.length > this.maxVisible
126
+ },
127
+ visibleItems() {
128
+ if (!this.localCollapsed || !this.hasCollapse) return this.items
129
+ return this.items.slice(0, this.maxVisible)
130
+ }
131
+ },
132
+ watch: {
133
+ model: {
134
+ handler(val) {
135
+ if (val) {
136
+ this.internalModel = val
137
+ }
138
+ },
139
+ deep: true,
140
+ immediate: true
141
+ },
142
+ internalModel: {
143
+ handler(val) {
144
+ this.$emit('input', val)
145
+ },
146
+ deep: true
147
+ },
148
+ collapsed(val) {
149
+ this.localCollapsed = val
150
+ }
151
+ },
152
+ methods: {
153
+ getItemVisible(item) {
154
+ if (typeof item.visible === 'function') {
155
+ return item.visible(this.internalModel)
156
+ }
157
+ return item.visible !== false
158
+ },
159
+ resolvedOptions(item) {
160
+ if (typeof item.options === 'function') {
161
+ return item.options(this.internalModel)
162
+ }
163
+ return item.options || []
164
+ },
165
+ handleItemChange(item) {
166
+ if (typeof item.onChange === 'function') {
167
+ item.onChange(this.internalModel[item.prop], this.internalModel)
168
+ }
169
+ },
170
+ toggleCollapse() {
171
+ this.localCollapsed = !this.localCollapsed
172
+ },
173
+ handleQuery() {
174
+ this.$emit('search', { ...this.internalModel })
175
+ },
176
+ handleReset() {
177
+ const resetModel = {}
178
+ this.items.forEach(item => {
179
+ if (item.type === 'daterange') {
180
+ resetModel[item.prop] = null
181
+ } else if (item.type === 'cascader') {
182
+ resetModel[item.prop] = []
183
+ } else {
184
+ resetModel[item.prop] = ''
185
+ }
186
+ })
187
+ this.internalModel = resetModel
188
+ this.$emit('reset', { ...this.internalModel })
189
+ }
190
+ }
191
+ }
192
+ </script>
193
+
194
+ <style lang="scss" scoped>
195
+ // 组件自包含,不依赖项目 _var/_theme 变量
196
+
197
+ .filter-form {
198
+ position: relative;
199
+
200
+ .el-form-item {
201
+ margin-bottom: 18px;
202
+
203
+ &.is-hidden {
204
+ display: none;
205
+ }
206
+ }
207
+
208
+ ::v-deep .el-row--flex {
209
+ flex-wrap: wrap;
210
+ }
211
+
212
+ ::v-deep .el-input,
213
+ ::v-deep .el-select,
214
+ ::v-deep .el-cascader,
215
+ ::v-deep .el-date-editor {
216
+ width: 100%;
217
+ }
218
+
219
+ ::v-deep .el-input__inner {
220
+ height: 40px;
221
+ line-height: 40px;
222
+ background: #F1F3F7;
223
+ border-radius: 4px;
224
+ border: none;
225
+ }
226
+
227
+ ::v-deep .el-select .el-input__inner {
228
+ background: #F1F3F7;
229
+ }
230
+
231
+ .filter-actions {
232
+ display: flex;
233
+ justify-content: flex-end;
234
+ align-items: center;
235
+
236
+ &__collapse {
237
+ display: flex;
238
+ align-items: center;
239
+ justify-content: center;
240
+ align-self: end;
241
+ margin: 0 auto;
242
+ color: #777;
243
+ font-size: 14px;
244
+ user-select: none;
245
+ cursor: pointer;
246
+
247
+ &:hover {
248
+ color: #1F87F0;
249
+ fill: #1F87F0;
250
+ }
251
+ }
252
+ }
253
+
254
+ .chevrons-down {
255
+ margin-left: 4px;
256
+ display: inline-block;
257
+ transition: transform 0.2s;
258
+
259
+ &.up {
260
+ transform: rotate(180deg);
261
+ }
262
+ }
263
+
264
+ // ========== Cascader 多选 Tag 原生样式还原(被 CDN index.css / common.scss / table.scss 覆盖) ==========
265
+ // 基于 element-ui@2.15.7 packages/theme-chalk/src/cascader.scss
266
+ // 覆盖属性不含 background-color、height、border-radius
267
+
268
+ ::v-deep .el-cascader__tags {
269
+ flex-wrap: nowrap;
270
+
271
+ .el-tag {
272
+ &.el-tag--info {
273
+ background-color: rgba(0, 0, 0, 0.06);
274
+ color: #909399;
275
+ font-size: 12px;
276
+ overflow: hidden;
277
+ text-overflow: ellipsis;
278
+ white-space: nowrap;
279
+ }
280
+
281
+ &:first-child {
282
+ flex: 0 1 auto;
283
+ }
284
+
285
+ &:nth-child(2) {
286
+ flex: 0 0 auto;
287
+ }
288
+ }
289
+ }
290
+
291
+ // 搜索输入框
292
+ ::v-deep .el-cascader__search-input {
293
+ display: none;
294
+ }
295
+ }
296
+ </style>
package/index.js ADDED
@@ -0,0 +1,20 @@
1
+ // 页面布局组件统一导出
2
+ // 在 main.js 中通过 import '@/components/page' 全局注册
3
+ // 组件本体位于 src/shared/components/page/,通过 webpack alias 被各微应用引用
4
+
5
+ import FilterForm from './filter-form.vue'
6
+ import ListPage from './list-page.vue'
7
+
8
+ const install = function (Vue) {
9
+ if (install.installed) return
10
+ Vue.component('filter-form', FilterForm)
11
+ Vue.component('list-page', ListPage)
12
+ }
13
+
14
+ // 确保自动注册(当用 script 标签引入时)
15
+ if (typeof window !== 'undefined' && window.Vue) {
16
+ install(window.Vue)
17
+ }
18
+
19
+ export { FilterForm, ListPage }
20
+ export default { install }
package/list-page.vue ADDED
@@ -0,0 +1,335 @@
1
+ <template>
2
+ <el-container class="list-page" ref="listPage">
3
+ <el-aside class="list-page__aside" :width="asideWidth" v-if="$slots.aside">
4
+ <slot name="aside" />
5
+ </el-aside>
6
+ <el-main class="list-page__main">
7
+ <el-card v-if="hasFilterSlot" class="list-page__filter" shadow="never">
8
+ <slot name="filter" />
9
+ </el-card>
10
+
11
+ <el-card class="list-page__table-card" shadow="never">
12
+ <div v-if="hasToolbarSlot" class="list-page__toolbar">
13
+ <slot name="toolbar" />
14
+ </div>
15
+
16
+ <div class="list-page__table-wrapper" ref="tableWrapper">
17
+ <slot />
18
+ </div>
19
+
20
+ <div v-if="hasPaginationSlot" class="list-page__pagination">
21
+ <slot name="pagination" />
22
+ </div>
23
+ </el-card>
24
+ </el-main>
25
+ </el-container>
26
+ </template>
27
+
28
+ <script>
29
+ export default {
30
+ name: 'ListPage',
31
+ provide() {
32
+ return {
33
+ listPage: this
34
+ }
35
+ },
36
+ props: {
37
+ sidebarWidth: {
38
+ type: String,
39
+ default: '240px'
40
+ },
41
+ asideWidth: {
42
+ type: String,
43
+ default: '240px'
44
+ }
45
+ },
46
+ data() {
47
+ return {
48
+ _tableHeight: 300
49
+ }
50
+ },
51
+ computed: {
52
+ tableHeight() {
53
+ return this._tableHeight
54
+ },
55
+ hasFilterSlot() {
56
+ return !!this.$slots.filter || !!this.$scopedSlots.filter
57
+ },
58
+ hasToolbarSlot() {
59
+ return !!this.$slots.toolbar || !!this.$scopedSlots.toolbar
60
+ },
61
+ hasPaginationSlot() {
62
+ return !!this.$slots.pagination || !!this.$scopedSlots.pagination
63
+ }
64
+ },
65
+ mounted() {
66
+ this.calcTableHeight()
67
+ this.initObserver()
68
+ window.addEventListener('resize', this.calcTableHeight)
69
+ },
70
+ beforeDestroy() {
71
+ if (this._observer) this._observer.disconnect()
72
+ window.removeEventListener('resize', this.calcTableHeight)
73
+ },
74
+ methods: {
75
+ initObserver() {
76
+ const wrapper = this.$refs.tableWrapper
77
+ if (!wrapper || typeof ResizeObserver === 'undefined') return
78
+ this._observer = new ResizeObserver(() => this.calcTableHeight())
79
+ this._observer.observe(wrapper)
80
+ },
81
+ calcTableHeight() {
82
+ this.$nextTick(() => {
83
+ const wrapper = this.$refs.tableWrapper
84
+ if (!wrapper) return
85
+ const wrapperHeight = wrapper.clientHeight
86
+ if (wrapperHeight > 0) {
87
+ this._tableHeight = Math.max(100, Math.floor(wrapperHeight))
88
+ }
89
+ })
90
+ }
91
+ }
92
+ }
93
+ </script>
94
+
95
+ <style lang="scss" scoped>
96
+ // 组件自包含,不依赖项目 _var/_theme 变量
97
+ // 所有可定制属性均通过 CSS 变量暴露,子应用可在父级或 :root 中覆盖
98
+ // 格式:var(--变量名, 默认值)
99
+
100
+ .list-page {
101
+ height: 100% !important;
102
+ overflow: hidden;
103
+
104
+ ::v-deep .el-card {
105
+ border-radius: 6px;
106
+ border: none;
107
+ }
108
+
109
+ &__aside {
110
+ display: flex !important;
111
+ flex-direction: column !important;
112
+ overflow: hidden;
113
+ margin-right: var(--list-page-spacing, 16px);
114
+ }
115
+
116
+ &__main {
117
+ display: flex !important;
118
+ flex-direction: column !important;
119
+ padding: 0 !important;
120
+ overflow: hidden;
121
+ height: 100% !important;
122
+ }
123
+
124
+ &__filter {
125
+ flex-shrink: 0;
126
+ margin-bottom: var(--list-page-spacing, 16px);
127
+ }
128
+
129
+ &__table-card {
130
+ flex: 1;
131
+ min-height: 0;
132
+ display: flex !important;
133
+ flex-direction: column !important;
134
+ overflow: hidden;
135
+
136
+ ::v-deep .el-card__body {
137
+ display: flex !important;
138
+ flex-direction: column !important;
139
+ min-height: 0;
140
+ flex: 1;
141
+ overflow: hidden;
142
+ padding: 0;
143
+ }
144
+
145
+ ::v-deep .el-table {
146
+ thead {
147
+ tr {
148
+ th {
149
+ background-color: var(--list-page-thead-bg, #E2EDFF);
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ ::v-deep .el-table__fixed-right,
156
+ ::v-deep .el-table__fixed {
157
+ background-color: var(--list-page-gutter-bg, #F1F3F7);
158
+ }
159
+ }
160
+
161
+ &__toolbar {
162
+ flex-shrink: 0;
163
+ padding: var(--list-page-spacing, 16px);
164
+ display: flex !important;
165
+ flex-wrap: wrap;
166
+ justify-content: flex-end;
167
+ min-width: 0;
168
+
169
+ ::v-deep .el-table-show {
170
+ margin-left: 10px;
171
+ }
172
+ }
173
+
174
+ &__table-wrapper {
175
+ flex: 1;
176
+ min-height: 0;
177
+ overflow: hidden;
178
+ position: relative;
179
+ padding: 0 var(--list-page-spacing, 16px);
180
+
181
+ ::v-deep .el-table {
182
+ width: 100% !important;
183
+ height: 100% !important;
184
+ }
185
+
186
+ ::v-deep .el-table__body-wrapper {
187
+
188
+ &::-webkit-scrollbar {
189
+ width: var(--list-page-scrollbar-width, 8px);
190
+ height: var(--list-page-scrollbar-height, 8px);
191
+ }
192
+
193
+ &::-webkit-scrollbar-track {
194
+ background-color: var(--list-page-gutter-bg, #F1F3F7);
195
+ border-radius: 0;
196
+ }
197
+
198
+ &::-webkit-scrollbar-thumb {
199
+ background-color: var(--list-page-scrollbar-thumb-bg, #c0c4cc);
200
+ border-radius: 4px;
201
+ }
202
+ }
203
+
204
+ // 表头排序/筛选图标对齐
205
+ ::v-deep .el-table__cell {
206
+ .caret-wrapper {
207
+ position: absolute;
208
+ right: 10px;
209
+ top: 50%;
210
+ transform: translateY(-50%);
211
+
212
+ &:has(+ .el-table__column-filter-trigger) {
213
+ right: 22px;
214
+ }
215
+ }
216
+
217
+ .el-table__column-filter-trigger {
218
+ position: absolute;
219
+ right: 10px;
220
+ top: 50%;
221
+ transform: translateY(-50%);
222
+
223
+ i {
224
+ transform: scale(var(--list-page-table-filter-icon-scale, 1));
225
+ }
226
+ }
227
+ }
228
+
229
+ ::v-deep .el-table__header-wrapper {
230
+ height: var(--list-page-table-header-wrapper-height, initial);
231
+ }
232
+
233
+ ::v-deep .el-table__header {
234
+ table-layout: fixed !important;
235
+
236
+ th.el-table__cell {
237
+ .cell {
238
+ height: var(--list-page-table-header-cell-height, 24px);
239
+ line-height: var(--list-page-table-header-cell-line-height, 24px);
240
+ }
241
+ }
242
+ }
243
+
244
+ ::v-deep .el-table--border {
245
+ .el-table__header {
246
+ th.el-table__cell {
247
+ border-right: var(--list-page-table-header-cell-border-right, 1px solid rgba(0, 0, 0, 0.06));
248
+
249
+ // 检测 cell 内是否实际包含排序/筛选图标(不再依赖不准确的 is-leaf 类)
250
+ .cell:has(.caret-wrapper) {
251
+ padding-right: calc(var(--list-page-table-header-cell-is-sortable-padding-right, 24px) + 10px);
252
+ }
253
+
254
+ .cell:has(.el-table__column-filter-trigger) {
255
+ padding-right: calc(var(--list-page-table-header-cell-is-leaf-padding-right, 16px) + 10px);
256
+ }
257
+
258
+ .cell:has(.caret-wrapper):has(.el-table__column-filter-trigger) {
259
+ padding-right: calc(var(--list-page-table-header-cell-is-leaf-and-filter-padding-right, 12px) + var(--list-page-table-header-cell-is-sortable-padding-right, 24px) + 10px);
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+
266
+ &__pagination {
267
+ flex-shrink: 0;
268
+ display: flex !important;
269
+ justify-content: flex-end;
270
+ padding: var(--list-page-spacing, 16px);
271
+ margin: 0;
272
+
273
+ ::v-deep .el-pagination {
274
+ margin-top: 0;
275
+ padding: 0;
276
+ text-align: end;
277
+
278
+ :last-child {
279
+ margin-right: 0;
280
+ }
281
+
282
+ &.is-background .btn-next,
283
+ &.is-background .btn-prev,
284
+ &.is-background .el-pager li {
285
+ min-width: var(--list-page-pagination-btn-size, 32px);
286
+ height: var(--list-page-pagination-btn-size, 32px);
287
+ line-height: var(--list-page-pagination-btn-size, 32px);
288
+ border-radius: 2px;
289
+ font-size: var(--list-page-pagination-btn-font-size, 14px);
290
+ font-weight: 500;
291
+ color: var(--list-page-pagination-btn-color, #323233);
292
+ }
293
+
294
+ &.is-background .el-pager li:not(.disabled).active {
295
+ background: var(--list-page-pagination-active-bg, #1F87F0);
296
+ border-radius: 2px;
297
+ font-size: var(--list-page-pagination-btn-font-size, 14px);
298
+ font-weight: 500;
299
+ color: var(--list-page-pagination-active-color, #FFFFFF);
300
+ }
301
+
302
+ .el-select .el-input .el-input__inner {
303
+ height: var(--list-page-pagination-btn-size, 32px) !important;
304
+ font-size: var(--list-page-pagination-btn-font-size, 14px);
305
+ font-weight: 400;
306
+ color: var(--list-page-pagination-text-color, #333);
307
+ background-color: var(--list-page-pagination-input-bg, #F1F3F7);
308
+ }
309
+
310
+ &__editor.el-input .el-input__inner {
311
+ height: var(--list-page-pagination-btn-size, 32px);
312
+ background: var(--list-page-pagination-input-bg-editor, #FFFFFF);
313
+ border-radius: 2px;
314
+ border: 1px solid var(--list-page-pagination-input-border, #DCDEE0);
315
+ color: var(--list-page-pagination-text-color, #333);
316
+ font-size: var(--list-page-pagination-btn-font-size, 14px);
317
+ }
318
+
319
+ &__jump {
320
+ margin-left: 8px;
321
+ font-size: var(--list-page-pagination-btn-font-size, 14px);
322
+ font-weight: 400;
323
+ color: var(--list-page-pagination-text-color, #333);
324
+ }
325
+
326
+ &__total {
327
+ font-size: var(--list-page-pagination-btn-font-size, 14px);
328
+ font-weight: 400;
329
+ color: var(--list-page-pagination-text-color, #333);
330
+ margin-right: 4px;
331
+ }
332
+ }
333
+ }
334
+ }
335
+ </style>
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@suzhou-lab/page-components",
3
+ "version": "1.0.0",
4
+ "description": "苏州实验室 UMC 微应用统一列表页面组件 — list-page 布局容器 + filter-form 配置驱动筛选表单,附带 AI 改造技能",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "install-skills": "bin/install-skills.js"
8
+ },
9
+ "files": [
10
+ "index.js",
11
+ "list-page.vue",
12
+ "filter-form.vue",
13
+ "bin/",
14
+ "skills/",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "test": "echo \"暂无测试\" && exit 0"
19
+ },
20
+ "keywords": [
21
+ "vue",
22
+ "vue2",
23
+ "element-ui",
24
+ "list-page",
25
+ "filter-form",
26
+ "table",
27
+ "qiankun",
28
+ "micro-app",
29
+ "umc"
30
+ ],
31
+ "author": "苏州实验室",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "http://git.inspur.com/sbg/gih/biz-36/suzhou/umc-shared.git"
36
+ },
37
+ "peerDependencies": {
38
+ "vue": "^2.6.0",
39
+ "element-ui": "^2.15.0"
40
+ }
41
+ }