Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev
This commit is contained in:
commit
7f1548b343
@ -3,11 +3,12 @@
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
import type { Component } from 'vue';
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
import type { Recordable } from '@vben/types';
|
||||
|
||||
import { h } from 'vue';
|
||||
import { defineComponent, getCurrentInstance, h, ref } from 'vue';
|
||||
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
import { $t } from '@vben/locales';
|
||||
@ -44,10 +45,30 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
component: T,
|
||||
type: 'input' | 'select',
|
||||
) => {
|
||||
return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
|
||||
const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`);
|
||||
return h(component, { ...props, ...attrs, placeholder }, slots);
|
||||
};
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: component.name,
|
||||
setup: (props: any, { attrs, expose, slots }) => {
|
||||
const placeholder =
|
||||
props?.placeholder ||
|
||||
attrs?.placeholder ||
|
||||
$t(`ui.placeholder.${type}`);
|
||||
// 透传组件暴露的方法
|
||||
const innerRef = ref();
|
||||
const publicApi: Recordable<any> = {};
|
||||
expose(publicApi);
|
||||
const instance = getCurrentInstance();
|
||||
instance?.proxy?.$nextTick(() => {
|
||||
for (const key in innerRef.value) {
|
||||
if (typeof innerRef.value[key] === 'function') {
|
||||
publicApi[key] = innerRef.value[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
return () =>
|
||||
h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||
|
@ -279,22 +279,24 @@ const [Form, formApi] = useVbenForm({
|
||||
|
||||
useVbenForm 返回的第二个参数,是一个对象,包含了一些表单的方法。
|
||||
|
||||
| 方法名 | 描述 | 类型 |
|
||||
| --- | --- | --- |
|
||||
| submitForm | 提交表单 | `(e:Event)=>Promise<Record<string,any>>` |
|
||||
| validateAndSubmitForm | 提交并校验表单 | `(e:Event)=>Promise<Record<string,any>>` |
|
||||
| resetForm | 重置表单 | `()=>Promise<void>` |
|
||||
| setValues | 设置表单值, 默认会过滤不在schema中定义的field, 可通过filterFields形参关闭过滤 | `(fields: Record<string, any>, filterFields?: boolean, shouldValidate?: boolean) => Promise<void>` |
|
||||
| getValues | 获取表单值 | `(fields:Record<string, any>,shouldValidate: boolean = false)=>Promise<void>` |
|
||||
| validate | 表单校验 | `()=>Promise<void>` |
|
||||
| validateField | 校验指定字段 | `(fieldName: string)=>Promise<ValidationResult<unknown>>` |
|
||||
| isFieldValid | 检查某个字段是否已通过校验 | `(fieldName: string)=>Promise<boolean>` |
|
||||
| resetValidate | 重置表单校验 | `()=>Promise<void>` |
|
||||
| updateSchema | 更新formSchema | `(schema:FormSchema[])=>void` |
|
||||
| setFieldValue | 设置字段值 | `(field: string, value: any, shouldValidate?: boolean)=>Promise<void>` |
|
||||
| setState | 设置组件状态(props) | `(stateOrFn:\| ((prev: VbenFormProps) => Partial<VbenFormProps>)\| Partial<VbenFormProps>)=>Promise<void>` |
|
||||
| getState | 获取组件状态(props) | `()=>Promise<VbenFormProps>` |
|
||||
| form | 表单对象实例,可以操作表单,见 [useForm](https://vee-validate.logaretm.com/v4/api/use-form/) | - |
|
||||
| 方法名 | 描述 | 类型 | 版本号 |
|
||||
| --- | --- | --- | --- |
|
||||
| submitForm | 提交表单 | `(e:Event)=>Promise<Record<string,any>>` | - |
|
||||
| validateAndSubmitForm | 提交并校验表单 | `(e:Event)=>Promise<Record<string,any>>` | - |
|
||||
| resetForm | 重置表单 | `()=>Promise<void>` | - |
|
||||
| setValues | 设置表单值, 默认会过滤不在schema中定义的field, 可通过filterFields形参关闭过滤 | `(fields: Record<string, any>, filterFields?: boolean, shouldValidate?: boolean) => Promise<void>` | - |
|
||||
| getValues | 获取表单值 | `(fields:Record<string, any>,shouldValidate: boolean = false)=>Promise<void>` | - |
|
||||
| validate | 表单校验 | `()=>Promise<void>` | - |
|
||||
| validateField | 校验指定字段 | `(fieldName: string)=>Promise<ValidationResult<unknown>>` | - |
|
||||
| isFieldValid | 检查某个字段是否已通过校验 | `(fieldName: string)=>Promise<boolean>` | - |
|
||||
| resetValidate | 重置表单校验 | `()=>Promise<void>` | - |
|
||||
| updateSchema | 更新formSchema | `(schema:FormSchema[])=>void` | - |
|
||||
| setFieldValue | 设置字段值 | `(field: string, value: any, shouldValidate?: boolean)=>Promise<void>` | - |
|
||||
| setState | 设置组件状态(props) | `(stateOrFn:\| ((prev: VbenFormProps) => Partial<VbenFormProps>)\| Partial<VbenFormProps>)=>Promise<void>` | - |
|
||||
| getState | 获取组件状态(props) | `()=>Promise<VbenFormProps>` | - |
|
||||
| form | 表单对象实例,可以操作表单,见 [useForm](https://vee-validate.logaretm.com/v4/api/use-form/) | - | - |
|
||||
| getFieldComponentRef | 获取指定字段的组件实例 | `<T=unknown>(fieldName: string)=>T` | >5.5.3 |
|
||||
| getFocusedField | 获取当前已获得焦点的字段 | `()=>string\|undefined` | >5.5.3 |
|
||||
|
||||
## Props
|
||||
|
||||
|
@ -165,7 +165,7 @@ vxeUI.renderer.add('CellLink', {
|
||||
|
||||
**表单搜索** 部分采用了`Vben Form 表单`,参考 [Vben Form 表单文档](/components/common-ui/vben-form)。
|
||||
|
||||
当启用了表单搜索时,可以在toolbarConfig中配置`search`为`true`来让表格在工具栏区域显示一个搜索表单控制按钮。
|
||||
当启用了表单搜索时,可以在toolbarConfig中配置`search`为`true`来让表格在工具栏区域显示一个搜索表单控制按钮。表格的所有以`form-`开头的命名插槽都会被传递给搜索表单。
|
||||
|
||||
<DemoPreview dir="demos/vben-vxe-table/form" />
|
||||
|
||||
@ -250,3 +250,9 @@ useVbenVxeGrid 返回的第二个参数,是一个对象,包含了一些表
|
||||
| toolbar-actions | 工具栏左侧部分(表格标题附近) |
|
||||
| toolbar-tools | 工具栏右侧部分(vxeTable原生工具按钮的左侧) |
|
||||
| table-title | 表格标题插槽 |
|
||||
|
||||
::: info 搜索表单的插槽
|
||||
|
||||
对于使用了搜索表单的表格来说,所有以`form-`开头的命名插槽都会传递给表单。
|
||||
|
||||
:::
|
||||
|
@ -95,7 +95,7 @@
|
||||
"node": ">=20.10.0",
|
||||
"pnpm": ">=9.12.0"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.6",
|
||||
"packageManager": "pnpm@9.15.7",
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
"allowedVersions": {
|
||||
|
@ -5,6 +5,8 @@ import type {
|
||||
ValidationOptions,
|
||||
} from 'vee-validate';
|
||||
|
||||
import type { ComponentPublicInstance } from 'vue';
|
||||
|
||||
import type { Recordable } from '@vben-core/typings';
|
||||
|
||||
import type { FormActions, FormSchema, VbenFormProps } from './types';
|
||||
@ -56,6 +58,11 @@ export class FormApi {
|
||||
|
||||
public store: Store<VbenFormProps>;
|
||||
|
||||
/**
|
||||
* 组件实例映射
|
||||
*/
|
||||
private componentRefMap: Map<string, unknown> = new Map();
|
||||
|
||||
// 最后一次点击提交时的表单值
|
||||
private latestSubmissionValues: null | Recordable<any> = null;
|
||||
|
||||
@ -85,6 +92,46 @@ export class FormApi {
|
||||
bindMethods(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段组件实例
|
||||
* @param fieldName 字段名
|
||||
* @returns 组件实例
|
||||
*/
|
||||
getFieldComponentRef<T = ComponentPublicInstance>(
|
||||
fieldName: string,
|
||||
): T | undefined {
|
||||
return this.componentRefMap.has(fieldName)
|
||||
? (this.componentRefMap.get(fieldName) as T)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前聚焦的字段,如果没有聚焦的字段则返回undefined
|
||||
*/
|
||||
getFocusedField() {
|
||||
for (const fieldName of this.componentRefMap.keys()) {
|
||||
const ref = this.getFieldComponentRef(fieldName);
|
||||
if (ref) {
|
||||
let el: HTMLElement | null = null;
|
||||
if (ref instanceof HTMLElement) {
|
||||
el = ref;
|
||||
} else if (ref.$el instanceof HTMLElement) {
|
||||
el = ref.$el;
|
||||
}
|
||||
if (!el) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
el === document.activeElement ||
|
||||
el.contains(document.activeElement)
|
||||
) {
|
||||
return fieldName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getLatestSubmissionValues() {
|
||||
return this.latestSubmissionValues || {};
|
||||
}
|
||||
@ -143,13 +190,14 @@ export class FormApi {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
mount(formActions: FormActions) {
|
||||
mount(formActions: FormActions, componentRefMap: Map<string, unknown>) {
|
||||
if (!this.isMounted) {
|
||||
Object.assign(this.form, formActions);
|
||||
this.stateHandler.setConditionTrue();
|
||||
this.setLatestSubmissionValues({
|
||||
...toRaw(this.handleRangeTimeValue(this.form.values)),
|
||||
});
|
||||
this.componentRefMap = componentRefMap;
|
||||
this.isMounted = true;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import type { ZodType } from 'zod';
|
||||
|
||||
import type { FormSchema, MaybeComponentProps } from '../types';
|
||||
|
||||
import { computed, nextTick, useTemplateRef, watch } from 'vue';
|
||||
import { computed, nextTick, onUnmounted, useTemplateRef, watch } from 'vue';
|
||||
|
||||
import {
|
||||
FormControl,
|
||||
@ -18,6 +18,7 @@ import { cn, isFunction, isObject, isString } from '@vben-core/shared/utils';
|
||||
import { toTypedSchema } from '@vee-validate/zod';
|
||||
import { useFieldError, useFormValues } from 'vee-validate';
|
||||
|
||||
import { injectComponentRefMap } from '../use-form-context';
|
||||
import { injectRenderFormProps, useFormContext } from './context';
|
||||
import useDependencies from './dependencies';
|
||||
import FormLabel from './form-label.vue';
|
||||
@ -267,6 +268,15 @@ function autofocus() {
|
||||
fieldComponentRef.value?.focus?.();
|
||||
}
|
||||
}
|
||||
const componentRefMap = injectComponentRefMap();
|
||||
watch(fieldComponentRef, (componentRef) => {
|
||||
componentRefMap?.set(fieldName, componentRef);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
if (componentRefMap?.has(fieldName)) {
|
||||
componentRefMap.delete(fieldName);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -20,6 +20,9 @@ export const [injectFormProps, provideFormProps] =
|
||||
'VbenFormProps',
|
||||
);
|
||||
|
||||
export const [injectComponentRefMap, provideComponentRefMap] =
|
||||
createContext<Map<string, unknown>>('ComponentRefMap');
|
||||
|
||||
export function useFormInitial(
|
||||
props: ComputedRef<VbenFormProps> | VbenFormProps,
|
||||
) {
|
||||
|
@ -17,7 +17,11 @@ import {
|
||||
DEFAULT_FORM_COMMON_CONFIG,
|
||||
} from './config';
|
||||
import { Form } from './form-render';
|
||||
import { provideFormProps, useFormInitial } from './use-form-context';
|
||||
import {
|
||||
provideComponentRefMap,
|
||||
provideFormProps,
|
||||
useFormInitial,
|
||||
} from './use-form-context';
|
||||
// 通过 extends 会导致热更新卡死,所以重复写了一遍
|
||||
interface Props extends VbenFormProps {
|
||||
formApi: ExtendedFormApi;
|
||||
@ -29,11 +33,14 @@ const state = props.formApi?.useStore?.();
|
||||
|
||||
const forward = useForwardPriorityValues(props, state);
|
||||
|
||||
const componentRefMap = new Map<string, unknown>();
|
||||
|
||||
const { delegatedSlots, form } = useFormInitial(forward);
|
||||
|
||||
provideFormProps([forward, form]);
|
||||
provideComponentRefMap(componentRefMap);
|
||||
|
||||
props.formApi?.mount?.(form);
|
||||
props.formApi?.mount?.(form, componentRefMap);
|
||||
|
||||
const handleUpdateCollapsed = (value: boolean) => {
|
||||
props.formApi?.setState({ collapsed: !!value });
|
||||
|
@ -3,6 +3,8 @@ import type { CSSProperties } from 'vue';
|
||||
|
||||
import type { VbenLayoutProps } from './vben-layout';
|
||||
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
import {
|
||||
SCROLL_FIXED_CLASS,
|
||||
useLayoutFooterStyle,
|
||||
@ -11,8 +13,8 @@ import {
|
||||
import { Menu } from '@vben-core/icons';
|
||||
import { VbenIconButton } from '@vben-core/shadcn-ui';
|
||||
import { ELEMENT_ID_MAIN_CONTENT } from '@vben-core/shared/constants';
|
||||
|
||||
import { useMouse, useScroll, useThrottleFn } from '@vueuse/core';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
import {
|
||||
LayoutContent,
|
||||
@ -60,10 +62,16 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
});
|
||||
|
||||
const emit = defineEmits<{ sideMouseLeave: []; toggleSidebar: [] }>();
|
||||
const sidebarCollapse = defineModel<boolean>('sidebarCollapse');
|
||||
const sidebarCollapse = defineModel<boolean>('sidebarCollapse', {
|
||||
default: false,
|
||||
});
|
||||
const sidebarExtraVisible = defineModel<boolean>('sidebarExtraVisible');
|
||||
const sidebarExtraCollapse = defineModel<boolean>('sidebarExtraCollapse');
|
||||
const sidebarExpandOnHover = defineModel<boolean>('sidebarExpandOnHover');
|
||||
const sidebarExtraCollapse = defineModel<boolean>('sidebarExtraCollapse', {
|
||||
default: false,
|
||||
});
|
||||
const sidebarExpandOnHover = defineModel<boolean>('sidebarExpandOnHover', {
|
||||
default: false,
|
||||
});
|
||||
const sidebarEnable = defineModel<boolean>('sidebarEnable', { default: true });
|
||||
|
||||
// side是否处于hover状态展开菜单中
|
||||
|
@ -1,14 +1,20 @@
|
||||
import type { Component, DefineComponent } from 'vue';
|
||||
|
||||
import type {
|
||||
AccessModeType,
|
||||
GenerateMenuAndRoutesOptions,
|
||||
RouteRecordRaw,
|
||||
} from '@vben/types';
|
||||
|
||||
import { defineComponent, h } from 'vue';
|
||||
|
||||
import {
|
||||
cloneDeep,
|
||||
generateMenus,
|
||||
generateRoutesByBackend,
|
||||
generateRoutesByFrontend,
|
||||
isFunction,
|
||||
isString,
|
||||
mapTree,
|
||||
setObjToUrlParams,
|
||||
} from '@vben/utils';
|
||||
@ -89,8 +95,31 @@ async function generateRoutes(
|
||||
/**
|
||||
* 调整路由树,做以下处理:
|
||||
* 1. 对未添加redirect的路由添加redirect
|
||||
* 2. 将懒加载的组件名称修改为当前路由的名称(如果启用了keep-alive的话)
|
||||
*/
|
||||
resultRoutes = mapTree(resultRoutes, (route) => {
|
||||
// 重新包装component,使用与路由名称相同的name以支持keep-alive的条件缓存。
|
||||
if (
|
||||
route.meta?.keepAlive &&
|
||||
isFunction(route.component) &&
|
||||
route.name &&
|
||||
isString(route.name)
|
||||
) {
|
||||
const originalComponent = route.component as () => Promise<{
|
||||
default: Component | DefineComponent;
|
||||
}>;
|
||||
route.component = async () => {
|
||||
const component = await originalComponent();
|
||||
if (!component.default) return component;
|
||||
return defineComponent({
|
||||
name: route.name as string,
|
||||
setup(props, { attrs, slots }) {
|
||||
return () => h(component.default, { ...props, ...attrs }, slots);
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// 如果有redirect或者没有子路由,则直接返回
|
||||
if (route.redirect || !route.children || route.children.length === 0) {
|
||||
return route;
|
||||
|
@ -3,11 +3,12 @@
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component, SetupContext } from 'vue';
|
||||
import type { Component } from 'vue';
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
import type { Recordable } from '@vben/types';
|
||||
|
||||
import { h } from 'vue';
|
||||
import { defineComponent, getCurrentInstance, h, ref } from 'vue';
|
||||
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
import { $t } from '@vben/locales';
|
||||
@ -41,10 +42,30 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
component: T,
|
||||
type: 'input' | 'select',
|
||||
) => {
|
||||
return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
|
||||
const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`);
|
||||
return h(component, { ...props, ...attrs, placeholder }, slots);
|
||||
};
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: component.name,
|
||||
setup: (props: any, { attrs, expose, slots }) => {
|
||||
const placeholder =
|
||||
props?.placeholder ||
|
||||
attrs?.placeholder ||
|
||||
$t(`ui.placeholder.${type}`);
|
||||
// 透传组件暴露的方法
|
||||
const innerRef = ref();
|
||||
const publicApi: Recordable<any> = {};
|
||||
expose(publicApi);
|
||||
const instance = getCurrentInstance();
|
||||
instance?.proxy?.$nextTick(() => {
|
||||
for (const key in innerRef.value) {
|
||||
if (typeof innerRef.value[key] === 'function') {
|
||||
publicApi[key] = innerRef.value[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
return () =>
|
||||
h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||
|
@ -1,8 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import type { VbenFormSchema } from '@vben/common-ui';
|
||||
import type { BasicOption } from '@vben/types';
|
||||
import type { BasicOption, Recordable } from '@vben/types';
|
||||
|
||||
import { computed, markRaw } from 'vue';
|
||||
import { computed, markRaw, useTemplateRef } from 'vue';
|
||||
|
||||
import { AuthenticationLogin, SliderCaptcha, z } from '@vben/common-ui';
|
||||
import { $t } from '@vben/locales';
|
||||
@ -104,12 +104,28 @@ const formSchema = computed((): VbenFormSchema[] => {
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const loginRef =
|
||||
useTemplateRef<InstanceType<typeof AuthenticationLogin>>('loginRef');
|
||||
|
||||
async function onSubmit(params: Recordable<any>) {
|
||||
authStore.authLogin(params).catch(() => {
|
||||
// 登陆失败,刷新验证码的演示
|
||||
|
||||
// 使用表单API获取验证码组件实例,并调用其resume方法来重置验证码
|
||||
loginRef.value
|
||||
?.getFormApi()
|
||||
?.getFieldComponentRef<InstanceType<typeof SliderCaptcha>>('captcha')
|
||||
?.resume();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthenticationLogin
|
||||
ref="loginRef"
|
||||
:form-schema="formSchema"
|
||||
:loading="authStore.loginLoading"
|
||||
@submit="authStore.authLogin"
|
||||
@submit="onSubmit"
|
||||
/>
|
||||
</template>
|
||||
|
@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import type { RefSelectProps } from 'ant-design-vue/es/select';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
@ -82,6 +84,7 @@ function handleClick(
|
||||
action:
|
||||
| 'batchAddSchema'
|
||||
| 'batchDeleteSchema'
|
||||
| 'componentRef'
|
||||
| 'disabled'
|
||||
| 'hiddenAction'
|
||||
| 'hiddenResetButton'
|
||||
@ -129,6 +132,11 @@ function handleClick(
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'componentRef': {
|
||||
// 获取下拉组件的实例,并调用它的focus方法
|
||||
formApi.getFieldComponentRef<RefSelectProps>('fieldOptions')?.focus();
|
||||
break;
|
||||
}
|
||||
case 'disabled': {
|
||||
formApi.setState({ commonConfig: { disabled: true } });
|
||||
break;
|
||||
@ -182,6 +190,7 @@ function handleClick(
|
||||
formApi.setState({ submitButtonOptions: { show: true } });
|
||||
break;
|
||||
}
|
||||
|
||||
case 'updateActionAlign': {
|
||||
formApi.setState({
|
||||
// 可以自行调整class
|
||||
@ -189,7 +198,6 @@ function handleClick(
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'updateResetButton': {
|
||||
formApi.setState({
|
||||
resetButtonOptions: { disabled: true },
|
||||
@ -257,6 +265,7 @@ function handleClick(
|
||||
<Button @click="handleClick('batchDeleteSchema')">
|
||||
批量删除表单项
|
||||
</Button>
|
||||
<Button @click="handleClick('componentRef')">下拉组件获取焦点</Button>
|
||||
</Space>
|
||||
<Card title="操作示例">
|
||||
<BaseForm />
|
||||
|
@ -18,25 +18,25 @@ catalog:
|
||||
'@changesets/cli': ^2.28.1
|
||||
'@changesets/git': ^3.0.2
|
||||
'@clack/prompts': ^0.9.1
|
||||
'@commitlint/cli': ^19.7.1
|
||||
'@commitlint/config-conventional': ^19.7.1
|
||||
'@commitlint/cli': ^19.8.0
|
||||
'@commitlint/config-conventional': ^19.8.0
|
||||
'@ctrl/tinycolor': ^4.1.0
|
||||
'@eslint/js': ^9.21.0
|
||||
'@faker-js/faker': ^9.5.1
|
||||
'@iconify/json': ^2.2.311
|
||||
'@eslint/js': ^9.22.0
|
||||
'@faker-js/faker': ^9.6.0
|
||||
'@iconify/json': ^2.2.314
|
||||
'@iconify/tailwind': ^1.2.0
|
||||
'@iconify/vue': ^4.3.0
|
||||
'@intlify/core-base': ^11.1.1
|
||||
'@intlify/core-base': ^11.1.2
|
||||
'@intlify/unplugin-vue-i18n': ^6.0.3
|
||||
'@jspm/generator': ^2.5.1
|
||||
'@manypkg/get-packages': ^2.2.2
|
||||
'@nolebase/vitepress-plugin-git-changelog': ^2.15.0
|
||||
'@playwright/test': ^1.50.1
|
||||
'@pnpm/workspace.read-manifest': ^1000.1.0
|
||||
'@playwright/test': ^1.51.0
|
||||
'@pnpm/workspace.read-manifest': ^1000.1.1
|
||||
'@stylistic/stylelint-plugin': ^3.1.2
|
||||
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e
|
||||
'@tailwindcss/typography': ^0.5.16
|
||||
'@tanstack/vue-query': ^5.66.9
|
||||
'@tanstack/vue-query': ^5.67.2
|
||||
'@tanstack/vue-store': ^0.7.0
|
||||
'@types/archiver': ^6.0.3
|
||||
'@types/eslint': ^9.6.1
|
||||
@ -45,13 +45,13 @@ catalog:
|
||||
'@types/lodash.clonedeep': ^4.5.9
|
||||
'@types/lodash.get': ^4.4.9
|
||||
'@types/lodash.isequal': ^4.5.8
|
||||
'@types/node': ^22.13.5
|
||||
'@types/node': ^22.13.10
|
||||
'@types/nprogress': ^0.2.3
|
||||
'@types/postcss-import': ^14.0.3
|
||||
'@types/qrcode': ^1.5.5
|
||||
'@types/sortablejs': ^1.15.8
|
||||
'@typescript-eslint/eslint-plugin': ^8.25.0
|
||||
'@typescript-eslint/parser': ^8.25.0
|
||||
'@typescript-eslint/eslint-plugin': ^8.26.0
|
||||
'@typescript-eslint/parser': ^8.26.0
|
||||
'@vee-validate/zod': ^4.15.0
|
||||
'@vite-pwa/vitepress': ^0.5.3
|
||||
'@vitejs/plugin-vue': ^5.2.1
|
||||
@ -59,13 +59,13 @@ catalog:
|
||||
'@vue/reactivity': ^3.5.13
|
||||
'@vue/shared': ^3.5.13
|
||||
'@vue/test-utils': ^2.4.6
|
||||
'@vueuse/core': ^12.7.0
|
||||
'@vueuse/core': ^12.8.2
|
||||
'@vueuse/motion': ^2.2.6
|
||||
'@vueuse/integrations': ^12.7.0
|
||||
'@vueuse/integrations': ^12.8.2
|
||||
ant-design-vue: ^4.2.6
|
||||
archiver: ^7.0.1
|
||||
autoprefixer: ^10.4.20
|
||||
axios: ^1.8.1
|
||||
axios: ^1.8.2
|
||||
axios-mock-adapter: ^2.1.0
|
||||
cac: ^6.7.14
|
||||
chalk: ^5.4.1
|
||||
@ -78,30 +78,30 @@ catalog:
|
||||
cross-env: ^7.0.3
|
||||
cspell: 8.17.2
|
||||
cssnano: ^7.0.6
|
||||
cz-git: ^1.11.0
|
||||
czg: ^1.11.0
|
||||
cz-git: ^1.11.1
|
||||
czg: ^1.11.1
|
||||
dayjs: ^1.11.13
|
||||
defu: ^6.1.4
|
||||
depcheck: ^1.4.7
|
||||
dotenv: ^16.4.7
|
||||
echarts: ^5.6.0
|
||||
element-plus: ^2.9.5
|
||||
eslint: ^9.21.0
|
||||
element-plus: ^2.9.6
|
||||
eslint: ^9.22.0
|
||||
eslint-config-turbo: ^2.4.4
|
||||
eslint-plugin-command: ^0.2.7
|
||||
eslint-plugin-eslint-comments: ^3.2.0
|
||||
eslint-plugin-import-x: ^4.6.1
|
||||
eslint-plugin-jsdoc: ^50.6.3
|
||||
eslint-plugin-jsonc: ^2.19.1
|
||||
eslint-plugin-n: ^17.15.1
|
||||
eslint-plugin-n: ^17.16.2
|
||||
eslint-plugin-no-only-tests: ^3.3.0
|
||||
eslint-plugin-perfectionist: ^4.9.0
|
||||
eslint-plugin-perfectionist: ^4.10.0
|
||||
eslint-plugin-prettier: ^5.2.3
|
||||
eslint-plugin-regexp: ^2.7.0
|
||||
eslint-plugin-unicorn: ^56.0.1
|
||||
eslint-plugin-unused-imports: ^4.1.4
|
||||
eslint-plugin-vitest: ^0.5.4
|
||||
eslint-plugin-vue: ^9.32.0
|
||||
eslint-plugin-vue: ^9.33.0
|
||||
execa: ^9.5.2
|
||||
find-up: ^7.0.0
|
||||
get-port: ^7.1.0
|
||||
@ -120,31 +120,31 @@ catalog:
|
||||
lucide-vue-next: ^0.469.0
|
||||
medium-zoom: ^1.1.0
|
||||
naive-ui: ^2.41.0
|
||||
nitropack: ^2.10.4
|
||||
nitropack: ^2.11.6
|
||||
nprogress: ^0.2.0
|
||||
ora: ^8.2.0
|
||||
pinia: ^2.3.1
|
||||
pinia-plugin-persistedstate: ^4.2.0
|
||||
pkg-types: ^1.3.1
|
||||
playwright: ^1.50.1
|
||||
playwright: ^1.51.0
|
||||
postcss: ^8.5.3
|
||||
postcss-antd-fixes: ^0.2.0
|
||||
postcss-html: ^1.8.0
|
||||
postcss-import: ^16.1.0
|
||||
postcss-preset-env: ^10.1.5
|
||||
postcss-scss: ^4.0.9
|
||||
prettier: ^3.5.2
|
||||
prettier: ^3.5.3
|
||||
prettier-plugin-tailwindcss: ^0.6.11
|
||||
publint: ^0.2.12
|
||||
qrcode: ^1.5.4
|
||||
radix-vue: ^1.9.17
|
||||
resolve.exports: ^2.0.3
|
||||
rimraf: ^6.0.1
|
||||
rollup: ^4.34.8
|
||||
rollup: ^4.35.0
|
||||
rollup-plugin-visualizer: ^5.14.0
|
||||
sass: ^1.85.1
|
||||
sortablejs: ^1.15.6
|
||||
stylelint: ^16.14.1
|
||||
stylelint: ^16.15.0
|
||||
stylelint-config-recess-order: ^5.1.1
|
||||
stylelint-config-recommended: ^14.0.1
|
||||
stylelint-config-recommended-scss: ^14.1.0
|
||||
@ -163,9 +163,9 @@ catalog:
|
||||
unbuild: ^3.5.0
|
||||
unplugin-element-plus: ^0.9.1
|
||||
vee-validate: ^4.15.0
|
||||
vite: ^6.2.0
|
||||
vite: ^6.2.1
|
||||
vite-plugin-compression: ^0.5.1
|
||||
vite-plugin-dts: ^4.5.1
|
||||
vite-plugin-dts: ^4.5.3
|
||||
vite-plugin-html: ^3.2.2
|
||||
vite-plugin-lazy-import: ^1.0.7
|
||||
vite-plugin-pwa: ^0.21.1
|
||||
@ -175,12 +175,12 @@ catalog:
|
||||
vitest: ^2.1.9
|
||||
vue: ^3.5.13
|
||||
vue-eslint-parser: ^9.4.3
|
||||
vue-i18n: ^11.1.1
|
||||
vue-i18n: ^11.1.2
|
||||
vue-json-viewer: ^3.0.4
|
||||
vue-router: ^4.5.0
|
||||
vue-tippy: ^6.6.0
|
||||
vue-tsc: 2.1.10
|
||||
vxe-pc-ui: ^4.3.99
|
||||
vxe-pc-ui: ^4.4.8
|
||||
vxe-table: 4.10.0
|
||||
watermark-js-plus: ^1.5.8
|
||||
zod: ^3.24.2
|
||||
|
Loading…
Reference in New Issue
Block a user