feat: add api-select component (#5024)
parent
db38ef522f
commit
9896a67c21
|
@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -48,6 +48,7 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'AutoComplete'
|
| 'AutoComplete'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
|
@ -78,7 +79,20 @@ async function initComponentAdapter() {
|
||||||
// 如果你的组件体积比较大,可以使用异步加载
|
// 如果你的组件体积比较大,可以使用异步加载
|
||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: Select,
|
||||||
|
loadingSlot: 'suffixIcon',
|
||||||
|
visibleEvent: 'onDropdownVisibleChange',
|
||||||
|
modelField: 'value',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
AutoComplete,
|
AutoComplete,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
CheckboxGroup,
|
CheckboxGroup,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -22,6 +22,7 @@ import {
|
||||||
ElNotification,
|
ElNotification,
|
||||||
ElRadioGroup,
|
ElRadioGroup,
|
||||||
ElSelect,
|
ElSelect,
|
||||||
|
ElSelectV2,
|
||||||
ElSpace,
|
ElSpace,
|
||||||
ElSwitch,
|
ElSwitch,
|
||||||
ElTimePicker,
|
ElTimePicker,
|
||||||
|
@ -41,6 +42,7 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
| 'DatePicker'
|
| 'DatePicker'
|
||||||
|
@ -62,7 +64,19 @@ async function initComponentAdapter() {
|
||||||
// 如果你的组件体积比较大,可以使用异步加载
|
// 如果你的组件体积比较大,可以使用异步加载
|
||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: ElSelectV2,
|
||||||
|
loadingSlot: 'loading',
|
||||||
|
visibleEvent: 'onDropdownVisibleChange',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
Checkbox: ElCheckbox,
|
Checkbox: ElCheckbox,
|
||||||
CheckboxGroup: ElCheckboxGroup,
|
CheckboxGroup: ElCheckboxGroup,
|
||||||
// 自定义默认按钮
|
// 自定义默认按钮
|
||||||
|
|
|
@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -42,6 +42,7 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
| 'DatePicker'
|
| 'DatePicker'
|
||||||
|
@ -64,6 +65,18 @@ async function initComponentAdapter() {
|
||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: NSelect,
|
||||||
|
modelField: 'value',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
Checkbox: NCheckbox,
|
Checkbox: NCheckbox,
|
||||||
CheckboxGroup: NCheckboxGroup,
|
CheckboxGroup: NCheckboxGroup,
|
||||||
DatePicker: NDatePicker,
|
DatePicker: NDatePicker,
|
||||||
|
|
|
@ -86,12 +86,16 @@
|
||||||
"dayjs": "catalog:",
|
"dayjs": "catalog:",
|
||||||
"defu": "catalog:",
|
"defu": "catalog:",
|
||||||
"lodash.clonedeep": "catalog:",
|
"lodash.clonedeep": "catalog:",
|
||||||
|
"lodash.get": "catalog:",
|
||||||
|
"lodash.isequal": "catalog:",
|
||||||
"nprogress": "catalog:",
|
"nprogress": "catalog:",
|
||||||
"tailwind-merge": "catalog:",
|
"tailwind-merge": "catalog:",
|
||||||
"theme-colors": "catalog:"
|
"theme-colors": "catalog:"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash.clonedeep": "catalog:",
|
"@types/lodash.clonedeep": "catalog:",
|
||||||
|
"@types/lodash.get": "catalog:",
|
||||||
|
"@types/lodash.isequal": "catalog:",
|
||||||
"@types/nprogress": "catalog:"
|
"@types/nprogress": "catalog:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,3 +15,5 @@ export * from './update-css-variables';
|
||||||
export * from './util';
|
export * from './util';
|
||||||
export * from './window';
|
export * from './window';
|
||||||
export { default as cloneDeep } from 'lodash.clonedeep';
|
export { default as cloneDeep } from 'lodash.clonedeep';
|
||||||
|
export { default as get } from 'lodash.get';
|
||||||
|
export { default as isEqual } from 'lodash.isequal';
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { AnyPromiseFunction } from '@vben/types';
|
||||||
|
|
||||||
|
import { computed, ref, unref, useAttrs, type VNode, watch } from 'vue';
|
||||||
|
|
||||||
|
import { LoaderCircle } from '@vben/icons';
|
||||||
|
import { get, isEqual, isFunction } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
|
import { objectOmit } from '@vueuse/core';
|
||||||
|
|
||||||
|
type OptionsItem = {
|
||||||
|
[name: string]: any;
|
||||||
|
disabled?: boolean;
|
||||||
|
label?: string;
|
||||||
|
value?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
// 组件
|
||||||
|
component: VNode;
|
||||||
|
numberToString?: boolean;
|
||||||
|
api?: (arg?: any) => Promise<OptionsItem[] | Record<string, any>>;
|
||||||
|
params?: Record<string, any>;
|
||||||
|
resultField?: string;
|
||||||
|
labelField?: string;
|
||||||
|
valueField?: string;
|
||||||
|
immediate?: boolean;
|
||||||
|
alwaysLoad?: boolean;
|
||||||
|
beforeFetch?: AnyPromiseFunction<any, any>;
|
||||||
|
afterFetch?: AnyPromiseFunction<any, any>;
|
||||||
|
options?: OptionsItem[];
|
||||||
|
// 尾部插槽
|
||||||
|
loadingSlot?: string;
|
||||||
|
// 可见时触发的事件名
|
||||||
|
visibleEvent?: string;
|
||||||
|
modelField?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineOptions({ name: 'ApiSelect', inheritAttrs: false });
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
labelField: 'label',
|
||||||
|
valueField: 'value',
|
||||||
|
resultField: '',
|
||||||
|
visibleEvent: '',
|
||||||
|
numberToString: false,
|
||||||
|
params: () => ({}),
|
||||||
|
immediate: true,
|
||||||
|
alwaysLoad: false,
|
||||||
|
loadingSlot: '',
|
||||||
|
beforeFetch: undefined,
|
||||||
|
afterFetch: undefined,
|
||||||
|
modelField: 'modelValue',
|
||||||
|
api: undefined,
|
||||||
|
options: () => [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
optionsChange: [OptionsItem[]];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const modelValue = defineModel({ default: '' });
|
||||||
|
|
||||||
|
const attrs = useAttrs();
|
||||||
|
|
||||||
|
const refOptions = ref<OptionsItem[]>([]);
|
||||||
|
const loading = ref(false);
|
||||||
|
// 首次是否加载过了
|
||||||
|
const isFirstLoaded = ref(false);
|
||||||
|
|
||||||
|
const getOptions = computed(() => {
|
||||||
|
const { labelField, valueField, numberToString } = props;
|
||||||
|
|
||||||
|
const data: OptionsItem[] = [];
|
||||||
|
const refOptionsData = unref(refOptions);
|
||||||
|
|
||||||
|
for (const next of refOptionsData) {
|
||||||
|
if (next) {
|
||||||
|
const value = get(next, valueField);
|
||||||
|
data.push({
|
||||||
|
...objectOmit(next, [labelField, valueField]),
|
||||||
|
label: get(next, labelField),
|
||||||
|
value: numberToString ? `${value}` : value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.length > 0 ? data : props.options;
|
||||||
|
});
|
||||||
|
|
||||||
|
const bindProps = computed(() => {
|
||||||
|
return {
|
||||||
|
[props.modelField]: unref(modelValue),
|
||||||
|
[`onUpdate:${props.modelField}`]: (val: string) => {
|
||||||
|
modelValue.value = val;
|
||||||
|
},
|
||||||
|
...objectOmit(attrs, ['onUpdate:value']),
|
||||||
|
...(props.visibleEvent
|
||||||
|
? {
|
||||||
|
[props.visibleEvent]: handleFetchForVisible,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fetchApi() {
|
||||||
|
let { api, beforeFetch, afterFetch, params, resultField } = props;
|
||||||
|
|
||||||
|
if (!api || !isFunction(api) || loading.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refOptions.value = [];
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
if (beforeFetch && isFunction(beforeFetch)) {
|
||||||
|
params = (await beforeFetch(params)) || params;
|
||||||
|
}
|
||||||
|
let res = await api(params);
|
||||||
|
if (afterFetch && isFunction(afterFetch)) {
|
||||||
|
res = (await afterFetch(res)) || res;
|
||||||
|
}
|
||||||
|
isFirstLoaded.value = true;
|
||||||
|
if (Array.isArray(res)) {
|
||||||
|
refOptions.value = res;
|
||||||
|
emitChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resultField) {
|
||||||
|
refOptions.value = get(res, resultField) || [];
|
||||||
|
}
|
||||||
|
emitChange();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(error);
|
||||||
|
// reset status
|
||||||
|
isFirstLoaded.value = false;
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleFetchForVisible(visible: boolean) {
|
||||||
|
if (visible) {
|
||||||
|
if (props.alwaysLoad) {
|
||||||
|
await fetchApi();
|
||||||
|
} else if (!props.immediate && !unref(isFirstLoaded)) {
|
||||||
|
await fetchApi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.params,
|
||||||
|
(value, oldValue) => {
|
||||||
|
if (isEqual(value, oldValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetchApi();
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: props.immediate },
|
||||||
|
);
|
||||||
|
|
||||||
|
function emitChange() {
|
||||||
|
emit('optionsChange', unref(getOptions));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div v-bind="{ ...$attrs }">
|
||||||
|
<component
|
||||||
|
:is="component"
|
||||||
|
v-bind="bindProps"
|
||||||
|
:options="getOptions"
|
||||||
|
:placeholder="$attrs.placeholder"
|
||||||
|
>
|
||||||
|
<template v-for="item in Object.keys($slots)" #[item]="data">
|
||||||
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
|
</template>
|
||||||
|
<template v-if="loadingSlot && loading" #[loadingSlot]>
|
||||||
|
<LoaderCircle class="animate-spin" />
|
||||||
|
</template>
|
||||||
|
</component>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as ApiSelect } from './api-select.vue';
|
|
@ -1,3 +1,4 @@
|
||||||
|
export * from './api-select';
|
||||||
export * from './captcha';
|
export * from './captcha';
|
||||||
export * from './ellipsis-text';
|
export * from './ellipsis-text';
|
||||||
export * from './icon-picker';
|
export * from './icon-picker';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -48,6 +48,7 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'AutoComplete'
|
| 'AutoComplete'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
|
@ -79,6 +80,20 @@ async function initComponentAdapter() {
|
||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: Select,
|
||||||
|
loadingSlot: 'suffixIcon',
|
||||||
|
modelField: 'value',
|
||||||
|
visibleEvent: 'onVisibleChange',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
AutoComplete,
|
AutoComplete,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
CheckboxGroup,
|
CheckboxGroup,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { Button, Card, message, TabPane, Tabs } from 'ant-design-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import { getAllMenusApi } from '#/api';
|
||||||
|
|
||||||
import DocButton from '../doc-button.vue';
|
import DocButton from '../doc-button.vue';
|
||||||
|
|
||||||
|
@ -40,6 +41,27 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
||||||
// 界面显示的label
|
// 界面显示的label
|
||||||
label: '字符串',
|
label: '字符串',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// 组件需要在 #/adapter.ts内注册,并加上类型
|
||||||
|
component: 'ApiSelect',
|
||||||
|
// 对应组件的参数
|
||||||
|
componentProps: {
|
||||||
|
// 菜单接口转options格式
|
||||||
|
afterFetch: (data: { name: string; path: string }[]) => {
|
||||||
|
return data.map((item: any) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.path,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
// 菜单接口
|
||||||
|
api: getAllMenusApi,
|
||||||
|
placeholder: '请选择',
|
||||||
|
},
|
||||||
|
// 字段名
|
||||||
|
fieldName: 'api',
|
||||||
|
// 界面显示的label
|
||||||
|
label: 'ApiSelect',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'InputPassword',
|
component: 'InputPassword',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
|
|
1088
pnpm-lock.yaml
1088
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,7 @@ packages:
|
||||||
- docs
|
- docs
|
||||||
- playground
|
- playground
|
||||||
catalog:
|
catalog:
|
||||||
'@ast-grep/napi': ^0.30.1
|
'@ast-grep/napi': ^0.31.0
|
||||||
'@changesets/changelog-github': ^0.5.0
|
'@changesets/changelog-github': ^0.5.0
|
||||||
'@changesets/cli': ^2.27.10
|
'@changesets/cli': ^2.27.10
|
||||||
'@changesets/git': ^3.0.2
|
'@changesets/git': ^3.0.2
|
||||||
|
@ -22,8 +22,8 @@ catalog:
|
||||||
'@commitlint/config-conventional': ^19.6.0
|
'@commitlint/config-conventional': ^19.6.0
|
||||||
'@ctrl/tinycolor': ^4.1.0
|
'@ctrl/tinycolor': ^4.1.0
|
||||||
'@eslint/js': ^9.16.0
|
'@eslint/js': ^9.16.0
|
||||||
'@faker-js/faker': ^9.2.0
|
'@faker-js/faker': ^9.3.0
|
||||||
'@iconify/json': ^2.2.278
|
'@iconify/json': ^2.2.279
|
||||||
'@iconify/tailwind': ^1.1.3
|
'@iconify/tailwind': ^1.1.3
|
||||||
'@iconify/vue': ^4.1.2
|
'@iconify/vue': ^4.1.2
|
||||||
'@intlify/core-base': ^10.0.5
|
'@intlify/core-base': ^10.0.5
|
||||||
|
@ -36,20 +36,22 @@ catalog:
|
||||||
'@stylistic/stylelint-plugin': ^3.1.1
|
'@stylistic/stylelint-plugin': ^3.1.1
|
||||||
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e
|
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e
|
||||||
'@tailwindcss/typography': ^0.5.15
|
'@tailwindcss/typography': ^0.5.15
|
||||||
'@tanstack/vue-query': ^5.62.0
|
'@tanstack/vue-query': ^5.62.2
|
||||||
'@tanstack/vue-store': ^0.6.0
|
'@tanstack/vue-store': ^0.6.0
|
||||||
'@types/archiver': ^6.0.3
|
'@types/archiver': ^6.0.3
|
||||||
'@types/eslint': ^9.6.1
|
'@types/eslint': ^9.6.1
|
||||||
'@types/html-minifier-terser': ^7.0.2
|
'@types/html-minifier-terser': ^7.0.2
|
||||||
'@types/jsonwebtoken': ^9.0.7
|
'@types/jsonwebtoken': ^9.0.7
|
||||||
'@types/lodash.clonedeep': ^4.5.9
|
'@types/lodash.clonedeep': ^4.5.9
|
||||||
'@types/node': ^22.10.0
|
'@types/lodash.get': ^4.4.9
|
||||||
|
'@types/lodash.isequal': ^4.5.8
|
||||||
|
'@types/node': ^22.10.1
|
||||||
'@types/nprogress': ^0.2.3
|
'@types/nprogress': ^0.2.3
|
||||||
'@types/postcss-import': ^14.0.3
|
'@types/postcss-import': ^14.0.3
|
||||||
'@types/qrcode': ^1.5.5
|
'@types/qrcode': ^1.5.5
|
||||||
'@types/sortablejs': ^1.15.8
|
'@types/sortablejs': ^1.15.8
|
||||||
'@typescript-eslint/eslint-plugin': ^8.16.0
|
'@typescript-eslint/eslint-plugin': ^8.17.0
|
||||||
'@typescript-eslint/parser': ^8.16.0
|
'@typescript-eslint/parser': ^8.17.0
|
||||||
'@vee-validate/zod': ^4.14.7
|
'@vee-validate/zod': ^4.14.7
|
||||||
'@vite-pwa/vitepress': ^0.5.3
|
'@vite-pwa/vitepress': ^0.5.3
|
||||||
'@vitejs/plugin-vue': ^5.2.1
|
'@vitejs/plugin-vue': ^5.2.1
|
||||||
|
@ -62,7 +64,7 @@ catalog:
|
||||||
ant-design-vue: ^4.2.6
|
ant-design-vue: ^4.2.6
|
||||||
archiver: ^7.0.1
|
archiver: ^7.0.1
|
||||||
autoprefixer: ^10.4.20
|
autoprefixer: ^10.4.20
|
||||||
axios: ^1.7.8
|
axios: ^1.7.9
|
||||||
axios-mock-adapter: ^2.1.0
|
axios-mock-adapter: ^2.1.0
|
||||||
cac: ^6.7.14
|
cac: ^6.7.14
|
||||||
chalk: ^5.3.0
|
chalk: ^5.3.0
|
||||||
|
@ -80,14 +82,14 @@ catalog:
|
||||||
dayjs: ^1.11.13
|
dayjs: ^1.11.13
|
||||||
defu: ^6.1.4
|
defu: ^6.1.4
|
||||||
depcheck: ^1.4.7
|
depcheck: ^1.4.7
|
||||||
dotenv: ^16.4.5
|
dotenv: ^16.4.7
|
||||||
echarts: ^5.5.1
|
echarts: ^5.5.1
|
||||||
element-plus: ^2.9.0
|
element-plus: ^2.9.0
|
||||||
eslint: ^9.16.0
|
eslint: ^9.16.0
|
||||||
eslint-config-turbo: ^2.3.3
|
eslint-config-turbo: ^2.3.3
|
||||||
eslint-plugin-command: ^0.2.6
|
eslint-plugin-command: ^0.2.6
|
||||||
eslint-plugin-eslint-comments: ^3.2.0
|
eslint-plugin-eslint-comments: ^3.2.0
|
||||||
eslint-plugin-import-x: ^4.4.3
|
eslint-plugin-import-x: ^4.5.0
|
||||||
eslint-plugin-jsdoc: ^50.6.0
|
eslint-plugin-jsdoc: ^50.6.0
|
||||||
eslint-plugin-jsonc: ^2.18.2
|
eslint-plugin-jsonc: ^2.18.2
|
||||||
eslint-plugin-n: ^17.14.0
|
eslint-plugin-n: ^17.14.0
|
||||||
|
@ -102,7 +104,7 @@ catalog:
|
||||||
execa: ^9.5.1
|
execa: ^9.5.1
|
||||||
find-up: ^7.0.0
|
find-up: ^7.0.0
|
||||||
get-port: ^7.1.0
|
get-port: ^7.1.0
|
||||||
globals: ^15.12.0
|
globals: ^15.13.0
|
||||||
h3: ^1.13.0
|
h3: ^1.13.0
|
||||||
happy-dom: ^15.11.7
|
happy-dom: ^15.11.7
|
||||||
html-minifier-terser: ^7.2.0
|
html-minifier-terser: ^7.2.0
|
||||||
|
@ -112,9 +114,11 @@ catalog:
|
||||||
jsonwebtoken: ^9.0.2
|
jsonwebtoken: ^9.0.2
|
||||||
lint-staged: ^15.2.10
|
lint-staged: ^15.2.10
|
||||||
lodash.clonedeep: ^4.5.0
|
lodash.clonedeep: ^4.5.0
|
||||||
lucide-vue-next: ^0.461.0
|
lodash.get: ^4.4.2
|
||||||
|
lodash.isequal: ^4.5.0
|
||||||
|
lucide-vue-next: ^0.465.0
|
||||||
medium-zoom: ^1.1.0
|
medium-zoom: ^1.1.0
|
||||||
naive-ui: ^2.40.2
|
naive-ui: ^2.40.3
|
||||||
nitropack: ^2.10.4
|
nitropack: ^2.10.4
|
||||||
nprogress: ^0.2.0
|
nprogress: ^0.2.0
|
||||||
ora: ^8.1.1
|
ora: ^8.1.1
|
||||||
|
@ -128,12 +132,12 @@ catalog:
|
||||||
postcss-import: ^16.1.0
|
postcss-import: ^16.1.0
|
||||||
postcss-preset-env: ^10.1.1
|
postcss-preset-env: ^10.1.1
|
||||||
postcss-scss: ^4.0.9
|
postcss-scss: ^4.0.9
|
||||||
prettier: ^3.4.1
|
prettier: ^3.4.2
|
||||||
prettier-plugin-tailwindcss: ^0.6.9
|
prettier-plugin-tailwindcss: ^0.6.9
|
||||||
publint: ^0.2.12
|
publint: ^0.2.12
|
||||||
qrcode: ^1.5.4
|
qrcode: ^1.5.4
|
||||||
radix-vue: ^1.9.10
|
radix-vue: ^1.9.10
|
||||||
resolve.exports: ^2.0.2
|
resolve.exports: ^2.0.3
|
||||||
rimraf: ^6.0.1
|
rimraf: ^6.0.1
|
||||||
rollup: ^4.28.0
|
rollup: ^4.28.0
|
||||||
rollup-plugin-visualizer: ^5.12.0
|
rollup-plugin-visualizer: ^5.12.0
|
||||||
|
@ -149,7 +153,7 @@ catalog:
|
||||||
stylelint-prettier: ^5.0.2
|
stylelint-prettier: ^5.0.2
|
||||||
stylelint-scss: ^6.10.0
|
stylelint-scss: ^6.10.0
|
||||||
tailwind-merge: ^2.5.5
|
tailwind-merge: ^2.5.5
|
||||||
tailwindcss: ^3.4.15
|
tailwindcss: ^3.4.16
|
||||||
tailwindcss-animate: ^1.0.7
|
tailwindcss-animate: ^1.0.7
|
||||||
theme-colors: ^0.1.0
|
theme-colors: ^0.1.0
|
||||||
turbo: ^2.3.3
|
turbo: ^2.3.3
|
||||||
|
@ -157,7 +161,7 @@ catalog:
|
||||||
unbuild: ^3.0.0-rc.11
|
unbuild: ^3.0.0-rc.11
|
||||||
unplugin-element-plus: ^0.8.0
|
unplugin-element-plus: ^0.8.0
|
||||||
vee-validate: ^4.14.7
|
vee-validate: ^4.14.7
|
||||||
vite: ^6.0.1
|
vite: ^6.0.2
|
||||||
vite-plugin-compression: ^0.5.1
|
vite-plugin-compression: ^0.5.1
|
||||||
vite-plugin-dts: 4.2.1
|
vite-plugin-dts: 4.2.1
|
||||||
vite-plugin-html: ^3.2.2
|
vite-plugin-html: ^3.2.2
|
||||||
|
@ -165,15 +169,15 @@ catalog:
|
||||||
vite-plugin-pwa: ^0.21.1
|
vite-plugin-pwa: ^0.21.1
|
||||||
vite-plugin-vue-devtools: ^7.6.7
|
vite-plugin-vue-devtools: ^7.6.7
|
||||||
vitepress: ^1.5.0
|
vitepress: ^1.5.0
|
||||||
vitepress-plugin-group-icons: ^1.3.0
|
vitepress-plugin-group-icons: ^1.3.1
|
||||||
vitest: ^2.1.6
|
vitest: ^2.1.8
|
||||||
vue: ^3.5.13
|
vue: ^3.5.13
|
||||||
vue-eslint-parser: ^9.4.3
|
vue-eslint-parser: ^9.4.3
|
||||||
vue-i18n: ^10.0.5
|
vue-i18n: ^10.0.5
|
||||||
vue-router: ^4.5.0
|
vue-router: ^4.5.0
|
||||||
vue-tsc: ^2.1.10
|
vue-tsc: ^2.1.10
|
||||||
vxe-pc-ui: ^4.3.10
|
vxe-pc-ui: ^4.3.14
|
||||||
vxe-table: ^4.9.10
|
vxe-table: ^4.9.14
|
||||||
watermark-js-plus: ^1.5.7
|
watermark-js-plus: ^1.5.7
|
||||||
zod: ^3.23.8
|
zod: ^3.23.8
|
||||||
zod-defaults: ^0.1.3
|
zod-defaults: ^0.1.3
|
||||||
|
|
Loading…
Reference in New Issue