From f7bae8ac0f90f6034a11f00b7706e07bc27e672b Mon Sep 17 00:00:00 2001 From: zwtvip Date: Wed, 21 May 2025 00:37:26 +0800 Subject: [PATCH 01/11] chore: export framework components for use in independent pages --- packages/effects/common-ui/src/components/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/effects/common-ui/src/components/index.ts b/packages/effects/common-ui/src/components/index.ts index fc50391e..543fcf3c 100644 --- a/packages/effects/common-ui/src/components/index.ts +++ b/packages/effects/common-ui/src/components/index.ts @@ -17,6 +17,7 @@ export { VbenAvatar, VbenButton, VbenButtonGroup, + VbenCheckbox, VbenCheckButtonGroup, VbenCountToAnimator, VbenFullScreen, @@ -24,6 +25,7 @@ export { VbenLoading, VbenLogo, VbenPinInput, + VbenSelect, VbenSpinner, VbenTree, } from '@vben-core/shadcn-ui'; From 8554924cb9dee1d8bb1fa9f5053dc656fb05f92c Mon Sep 17 00:00:00 2001 From: chenweiran Date: Thu, 3 Jul 2025 17:43:19 +0800 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E5=9B=BE=E7=89=87=E6=8B=BC=E5=9B=BE=E5=88=87=E7=89=87?= =?UTF-8?q?=E5=B9=B3=E7=A7=BB=E7=9A=84=E9=AA=8C=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../slider-translate-captcha/index.vue | 298 ++++++++++++++++++ .../captcha/slider-translate-captcha.vue | 27 ++ 2 files changed, 325 insertions(+) create mode 100644 packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue create mode 100644 playground/src/views/examples/captcha/slider-translate-captcha.vue diff --git a/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue new file mode 100644 index 00000000..d340c201 --- /dev/null +++ b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue @@ -0,0 +1,298 @@ + + + diff --git a/playground/src/views/examples/captcha/slider-translate-captcha.vue b/playground/src/views/examples/captcha/slider-translate-captcha.vue new file mode 100644 index 00000000..78fbd86c --- /dev/null +++ b/playground/src/views/examples/captcha/slider-translate-captcha.vue @@ -0,0 +1,27 @@ + + + From bbd8a53d9d9c2d7d845501c8b60c76e6db85b4b9 Mon Sep 17 00:00:00 2001 From: chenweiran Date: Thu, 3 Jul 2025 18:20:20 +0800 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E5=9B=BE=E7=89=87=E6=8B=BC=E5=9B=BE=E5=88=87=E7=89=87?= =?UTF-8?q?=E5=B9=B3=E7=A7=BB=E7=9A=84=E9=AA=8C=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common-ui/src/components/captcha/index.ts | 1 + .../slider-translate-captcha/index.vue | 19 ++++++++-- .../common-ui/src/components/captcha/types.ts | 36 +++++++++++++++++++ .../src/locales/langs/en-US/examples.json | 1 + .../src/locales/langs/zh-CN/examples.json | 1 + .../src/router/routes/modules/examples.ts | 9 +++++ 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/packages/effects/common-ui/src/components/captcha/index.ts b/packages/effects/common-ui/src/components/captcha/index.ts index 6ad68c49..13634cd4 100644 --- a/packages/effects/common-ui/src/components/captcha/index.ts +++ b/packages/effects/common-ui/src/components/captcha/index.ts @@ -3,4 +3,5 @@ export { default as PointSelectionCaptchaCard } from './point-selection-captcha/ export { default as SliderCaptcha } from './slider-captcha/index.vue'; export { default as SliderRotateCaptcha } from './slider-rotate-captcha/index.vue'; +export { default as SliderTranslateCaptcha } from './slider-translate-captcha/index.vue'; export type * from './types'; diff --git a/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue index d340c201..ece15205 100644 --- a/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue +++ b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue @@ -127,7 +127,12 @@ function resetCanvas() { if (!puzzleCanvas || !pieceCanvas) return; pieceCanvas.width = canvasWidth; const puzzleCanvasCtx = puzzleCanvas.getContext('2d'); - const pieceCanvasCtx = pieceCanvas.getContext('2d'); + // Canvas2D: Multiple readback operations using getImageData + // are faster with the willReadFrequently attribute set to true. + // See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently (anonymous) + const pieceCanvasCtx = pieceCanvas.getContext('2d', { + willReadFrequently: true, + }); if (!puzzleCanvasCtx || !pieceCanvasCtx) return; puzzleCanvasCtx.clearRect(0, 0, canvasWidth, canvasHeight); pieceCanvasCtx.clearRect(0, 0, canvasWidth, canvasHeight); @@ -139,9 +144,16 @@ function initCanvas() { const pieceCanvas = unref(pieceCanvasRef); if (!puzzleCanvas || !pieceCanvas) return; const puzzleCanvasCtx = puzzleCanvas.getContext('2d'); - const pieceCanvasCtx = pieceCanvas.getContext('2d'); + // Canvas2D: Multiple readback operations using getImageData + // are faster with the willReadFrequently attribute set to true. + // See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently (anonymous) + const pieceCanvasCtx = pieceCanvas.getContext('2d', { + willReadFrequently: true, + }); if (!puzzleCanvasCtx || !pieceCanvasCtx) return; const img = new Image(); + // 解决跨域 + img.crossOrigin = 'Anonymous'; img.src = src; img.addEventListener('load', () => { draw(puzzleCanvasCtx, pieceCanvasCtx); @@ -158,6 +170,7 @@ function initCanvas() { ); pieceCanvas.width = pieceLength; pieceCanvasCtx.putImageData(imageData, 0, sy); + setLeft('0'); }); } @@ -265,7 +278,7 @@ onMounted(() => { @click="resume" >
+ import('#/views/examples/captcha/slider-translate-captcha.vue'), + meta: { + title: $t('examples.captcha.sliderTranslateCaptcha'), + }, + }, { name: 'CaptchaPointSelectionExample', path: '/examples/captcha/point-selection', From 8ccd01ade5929a0c49b28b6d684f5b018f42c5d3 Mon Sep 17 00:00:00 2001 From: chenweiran Date: Fri, 4 Jul 2025 10:23:47 +0800 Subject: [PATCH 04/11] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E5=9B=BE=E7=89=87=E6=8B=BC=E5=9B=BE=E5=88=87=E7=89=87?= =?UTF-8?q?=E5=B9=B3=E7=A7=BB=E7=9A=84=E9=AA=8C=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../slider-translate-captcha/index.vue | 20 +++++++++---------- packages/locales/src/langs/en-US/ui.json | 3 +++ packages/locales/src/langs/zh-CN/ui.json | 3 +++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue index ece15205..a1b15654 100644 --- a/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue +++ b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue @@ -53,7 +53,7 @@ const state = reactive({ startTime: 0, endTime: 0, pieceX: 0, - PieceY: 0, + pieceY: 0, moveDistance: 0, isPassing: false, showTip: false, @@ -73,10 +73,10 @@ function setLeft(val: string) { const verifyTip = computed(() => { return state.isPassing - ? $t('ui.captcha.sliderRotateSuccessTip', [ + ? $t('ui.captcha.sliderTranslateSuccessTip', [ ((state.endTime - state.startTime) / 1000).toFixed(1), ]) - : $t('ui.captcha.sliderRotateFailTip'); + : $t('ui.captcha.sliderTranslateFailTip'); }); function handleStart() { state.startTime = Date.now(); @@ -93,7 +93,7 @@ function handleDragEnd() { const { pieceX } = state; const { diffDistance } = props; - if (Math.abs(pieceX - state.moveDistance) >= (diffDistance || 10)) { + if (Math.abs(pieceX - state.moveDistance) >= (diffDistance || 5)) { setLeft('0'); state.moveDistance = 0; } else { @@ -161,7 +161,7 @@ function initCanvas() { pieceCanvasCtx.drawImage(img, 0, 0, canvasWidth, canvasHeight); const pieceLength = squareLength + 2 * circleRadius + 3; const sx = state.pieceX; - const sy = state.PieceY - 2 * circleRadius - 1; + const sy = state.pieceY - 2 * circleRadius - 1; const imageData = pieceCanvasCtx.getImageData( sx, sy, @@ -185,12 +185,12 @@ function draw(ctx1: CanvasRenderingContext2D, ctx2: CanvasRenderingContext2D) { squareLength + 2 * circleRadius, canvasWidth - (squareLength + 2 * circleRadius), ); - state.PieceY = getRandomNumberByRange( + state.pieceY = getRandomNumberByRange( 3 * circleRadius, canvasHeight - (squareLength + 2 * circleRadius), ); - drawPiece(ctx1, state.pieceX, state.PieceY, CanvasOpr.Fill); - drawPiece(ctx2, state.pieceX, state.PieceY, CanvasOpr.Clip); + drawPiece(ctx1, state.pieceX, state.pieceY, CanvasOpr.Fill); + drawPiece(ctx2, state.pieceX, state.pieceY, CanvasOpr.Clip); } // 绘制拼图切块 @@ -246,7 +246,7 @@ function resume() { state.dragging = false; state.isPassing = false; state.pieceX = 0; - state.PieceY = 0; + state.pieceY = 0; basicEl.resume(); resetCanvas(); @@ -290,7 +290,7 @@ onMounted(() => { {{ verifyTip }}
- {{ defaultTip || $t('ui.captcha.sliderRotateDefaultTip') }} + {{ defaultTip || $t('ui.captcha.sliderTranslateDefaultTip') }}
diff --git a/packages/locales/src/langs/en-US/ui.json b/packages/locales/src/langs/en-US/ui.json index 5bfd5d07..0179c225 100644 --- a/packages/locales/src/langs/en-US/ui.json +++ b/packages/locales/src/langs/en-US/ui.json @@ -32,8 +32,11 @@ "sliderDefaultText": "Slider and drag", "alt": "Supports img tag src attribute value", "sliderRotateDefaultTip": "Click picture to refresh", + "sliderTranslateDefaultTip": "Click picture to refresh", "sliderRotateFailTip": "Validation failed", "sliderRotateSuccessTip": "Validation successful, time {0} seconds", + "sliderTranslateFailTip": "Validation failed", + "sliderTranslateSuccessTip": "Validation successful, time {0} seconds", "refreshAriaLabel": "Refresh captcha", "confirmAriaLabel": "Confirm selection", "confirm": "Confirm", diff --git a/packages/locales/src/langs/zh-CN/ui.json b/packages/locales/src/langs/zh-CN/ui.json index c0679581..da2dbeb0 100644 --- a/packages/locales/src/langs/zh-CN/ui.json +++ b/packages/locales/src/langs/zh-CN/ui.json @@ -31,8 +31,11 @@ "sliderSuccessText": "验证通过", "sliderDefaultText": "请按住滑块拖动", "sliderRotateDefaultTip": "点击图片可刷新", + "sliderTranslateDefaultTip": "点击图片可刷新", "sliderRotateFailTip": "验证失败", "sliderRotateSuccessTip": "验证成功,耗时{0}秒", + "sliderTranslateFailTip": "验证失败", + "sliderTranslateSuccessTip": "验证成功,耗时{0}秒", "alt": "支持img标签src属性值", "refreshAriaLabel": "刷新验证码", "confirmAriaLabel": "确认选择", From 1aafb43103c4041e998c5ec2939bc830773661dd Mon Sep 17 00:00:00 2001 From: chenweiran Date: Fri, 4 Jul 2025 10:26:02 +0800 Subject: [PATCH 05/11] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E5=9B=BE=E7=89=87=E6=8B=BC=E5=9B=BE=E5=88=87=E7=89=87?= =?UTF-8?q?=E5=B9=B3=E7=A7=BB=E7=9A=84=E9=AA=8C=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/captcha/slider-translate-captcha/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue index a1b15654..81b7342b 100644 --- a/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue +++ b/packages/effects/common-ui/src/components/captcha/slider-translate-captcha/index.vue @@ -93,7 +93,7 @@ function handleDragEnd() { const { pieceX } = state; const { diffDistance } = props; - if (Math.abs(pieceX - state.moveDistance) >= (diffDistance || 5)) { + if (Math.abs(pieceX - state.moveDistance) >= (diffDistance || 3)) { setLeft('0'); state.moveDistance = 0; } else { From 243f3a201d610f3146d98f96006e057fcdc2238f Mon Sep 17 00:00:00 2001 From: sqchen <9110848@qq.com> Date: Sat, 5 Jul 2025 00:19:12 +0800 Subject: [PATCH 06/11] feat: add scrollToFirstError to the form component --- docs/src/components/common-ui/vben-form.md | 1 + docs/src/demos/vben-form/rules/index.vue | 1 + .../form-ui/src/components/form-actions.vue | 11 +- packages/@core/ui-kit/form-ui/src/form-api.ts | 49 ++++- packages/@core/ui-kit/form-ui/src/types.ts | 6 + .../src/locales/langs/en-US/examples.json | 1 + .../src/locales/langs/zh-CN/examples.json | 1 + .../src/router/routes/modules/examples.ts | 9 + .../examples/form/scroll-to-error-test.vue | 183 ++++++++++++++++++ 9 files changed, 258 insertions(+), 4 deletions(-) create mode 100644 playground/src/views/examples/form/scroll-to-error-test.vue diff --git a/docs/src/components/common-ui/vben-form.md b/docs/src/components/common-ui/vben-form.md index 7abb3051..a6d45525 100644 --- a/docs/src/components/common-ui/vben-form.md +++ b/docs/src/components/common-ui/vben-form.md @@ -324,6 +324,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单 | submitOnEnter | 按下回车健时提交表单 | `boolean` | false | | submitOnChange | 字段值改变时提交表单(内部防抖,这个属性一般用于表格的搜索表单) | `boolean` | false | | compact | 是否紧凑模式(忽略为校验信息所预留的空间) | `boolean` | false | +| scrollToFirstError | 表单验证失败时是否自动滚动到第一个错误字段 | `boolean` | false | ::: tip handleValuesChange diff --git a/docs/src/demos/vben-form/rules/index.vue b/docs/src/demos/vben-form/rules/index.vue index 7abcc6f6..78e59813 100644 --- a/docs/src/demos/vben-form/rules/index.vue +++ b/docs/src/demos/vben-form/rules/index.vue @@ -15,6 +15,7 @@ const [Form] = useVbenForm({ handleSubmit: onSubmit, // 垂直布局,label和input在不同行,值为vertical // 水平布局,label和input在同一行 + scrollToFirstError: true, layout: 'horizontal', schema: [ { diff --git a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue index c5a3f9c2..18975596 100644 --- a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue +++ b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue @@ -48,13 +48,18 @@ const queryFormStyle = computed(() => { async function handleSubmit(e: Event) { e?.preventDefault(); e?.stopPropagation(); - const { valid } = await form.validate(); + const props = unref(rootProps); + if (!props.formApi) { + return; + } + + const { valid } = await props.formApi.validate(); if (!valid) { return; } - const values = toRaw(await unref(rootProps).formApi?.getValues()); - await unref(rootProps).handleSubmit?.(values); + const values = toRaw(await props.formApi.getValues()); + await props.handleSubmit?.(values); } async function handleReset(e: Event) { diff --git a/packages/@core/ui-kit/form-ui/src/form-api.ts b/packages/@core/ui-kit/form-ui/src/form-api.ts index e097a465..bdc44de7 100644 --- a/packages/@core/ui-kit/form-ui/src/form-api.ts +++ b/packages/@core/ui-kit/form-ui/src/form-api.ts @@ -39,6 +39,7 @@ function getDefaultState(): VbenFormProps { layout: 'horizontal', resetButtonOptions: {}, schema: [], + scrollToFirstError: false, showCollapseButton: false, showDefaultActions: true, submitButtonOptions: {}, @@ -253,6 +254,41 @@ export class FormApi { }); } + /** + * 滚动到第一个错误字段 + * @param errors 验证错误对象 + */ + scrollToFirstError(errors: Record | string) { + // https://github.com/logaretm/vee-validate/discussions/3835 + const firstErrorFieldName = + typeof errors === 'string' ? errors : Object.keys(errors)[0]; + + if (!firstErrorFieldName) { + return; + } + + let el = document.querySelector( + `[name="${firstErrorFieldName}"]`, + ) as HTMLElement; + + // 如果通过 name 属性找不到,尝试通过组件引用查找, 正常情况下不会走到这,怕哪天 vee-validate 改了 name 属性有个兜底的 + if (!el) { + const componentRef = this.getFieldComponentRef(firstErrorFieldName); + if (componentRef && componentRef.$el instanceof HTMLElement) { + el = componentRef.$el; + } + } + + if (el) { + // 滚动到错误字段,添加一些偏移量以确保字段完全可见 + el.scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'nearest', + }); + } + } + async setFieldValue(field: string, value: any, shouldValidate?: boolean) { const form = await this.getForm(); form.setFieldValue(field, value, shouldValidate); @@ -377,14 +413,21 @@ export class FormApi { if (Object.keys(validateResult?.errors ?? {}).length > 0) { console.error('validate error', validateResult?.errors); + + if (this.state?.scrollToFirstError) { + this.scrollToFirstError(validateResult.errors); + } } return validateResult; } async validateAndSubmitForm() { const form = await this.getForm(); - const { valid } = await form.validate(); + const { valid, errors } = await form.validate(); if (!valid) { + if (this.state?.scrollToFirstError) { + this.scrollToFirstError(errors); + } return; } return await this.submitForm(); @@ -396,6 +439,10 @@ export class FormApi { if (Object.keys(validateResult?.errors ?? {}).length > 0) { console.error('validate error', validateResult?.errors); + + if (this.state?.scrollToFirstError) { + this.scrollToFirstError(fieldName); + } } return validateResult; } diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts index 34312ae7..aa4f2dc6 100644 --- a/packages/@core/ui-kit/form-ui/src/types.ts +++ b/packages/@core/ui-kit/form-ui/src/types.ts @@ -387,6 +387,12 @@ export interface VbenFormProps< */ resetButtonOptions?: ActionButtonOptions; + /** + * 验证失败时是否自动滚动到第一个错误字段 + * @default true + */ + scrollToFirstError?: boolean; + /** * 是否显示默认操作按钮 * @default true diff --git a/playground/src/locales/langs/en-US/examples.json b/playground/src/locales/langs/en-US/examples.json index 9335b28b..c8d2b8c4 100644 --- a/playground/src/locales/langs/en-US/examples.json +++ b/playground/src/locales/langs/en-US/examples.json @@ -19,6 +19,7 @@ "custom": "Custom Component", "api": "Api", "merge": "Merge Form", + "scrollToError": "Scroll to Error Field", "upload-error": "Partial file upload failed", "upload-urls": "Urls after file upload", "file": "file", diff --git a/playground/src/locales/langs/zh-CN/examples.json b/playground/src/locales/langs/zh-CN/examples.json index ff11d7fd..035fbe24 100644 --- a/playground/src/locales/langs/zh-CN/examples.json +++ b/playground/src/locales/langs/zh-CN/examples.json @@ -22,6 +22,7 @@ "custom": "自定义组件", "api": "Api", "merge": "合并表单", + "scrollToError": "滚动到错误字段", "upload-error": "部分文件上传失败", "upload-urls": "文件上传后的网址", "file": "文件", diff --git a/playground/src/router/routes/modules/examples.ts b/playground/src/router/routes/modules/examples.ts index c91303c7..7bdbe5d0 100644 --- a/playground/src/router/routes/modules/examples.ts +++ b/playground/src/router/routes/modules/examples.ts @@ -85,6 +85,15 @@ const routes: RouteRecordRaw[] = [ title: $t('examples.form.merge'), }, }, + { + name: 'FormScrollToErrorExample', + path: '/examples/form/scroll-to-error-test', + component: () => + import('#/views/examples/form/scroll-to-error-test.vue'), + meta: { + title: $t('examples.form.scrollToError'), + }, + }, ], }, { diff --git a/playground/src/views/examples/form/scroll-to-error-test.vue b/playground/src/views/examples/form/scroll-to-error-test.vue new file mode 100644 index 00000000..61e8815c --- /dev/null +++ b/playground/src/views/examples/form/scroll-to-error-test.vue @@ -0,0 +1,183 @@ + + + From f1051c8773a2c2599488401ba506b325d5719063 Mon Sep 17 00:00:00 2001 From: sqchen <9110848@qq.com> Date: Sat, 5 Jul 2025 00:50:53 +0800 Subject: [PATCH 07/11] feat: add scrollToFirstError to the form component --- packages/@core/ui-kit/form-ui/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts index aa4f2dc6..ccfe8dd8 100644 --- a/packages/@core/ui-kit/form-ui/src/types.ts +++ b/packages/@core/ui-kit/form-ui/src/types.ts @@ -389,7 +389,7 @@ export interface VbenFormProps< /** * 验证失败时是否自动滚动到第一个错误字段 - * @default true + * @default false */ scrollToFirstError?: boolean; From b333fd676d6854364e1096b984cccb679b131e66 Mon Sep 17 00:00:00 2001 From: xue-jn <40727429+xue-jn@users.noreply.github.com> Date: Sun, 6 Jul 2025 20:26:06 +0800 Subject: [PATCH 08/11] docs: update vben-drawer.md (#6478) * docs: update vben-drawer.md * docs: update vben-drawer.md --------- Co-authored-by: Jin Mao <50581550+jinmao88@users.noreply.github.com> --- docs/src/components/common-ui/vben-drawer.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/components/common-ui/vben-drawer.md b/docs/src/components/common-ui/vben-drawer.md index b66bd3a0..3a28cce7 100644 --- a/docs/src/components/common-ui/vben-drawer.md +++ b/docs/src/components/common-ui/vben-drawer.md @@ -22,7 +22,7 @@ outline: deep ## 基础用法 -使用 `useVbenDrawer` 创建最基础的模态框。 +使用 `useVbenDrawer` 创建最基础的抽屉。 @@ -52,7 +52,7 @@ Drawer 内的内容一般业务中,会比较复杂,所以我们可以将 dra ::: info 注意 -- `VbenDrawer` 组件对与参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenDrawer参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。 +- `VbenDrawer` 组件对于参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenDrawer参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。 - 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenDrawer`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。 - 使用了`connectedComponent`参数时,可以配置`destroyOnClose`属性来决定当关闭弹窗时,是否要销毁`connectedComponent`组件(重新创建`connectedComponent`组件,这将会把其内部所有的变量、状态、数据等恢复到初始状态。)。 - 如果抽屉的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultDrawerProps`的参数来设置默认的属性,如默认隐藏全屏按钮,修改默认ZIndex等。 @@ -77,7 +77,7 @@ const [Drawer, drawerApi] = useVbenDrawer({ | 属性名 | 描述 | 类型 | 默认值 | | --- | --- | --- | --- | | appendToMain | 是否挂载到内容区域(默认挂载到body) | `boolean` | `false` | -| connectedComponent | 连接另一个Modal组件 | `Component` | - | +| connectedComponent | 连接另一个Drawer组件 | `Component` | - | | destroyOnClose | 关闭时销毁 | `boolean` | `false` | | title | 标题 | `string\|slot` | - | | titleTooltip | 标题提示信息 | `string\|slot` | - | @@ -96,7 +96,7 @@ const [Drawer, drawerApi] = useVbenDrawer({ | cancelText | 取消按钮文本 | `string\|slot` | `取消` | | placement | 抽屉弹出位置 | `'left'\|'right'\|'top'\|'bottom'` | `right` | | showCancelButton | 显示取消按钮 | `boolean` | `true` | -| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` | +| showConfirmButton | 显示确认按钮 | `boolean` | `true` | | class | modal的class,宽度通过这个配置 | `string` | - | | contentClass | modal内容区域的class | `string` | - | | footerClass | modal底部区域的class | `string` | - | From bbf02875111dac97bc2f1950d546c2ccee5c5281 Mon Sep 17 00:00:00 2001 From: Jin Mao <50581550+jinmao88@users.noreply.github.com> Date: Mon, 7 Jul 2025 08:21:25 +0800 Subject: [PATCH 09/11] chore: fix lint warning (#6487) --- packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue b/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue index 955ae67e..c6c4df7d 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue @@ -287,7 +287,11 @@ defineExpose({ class="tree-node focus:ring-grass8 my-0.5 flex items-center rounded px-2 py-1 outline-none focus:ring-2" >
{{ $t('ui.widgets.lockScreen.unlock') }}
-
-
- - {{ meridiem }} - - {{ hour }} -
-
- {{ minute }} +
+
+
+ + {{ meridiem }} + + {{ hour }} +
+
+ {{ minute }} +
@@ -117,9 +121,8 @@ useScrollLock(); class="flex-center size-full" @keydown.enter.prevent="handleSubmit" > -
+
-
@@ -145,12 +148,13 @@ useScrollLock();
-
- {{ hour }}:{{ minute }} {{ meridiem }} +
+ {{ hour }}:{{ minute }} + {{ meridiem }}
-
{{ date }}
+
{{ date }}
From 1bc5d2986b0a237fe146a73fbd791ffedfd07f2a Mon Sep 17 00:00:00 2001 From: Jin Mao <50581550+jinmao88@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:15:39 +0800 Subject: [PATCH 11/11] chore: update-vxe-table (#6516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: update vxe-pc-ui,vxe-table * fix(ui): 修复代理配置初始化方法名错误 * fix(ui): 修改远程表格刷新配置 * chroe: update vxeTable 更新到最新 --- packages/effects/plugins/src/vxe-table/use-vxe-grid.vue | 2 +- playground/src/views/examples/vxe-table/remote.vue | 2 +- pnpm-workspace.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue b/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue index f3eb6735..9844c409 100644 --- a/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue +++ b/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue @@ -300,7 +300,7 @@ async function init() { const enableProxyConfig = options.value.proxyConfig?.enabled; if (enableProxyConfig && autoLoad) { props.api.grid.commitProxy?.( - '_init', + 'initial', formOptions.value ? ((await formApi.getValues()) ?? {}) : {}, ); // props.api.reload(formApi.form?.values ?? {}); diff --git a/playground/src/views/examples/vxe-table/remote.vue b/playground/src/views/examples/vxe-table/remote.vue index 907c1e2c..7042019f 100644 --- a/playground/src/views/examples/vxe-table/remote.vue +++ b/playground/src/views/examples/vxe-table/remote.vue @@ -55,7 +55,7 @@ const gridOptions: VxeGridProps = { custom: true, export: true, // import: true, - refresh: { code: 'query' }, + refresh: true, zoom: true, }, }; diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 887e74dc..758ff050 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -187,8 +187,8 @@ catalog: vue-router: ^4.5.1 vue-tippy: ^6.7.1 vue-tsc: 2.2.10 - vxe-pc-ui: ^4.6.42 - vxe-table: ^4.13.51 + vxe-pc-ui: ^4.7.12 + vxe-table: ^4.14.4 watermark-js-plus: ^1.6.2 zod: ^3.25.67 zod-defaults: ^0.1.3