befly-admin 3.4.8 → 3.4.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly-admin",
3
- "version": "3.4.8",
3
+ "version": "3.4.9",
4
4
  "description": "Befly Admin - 基于 Vue3 + OpenTiny Vue 的后台管理系统",
5
5
  "type": "module",
6
6
  "private": false,
@@ -36,25 +36,27 @@
36
36
  "vue-router": "^4.6.3"
37
37
  },
38
38
  "devDependencies": {
39
- "@befly-addon/admin": "1.0.12",
39
+ "@befly-addon/admin": "1.0.13",
40
40
  "@iconify-json/lucide": "^1.2.72",
41
41
  "@opentiny/unplugin-tiny-vue": "^1.0.0",
42
+ "@unocss/preset-attributify": "^66.5.6",
43
+ "@unocss/preset-uno": "^66.5.6",
42
44
  "@vitejs/plugin-vue": "^6.0.1",
43
45
  "@vue-macros/reactivity-transform": "^3.1.1",
44
- "sass": "^1.93.3",
46
+ "sass": "^1.94.0",
45
47
  "typescript": "^5.9.3",
48
+ "unocss": "^66.5.6",
46
49
  "unplugin-auto-import": "^20.2.0",
47
- "unplugin-icons": "^0.22.0",
50
+ "unplugin-icons": "^22.5.0",
48
51
  "unplugin-vue-components": "^30.0.0",
49
- "unplugin-vue-router": "^0.10.8",
52
+ "unplugin-vue-router": "^0.16.1",
50
53
  "vite": "^7.2.2",
51
54
  "vite-plugin-vue-devtools": "^8.0.3",
52
- "vite-plugin-vue-layouts-next": "^1.2.0",
53
55
  "vue-tsc": "^3.1.3"
54
56
  },
55
57
  "engines": {
56
58
  "node": ">=24.0.0",
57
59
  "pnpm": ">=10.0.0"
58
60
  },
59
- "gitHead": "40b4c3e6591454ff060416a6275142792e7de66c"
61
+ "gitHead": "82f9de50d3c014ba80f68556da05dadcdc8d4c92"
60
62
  }
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <router-view />
3
+ </template>
4
+
5
+ <script setup>
6
+ // 空布局 - 不包含任何框架结构
7
+ // 用于登录页等不需要导航栏和侧边栏的页面
8
+ </script>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <router-view />
3
+ </template>
4
+
5
+ <script setup>
6
+ // 布局 2 - 空布局
7
+ // 用于特殊页面,不包含任何框架结构
8
+ </script>
@@ -18,10 +18,13 @@
18
18
 
19
19
  <!-- 菜单栏 -->
20
20
  <div class="layout-menu">
21
- <tiny-tree-menu :data="$Data.userMenus" :props="{ label: 'name' }" node-key="id" :node-height="40" :show-filter="false" :default-expanded-keys="$Data.expandedKeys" :default-expanded-keys-highlight="$Data.currentNodeKey" style="height: 100%" only-check-children width-adapt @node-click="$Method.onMenuClick">
21
+ <tiny-tree-menu :ref="(el) => ($From.treeMenuRef = el)" :data="$Data.userMenus" :props="{ label: 'name' }" node-key="id" :node-height="40" :show-filter="false" :default-expanded-keys="$Data.expandedKeys" style="height: 100%" only-check-children width-adapt @node-click="$Method.onMenuClick">
22
22
  <template #default="{ data }">
23
23
  <span class="menu-item">
24
- <i-lucide:square style="width: 16px; height: 16px; margin-right: 8px; vertical-align: middle" />
24
+ <!-- 根据路径和是否有子节点显示不同图标 -->
25
+ <i-lucide:home v-if="data.path === '/addon/admin/'" />
26
+ <i-lucide:folder v-else-if="data.children && data.children.length > 0" />
27
+ <i-lucide:file-text v-else />
25
28
  <span>{{ data.name }}</span>
26
29
  </span>
27
30
  </template>
@@ -43,9 +46,14 @@ const router = useRouter();
43
46
  const route = useRoute();
44
47
  const global = useGlobal();
45
48
 
49
+ const $From = {
50
+ treeMenuRef: null
51
+ };
52
+
46
53
  // 响应式数据
47
54
  const $Data = $ref({
48
55
  userMenus: [],
56
+ userMenusFlat: [], // 一维菜单数据
49
57
  expandedKeys: [],
50
58
  currentNodeKey: 0,
51
59
  userInfo: {
@@ -60,7 +68,8 @@ const $Method = {
60
68
  async fetchUserMenus() {
61
69
  try {
62
70
  const { data } = await $Http('/addon/admin/menu/all');
63
- // 将一维数组转换为树形结构(最多2级)
71
+ // 保存一维数据
72
+ $Data.userMenusFlat = data;
64
73
  $Data.userMenus = arrayToTree(data);
65
74
  $Method.setActiveMenu();
66
75
  } catch (error) {
@@ -68,32 +77,40 @@ const $Method = {
68
77
  }
69
78
  },
70
79
 
71
- // 设置当前激活的菜单(2级菜单专用)
80
+ // 设置当前激活的菜单(从一维数据查找并构建父级链)
72
81
  setActiveMenu() {
73
82
  const currentPath = route.path;
74
83
 
75
- // 遍历父级菜单
76
- for (const parent of $Data.userMenus) {
77
- // 检查父级菜单
78
- if (parent.path === currentPath) {
79
- $Data.currentNodeKey = parent.id;
80
- $Data.expandedKeys = [parent.id];
81
- return;
82
- }
84
+ // 在一维数据中查找当前路径对应的菜单
85
+ const currentMenu = $Data.userMenusFlat.find((menu) => menu.path === currentPath);
83
86
 
84
- // 检查子级菜单
85
- if (parent.children?.length) {
86
- for (const child of parent.children) {
87
- if (child.path === currentPath) {
88
- nextTick(() => {
89
- $Data.currentNodeKey = child.id;
90
- $Data.expandedKeys = [parent.id];
91
- });
92
- return;
93
- }
94
- }
87
+ if (!currentMenu) {
88
+ return;
89
+ }
90
+
91
+ // 构建展开的父级链
92
+ const expandedKeys = [];
93
+ let menu = currentMenu;
94
+
95
+ // 向上查找所有父级
96
+ while (menu.pid) {
97
+ const parent = $Data.userMenusFlat.find((m) => m.id === menu.pid);
98
+ if (parent) {
99
+ expandedKeys.unshift(parent.id);
100
+ menu = parent;
101
+ } else {
102
+ break;
95
103
  }
96
104
  }
105
+
106
+ // 使用 nextTick 确保 DOM 更新后再设置高亮
107
+ nextTick(() => {
108
+ $Data.expandedKeys = expandedKeys;
109
+ // 使用 setCurrentKey 方法设置当前高亮节点
110
+ if ($From.treeMenuRef) {
111
+ $From.treeMenuRef.setCurrentKey(currentMenu.id);
112
+ }
113
+ });
97
114
  },
98
115
 
99
116
  // 处理菜单点击
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="layout-none">
3
+ <RouterView />
4
+ </div>
5
+ </template>
package/src/main.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import App from './App.vue';
2
2
 
3
+ // 引入 UnoCSS 样式
4
+ import 'virtual:uno.css';
5
+
3
6
  // 引入全局基础样式(reset、通用类、滚动条等)
4
7
  import '@/styles/global.scss';
5
8
 
@@ -0,0 +1,27 @@
1
+ [
2
+ {
3
+ "path": "/addon",
4
+ "children": [
5
+ {
6
+ "path": "admin",
7
+ "children": [
8
+ { "path": "", "children": [{ "path": "", "name": "/addon/admin//" }] },
9
+ { "path": "403", "children": [{ "path": "", "name": "/addon/admin/403/" }] },
10
+ { "path": "admin", "children": [{ "path": "", "name": "/addon/admin/admin/" }] },
11
+ { "path": "dict", "children": [{ "path": "", "name": "/addon/admin/dict/" }] },
12
+ { "path": "login", "children": [{ "path": "index_1", "name": "/addon/admin/login/index_1" }] },
13
+ { "path": "menu", "children": [{ "path": "", "name": "/addon/admin/menu/", "meta": { "layout": "default", "title": "菜单管理" } }] },
14
+ {
15
+ "path": "news",
16
+ "children": [
17
+ { "path": "", "name": "/addon/admin/news/" },
18
+ { "path": "detail", "children": [{ "path": "", "name": "/addon/admin/news/detail/" }] }
19
+ ]
20
+ },
21
+ { "path": "role", "children": [{ "path": "", "name": "/addon/admin/role/" }] },
22
+ { "path": "user", "children": [{ "path": "", "name": "/addon/admin/user/" }] }
23
+ ]
24
+ }
25
+ ]
26
+ }
27
+ ]
@@ -1,16 +1,11 @@
1
1
  import { createRouter, createWebHashHistory } from 'vue-router';
2
+ import type { RouteRecordRaw } from 'vue-router';
2
3
  import { routes, handleHotUpdate } from 'vue-router/auto-routes';
3
- import { setupLayouts } from 'virtual:generated-layouts';
4
4
  import { $Storage } from '@/plugins/storage';
5
+ import { Layouts } from '@befly-addon/admin/util';
5
6
 
6
- // 应用布局系统
7
- const layoutRoutes = setupLayouts(routes);
8
-
9
- // 打印自动生成的路由信息
10
- console.log('=== 自动生成的路由列表 ===');
11
- console.log(`路由总数: ${layoutRoutes.length}`);
12
- console.dir(layoutRoutes);
13
- console.log('========================');
7
+ // 应用自定义布局系统
8
+ const layoutRoutes = Layouts(routes);
14
9
 
15
10
  /**
16
11
  * 创建并导出路由实例
@@ -30,17 +25,19 @@ if (import.meta.hot) {
30
25
  router.beforeEach(async (to, from, next) => {
31
26
  const token = $Storage.local.get('token');
32
27
 
33
- // 判断是否为公开路由:meta.public 为 true 表示公开路由
34
- const isPublicRoute = to.meta?.public === true;
28
+ // 0. 根路径重定向
29
+ if (to.path === '/') {
30
+ return next(token ? '/addon/admin' : '/addon/admin/login');
31
+ }
35
32
 
36
33
  // 1. 未登录且访问非公开路由 → 跳转登录
37
- if (!token && !isPublicRoute) {
38
- return next('/internal/login');
34
+ if (!token && to.meta?.public !== true && to.path !== '/addon/admin/login') {
35
+ return next('/addon/admin/login');
39
36
  }
40
37
 
41
38
  // 2. 已登录访问登录页 → 跳转首页
42
- if (token && to.path === '/internal/login') {
43
- return next('/');
39
+ if (token && to.path === '/addon/admin/login') {
40
+ return next('/addon/admin');
44
41
  }
45
42
 
46
43
  next();
@@ -23,6 +23,7 @@ declare global {
23
23
  const customRef: typeof import('vue').customRef
24
24
  const defineAsyncComponent: typeof import('vue').defineAsyncComponent
25
25
  const defineComponent: typeof import('vue').defineComponent
26
+ const definePage: typeof import('unplugin-vue-router/runtime').definePage
26
27
  const defineStore: typeof import('pinia').defineStore
27
28
  const effectScope: typeof import('vue').effectScope
28
29
  const getActivePinia: typeof import('pinia').getActivePinia
@@ -19,11 +19,16 @@ declare module 'vue' {
19
19
  'ILucide:circle': typeof import('~icons/lucide/circle')['default']
20
20
  'ILucide:clock': typeof import('~icons/lucide/clock')['default']
21
21
  'ILucide:cloud': typeof import('~icons/lucide/cloud')['default']
22
+ 'ILucide:code': typeof import('~icons/lucide/code')['default']
22
23
  'ILucide:cpu': typeof import('~icons/lucide/cpu')['default']
23
24
  'ILucide:database': typeof import('~icons/lucide/database')['default']
24
25
  'ILucide:disc': typeof import('~icons/lucide/disc')['default']
26
+ 'ILucide:fileText': typeof import('~icons/lucide/file-text')['default']
27
+ 'ILucide:folder': typeof import('~icons/lucide/folder')['default']
25
28
  'ILucide:hardDrive': typeof import('~icons/lucide/hard-drive')['default']
29
+ 'ILucide:home': typeof import('~icons/lucide/home')['default']
26
30
  'ILucide:info': typeof import('~icons/lucide/info')['default']
31
+ 'ILucide:lock': typeof import('~icons/lucide/lock')['default']
27
32
  'ILucide:logOut': typeof import('~icons/lucide/log-out')['default']
28
33
  'ILucide:mail': typeof import('~icons/lucide/mail')['default']
29
34
  'ILucide:menu': typeof import('~icons/lucide/menu')['default']
@@ -32,6 +37,7 @@ declare module 'vue' {
32
37
  'ILucide:rotateCw': typeof import('~icons/lucide/rotate-cw')['default']
33
38
  'ILucide:server': typeof import('~icons/lucide/server')['default']
34
39
  'ILucide:settings': typeof import('~icons/lucide/settings')['default']
40
+ 'ILucide:smile': typeof import('~icons/lucide/smile')['default']
35
41
  'ILucide:square': typeof import('~icons/lucide/square')['default']
36
42
  'ILucide:trash2': typeof import('~icons/lucide/trash2')['default']
37
43
  'ILucide:trendingUp': typeof import('~icons/lucide/trending-up')['default']
@@ -44,6 +50,8 @@ declare module 'vue' {
44
50
  RouterView: typeof import('vue-router')['RouterView']
45
51
  TinyAvatar: typeof import('@opentiny/vue-avatar')['default']
46
52
  TinyButton: typeof import('@opentiny/vue-button')['default']
53
+ TinyCheckbox: typeof import('@opentiny/vue-checkbox')['default']
54
+ TinyCheckboxGroup: typeof import('@opentiny/vue-checkbox-group')['default']
47
55
  TinyCol: typeof import('@opentiny/vue-col')['default']
48
56
  TinyDialogBox: typeof import('@opentiny/vue-dialog-box')['default']
49
57
  TinyDivider: typeof import('@opentiny/vue-divider')['default']
@@ -62,7 +70,10 @@ declare module 'vue' {
62
70
  TinyRadio: typeof import('@opentiny/vue-radio')['default']
63
71
  TinyRadioGroup: typeof import('@opentiny/vue-radio-group')['default']
64
72
  TinyRow: typeof import('@opentiny/vue-row')['default']
73
+ TinySearch: typeof import('@opentiny/vue-search')['default']
74
+ TinySelect: typeof import('@opentiny/vue-select')['default']
65
75
  TinyTag: typeof import('@opentiny/vue-tag')['default']
76
+ TinyTree: typeof import('@opentiny/vue-tree')['default']
66
77
  TinyTreeMenu: typeof import('@opentiny/vue-tree-menu')['default']
67
78
  TinyUserHead: typeof import('@opentiny/vue-user-head')['default']
68
79
  }
@@ -22,7 +22,7 @@ declare module 'vue-router/auto-routes' {
22
22
  '/addon/admin/403/': RouteRecordInfo<'/addon/admin/403/', '/addon/admin/403', Record<never, never>, Record<never, never>>,
23
23
  '/addon/admin/admin/': RouteRecordInfo<'/addon/admin/admin/', '/addon/admin/admin', Record<never, never>, Record<never, never>>,
24
24
  '/addon/admin/dict/': RouteRecordInfo<'/addon/admin/dict/', '/addon/admin/dict', Record<never, never>, Record<never, never>>,
25
- '/addon/admin/login/': RouteRecordInfo<'/addon/admin/login/', '/addon/admin/login', Record<never, never>, Record<never, never>>,
25
+ '/addon/admin/login/index_1': RouteRecordInfo<'/addon/admin/login/index_1', '/addon/admin/login/index_1', Record<never, never>, Record<never, never>>,
26
26
  '/addon/admin/menu/': RouteRecordInfo<'/addon/admin/menu/', '/addon/admin/menu', Record<never, never>, Record<never, never>>,
27
27
  '/addon/admin/news/': RouteRecordInfo<'/addon/admin/news/', '/addon/admin/news', Record<never, never>, Record<never, never>>,
28
28
  '/addon/admin/news/detail/': RouteRecordInfo<'/addon/admin/news/detail/', '/addon/admin/news/detail', Record<never, never>, Record<never, never>>,
package/vite.config.ts CHANGED
@@ -2,7 +2,6 @@ import { defineConfig } from 'vite';
2
2
  import vue from '@vitejs/plugin-vue';
3
3
  import VueRouter from 'unplugin-vue-router/vite';
4
4
  import { VueRouterAutoImports } from 'unplugin-vue-router';
5
- import Layouts from 'vite-plugin-vue-layouts-next';
6
5
  import VueDevTools from 'vite-plugin-vue-devtools';
7
6
  import AutoImport from 'unplugin-auto-import/vite';
8
7
  import Components from 'unplugin-vue-components/vite';
@@ -10,6 +9,7 @@ import Icons from 'unplugin-icons/vite';
10
9
  import IconsResolver from 'unplugin-icons/resolver';
11
10
  import ReactivityTransform from '@vue-macros/reactivity-transform/vite';
12
11
  import { TinyVueSingleResolver } from '@opentiny/unplugin-tiny-vue';
12
+ import UnoCSS from 'unocss/vite';
13
13
  import { fileURLToPath, URL } from 'node:url';
14
14
  import { readdirSync, existsSync } from 'node:fs';
15
15
  import { join } from 'node:path';
@@ -53,6 +53,9 @@ const routesFolders = scanBeflyAddonViews();
53
53
  export default defineConfig({
54
54
  // 插件配置
55
55
  plugins: [
56
+ // UnoCSS
57
+ UnoCSS(),
58
+
56
59
  // Vue DevTools(仅开发环境)
57
60
  VueDevTools(),
58
61
 
@@ -66,12 +69,6 @@ export default defineConfig({
66
69
  exclude: ['**/components/**']
67
70
  }),
68
71
 
69
- // 布局系统
70
- Layouts({
71
- layoutsDirs: 'src/layouts',
72
- defaultLayout: 'default'
73
- }),
74
-
75
72
  // Vue 插件
76
73
  vue({
77
74
  script: {
@@ -174,9 +171,205 @@ export default defineConfig({
174
171
  'vue-router',
175
172
  'pinia',
176
173
  'axios',
177
- // OpenTiny Vue 组件(使用正则匹配所有子包)
178
- '@opentiny/vue'
179
- // 注意:unplugin-tiny-vue 会自动处理按需导入,无需手动列出所有组件
174
+ // OpenTiny Vue 所有组件
175
+ '@opentiny/vue',
176
+ '@opentiny/vue-action-menu',
177
+ '@opentiny/vue-action-sheet',
178
+ '@opentiny/vue-alert',
179
+ '@opentiny/vue-amount',
180
+ '@opentiny/vue-anchor',
181
+ '@opentiny/vue-area',
182
+ '@opentiny/vue-async-flowchart',
183
+ '@opentiny/vue-autocomplete',
184
+ '@opentiny/vue-badge',
185
+ '@opentiny/vue-base-select',
186
+ '@opentiny/vue-breadcrumb',
187
+ '@opentiny/vue-breadcrumb-item',
188
+ '@opentiny/vue-bulletin-board',
189
+ '@opentiny/vue-button',
190
+ '@opentiny/vue-button-group',
191
+ '@opentiny/vue-calendar',
192
+ '@opentiny/vue-calendar-bar',
193
+ '@opentiny/vue-calendar-view',
194
+ '@opentiny/vue-card',
195
+ '@opentiny/vue-card-group',
196
+ '@opentiny/vue-card-template',
197
+ '@opentiny/vue-carousel',
198
+ '@opentiny/vue-carousel-item',
199
+ '@opentiny/vue-cascader',
200
+ '@opentiny/vue-cascader-menu',
201
+ '@opentiny/vue-cascader-mobile',
202
+ '@opentiny/vue-cascader-node',
203
+ '@opentiny/vue-cascader-panel',
204
+ '@opentiny/vue-cascader-select',
205
+ '@opentiny/vue-cascader-view',
206
+ '@opentiny/vue-cell',
207
+ '@opentiny/vue-checkbox',
208
+ '@opentiny/vue-checkbox-button',
209
+ '@opentiny/vue-checkbox-group',
210
+ '@opentiny/vue-col',
211
+ '@opentiny/vue-collapse',
212
+ '@opentiny/vue-collapse-item',
213
+ '@opentiny/vue-collapse-transition',
214
+ '@opentiny/vue-color-picker',
215
+ '@opentiny/vue-color-select-panel',
216
+ '@opentiny/vue-column-list-group',
217
+ '@opentiny/vue-column-list-item',
218
+ '@opentiny/vue-company',
219
+ '@opentiny/vue-config-provider',
220
+ '@opentiny/vue-container',
221
+ '@opentiny/vue-country',
222
+ '@opentiny/vue-crop',
223
+ '@opentiny/vue-currency',
224
+ '@opentiny/vue-date-panel',
225
+ '@opentiny/vue-date-picker',
226
+ '@opentiny/vue-date-picker-mobile-first',
227
+ '@opentiny/vue-date-range',
228
+ '@opentiny/vue-date-table',
229
+ '@opentiny/vue-dept',
230
+ '@opentiny/vue-dialog-box',
231
+ '@opentiny/vue-dialog-select',
232
+ '@opentiny/vue-divider',
233
+ '@opentiny/vue-drawer',
234
+ '@opentiny/vue-drop-roles',
235
+ '@opentiny/vue-drop-times',
236
+ '@opentiny/vue-dropdown',
237
+ '@opentiny/vue-dropdown-item',
238
+ '@opentiny/vue-dropdown-menu',
239
+ '@opentiny/vue-dynamic-scroller',
240
+ '@opentiny/vue-dynamic-scroller-item',
241
+ '@opentiny/vue-espace',
242
+ '@opentiny/vue-exception',
243
+ '@opentiny/vue-fall-menu',
244
+ '@opentiny/vue-file-upload',
245
+ '@opentiny/vue-filter',
246
+ '@opentiny/vue-filter-bar',
247
+ '@opentiny/vue-filter-box',
248
+ '@opentiny/vue-filter-panel',
249
+ '@opentiny/vue-float-button',
250
+ '@opentiny/vue-floatbar',
251
+ '@opentiny/vue-floating-button',
252
+ '@opentiny/vue-flowchart',
253
+ '@opentiny/vue-fluent-editor',
254
+ '@opentiny/vue-form',
255
+ '@opentiny/vue-form-item',
256
+ '@opentiny/vue-fullscreen',
257
+ '@opentiny/vue-grid',
258
+ '@opentiny/vue-grid-column',
259
+ '@opentiny/vue-grid-manager',
260
+ '@opentiny/vue-grid-select',
261
+ '@opentiny/vue-grid-toolbar',
262
+ '@opentiny/vue-guide',
263
+ '@opentiny/vue-hrapprover',
264
+ '@opentiny/vue-image',
265
+ '@opentiny/vue-image-viewer',
266
+ '@opentiny/vue-input',
267
+ '@opentiny/vue-ip-address',
268
+ '@opentiny/vue-layout',
269
+ '@opentiny/vue-link',
270
+ '@opentiny/vue-link-menu',
271
+ '@opentiny/vue-load-list',
272
+ '@opentiny/vue-loading',
273
+ '@opentiny/vue-locales',
274
+ '@opentiny/vue-logon-user',
275
+ '@opentiny/vue-logout',
276
+ '@opentiny/vue-menu',
277
+ '@opentiny/vue-message',
278
+ '@opentiny/vue-milestone',
279
+ '@opentiny/vue-mind-map',
280
+ '@opentiny/vue-modal',
281
+ '@opentiny/vue-month-range',
282
+ '@opentiny/vue-month-table',
283
+ '@opentiny/vue-nav-menu',
284
+ '@opentiny/vue-notify',
285
+ '@opentiny/vue-number-animation',
286
+ '@opentiny/vue-numeric',
287
+ '@opentiny/vue-option',
288
+ '@opentiny/vue-option-group',
289
+ '@opentiny/vue-pager',
290
+ '@opentiny/vue-pager-item',
291
+ '@opentiny/vue-panel',
292
+ '@opentiny/vue-picker',
293
+ '@opentiny/vue-pop-upload',
294
+ '@opentiny/vue-popconfirm',
295
+ '@opentiny/vue-popeditor',
296
+ '@opentiny/vue-popover',
297
+ '@opentiny/vue-popup',
298
+ '@opentiny/vue-progress',
299
+ '@opentiny/vue-pull-refresh',
300
+ '@opentiny/vue-qr-code',
301
+ '@opentiny/vue-quarter-panel',
302
+ '@opentiny/vue-query-builder',
303
+ '@opentiny/vue-radio',
304
+ '@opentiny/vue-radio-button',
305
+ '@opentiny/vue-radio-group',
306
+ '@opentiny/vue-rate',
307
+ '@opentiny/vue-record',
308
+ '@opentiny/vue-recycle-scroller',
309
+ '@opentiny/vue-river',
310
+ '@opentiny/vue-roles',
311
+ '@opentiny/vue-row',
312
+ '@opentiny/vue-scroll-text',
313
+ '@opentiny/vue-scrollbar',
314
+ '@opentiny/vue-search',
315
+ '@opentiny/vue-select',
316
+ '@opentiny/vue-select-dropdown',
317
+ '@opentiny/vue-select-mobile',
318
+ '@opentiny/vue-select-view',
319
+ '@opentiny/vue-selected-box',
320
+ '@opentiny/vue-signature',
321
+ '@opentiny/vue-skeleton',
322
+ '@opentiny/vue-skeleton-item',
323
+ '@opentiny/vue-slider',
324
+ '@opentiny/vue-slider-button',
325
+ '@opentiny/vue-slider-button-group',
326
+ '@opentiny/vue-space',
327
+ '@opentiny/vue-split',
328
+ '@opentiny/vue-standard-list-item',
329
+ '@opentiny/vue-statistic',
330
+ '@opentiny/vue-steps',
331
+ '@opentiny/vue-sticky',
332
+ '@opentiny/vue-switch',
333
+ '@opentiny/vue-tab-item',
334
+ '@opentiny/vue-tabbar',
335
+ '@opentiny/vue-tabbar-item',
336
+ '@opentiny/vue-table',
337
+ '@opentiny/vue-tabs',
338
+ '@opentiny/vue-tag',
339
+ '@opentiny/vue-tag-group',
340
+ '@opentiny/vue-text-popup',
341
+ '@opentiny/vue-time',
342
+ '@opentiny/vue-time-line',
343
+ '@opentiny/vue-time-panel',
344
+ '@opentiny/vue-time-picker',
345
+ '@opentiny/vue-time-picker-mobile',
346
+ '@opentiny/vue-time-range',
347
+ '@opentiny/vue-time-select',
348
+ '@opentiny/vue-time-spinner',
349
+ '@opentiny/vue-timeline-item',
350
+ '@opentiny/vue-toggle-menu',
351
+ '@opentiny/vue-tooltip',
352
+ '@opentiny/vue-top-box',
353
+ '@opentiny/vue-transfer',
354
+ '@opentiny/vue-transfer-panel',
355
+ '@opentiny/vue-tree',
356
+ '@opentiny/vue-tree-menu',
357
+ '@opentiny/vue-tree-select',
358
+ '@opentiny/vue-upload',
359
+ '@opentiny/vue-upload-dragger',
360
+ '@opentiny/vue-upload-list',
361
+ '@opentiny/vue-user',
362
+ '@opentiny/vue-user-account',
363
+ '@opentiny/vue-user-contact',
364
+ '@opentiny/vue-user-head',
365
+ '@opentiny/vue-user-head-group',
366
+ '@opentiny/vue-user-link',
367
+ '@opentiny/vue-virtual-scroll-box',
368
+ '@opentiny/vue-virtual-tree',
369
+ '@opentiny/vue-watermark',
370
+ '@opentiny/vue-wizard',
371
+ '@opentiny/vue-year-range',
372
+ '@opentiny/vue-year-table'
180
373
  ]
181
374
  }
182
375
  });