mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-09-16 00:09:59 +08:00
version: v5.2.2
This commit is contained in:
parent
4bce5f7713
commit
49af61a339
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -22,6 +22,7 @@
|
||||
"cSpell.words": [
|
||||
"baomitu",
|
||||
"bezier",
|
||||
"Cascader",
|
||||
"Clickoutside",
|
||||
"codabar",
|
||||
"commitmsg",
|
||||
@ -44,6 +45,7 @@
|
||||
"siderbar",
|
||||
"snapline",
|
||||
"stylelint",
|
||||
"unocss",
|
||||
"WUJIE",
|
||||
"zlevel"
|
||||
]
|
||||
|
20
CHANGELOG.md
20
CHANGELOG.md
@ -1,3 +1,23 @@
|
||||
## 5.2.2
|
||||
|
||||
## Feats
|
||||
|
||||
- `RForm` 组件相关
|
||||
- 新增 `submitWhenEnter` 配置项,允许在按下回车键时自动触发表单的校验,如果校验成功则会自动触发 `onFinish` 事件
|
||||
- 新增 `onFinish` 配置项,允许在表单校验成功后自动触发的事件
|
||||
- 新增 `autocomplete` 配置项,允许配置表单的自动完成功能,默认配置为 `off`
|
||||
- 新增 `loading` 配置项,允许配置表单的加载状态
|
||||
- 新增 `loadingDescription` 配置项,允许配置表单的加载状态的描述
|
||||
- `useForm` 相关
|
||||
- 新增 `validateTargetField` 方法,允许验证指定表单项的规则
|
||||
- 初始化方法现在支持传入函数,允许动态获取表单的初始化值与规则
|
||||
- `formModel` 方法现在会默认联合 `Recordable` 类型,获取初始化类型中未获取到的类型时,默认推到为 `any` 类型
|
||||
- 新增了 `formConditionRef` 属性,现在可以在内部解构获取一个 `ref` 包裹的响应式初始化表单对象值
|
||||
- 新增了 `updateFormCondition` 方法,允许更新表单的值,该方法会覆盖初始化值
|
||||
- 更新依赖为主流版本
|
||||
- 新增 `unocss` 原子化样式库,但是不推荐全量使用,仅作为一些简单的样式片段使用,否则在调试的时候将会是灾难
|
||||
> 新增 `unocss` 后,在使用 `ProTable` 组件的流体高度最外层父元素配置时,可以便捷的配置 `h-full` 即可。
|
||||
|
||||
## 5.2.1
|
||||
|
||||
## Feats
|
||||
|
10
package.json
10
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ray-template",
|
||||
"private": false,
|
||||
"version": "5.2.1",
|
||||
"version": "5.2.2",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": "^18.0.0 || ^20.0.0 || >=22.0.0",
|
||||
@ -48,8 +48,8 @@
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "1.1.0",
|
||||
"naive-ui": "^2.42.0",
|
||||
"pinia": "^3.0.1",
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.4.1",
|
||||
"print-js": "^1.6.0",
|
||||
"vue": "^3.5.17",
|
||||
"vue-demi": "0.14.10",
|
||||
@ -59,8 +59,6 @@
|
||||
"vue3-next-qrcode": "3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@amap/amap-jsapi-types": "0.0.15",
|
||||
"@ant-design/icons-vue": "7.0.1",
|
||||
"@commitlint/cli": "19.7.1",
|
||||
"@commitlint/config-conventional": "19.7.1",
|
||||
"@eslint/js": "9.28.0",
|
||||
@ -70,7 +68,6 @@
|
||||
"@types/jsbarcode": "3.11.4",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/mockjs": "1.0.10",
|
||||
"@types/three": "0.171.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.24.0",
|
||||
"@typescript-eslint/parser": "8.24.0",
|
||||
"@vitejs/plugin-vue": "5.2.3",
|
||||
@ -96,6 +93,7 @@
|
||||
"sass": "1.86.3",
|
||||
"svg-sprite-loader": "6.0.11",
|
||||
"typescript": "5.8.3",
|
||||
"unocss": "66.3.3",
|
||||
"unplugin-auto-import": "19.1.2",
|
||||
"unplugin-vue-components": "0.28.0",
|
||||
"vite": "6.3.5",
|
||||
|
834
pnpm-lock.yaml
generated
834
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,17 +1,41 @@
|
||||
import { NForm } from 'naive-ui'
|
||||
import { NForm, NSpin } from 'naive-ui'
|
||||
|
||||
import props from './props'
|
||||
import { call } from '@/utils'
|
||||
import { call, unrefElement } from '@/utils'
|
||||
import { useTemplateRef } from 'vue'
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
|
||||
import type { RFormInst } from './types'
|
||||
import type { FormProps } from 'naive-ui'
|
||||
import type { ShallowRef } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RForm',
|
||||
props,
|
||||
setup(props, { expose }) {
|
||||
const formRef = useTemplateRef<RFormInst>('formRef')
|
||||
const currentSubmitFn = computed(() => props.onFinish ?? Promise.resolve)
|
||||
|
||||
const bindKeydownListener = (e: KeyboardEvent) => {
|
||||
const keyCode = e.code
|
||||
|
||||
if (keyCode === 'Enter') {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
||||
formRef.value?.validate().then(currentSubmitFn.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (props.submitWhenEnter) {
|
||||
useEventListener(
|
||||
formRef as unknown as ShallowRef<HTMLElement>,
|
||||
'keydown',
|
||||
bindKeydownListener,
|
||||
{
|
||||
capture: true,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 主动调用 register 方法,满足 useForm 方法正常调用
|
||||
@ -20,6 +44,16 @@ export default defineComponent({
|
||||
if (onRegister && formRef.value) {
|
||||
call(onRegister, formRef.value)
|
||||
}
|
||||
|
||||
if (formRef.value) {
|
||||
const formElement = unrefElement(
|
||||
formRef.value as unknown as HTMLFormElement,
|
||||
)
|
||||
|
||||
if (formElement) {
|
||||
formElement.autocomplete = props.autocomplete
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
expose()
|
||||
@ -30,13 +64,22 @@ export default defineComponent({
|
||||
},
|
||||
render() {
|
||||
const { $attrs, $props, $slots } = this
|
||||
const { loading, loadingDescription, ...restProps } = $props
|
||||
|
||||
return (
|
||||
<NForm {...$attrs} {...($props as FormProps)} ref="formRef">
|
||||
{{
|
||||
...$slots,
|
||||
<NSpin
|
||||
show={loading}
|
||||
description={loadingDescription}
|
||||
style={{
|
||||
height: 'auto',
|
||||
}}
|
||||
</NForm>
|
||||
>
|
||||
<NForm {...$attrs} {...restProps} ref="formRef">
|
||||
{{
|
||||
...$slots,
|
||||
}}
|
||||
</NForm>
|
||||
</NSpin>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -40,10 +40,11 @@ const useForm = <
|
||||
T extends Recordable = Recordable,
|
||||
R extends RFormRules = RFormRules,
|
||||
>(
|
||||
model?: T,
|
||||
rules?: R,
|
||||
model?: T | (() => T),
|
||||
rules?: R | (() => R),
|
||||
) => {
|
||||
const formRef = shallowRef<RFormInst>()
|
||||
const formModelRef = ref<T>()
|
||||
|
||||
const register = (inst: RFormInst) => {
|
||||
if (inst) {
|
||||
@ -61,6 +62,15 @@ const useForm = <
|
||||
return formRef.value
|
||||
}
|
||||
|
||||
// 初始化 formModelRef 的值,根据 model 的类型进行初始化
|
||||
const initialFormModel = () => {
|
||||
if (typeof model === 'function') {
|
||||
formModelRef.value = model() ?? ({} as T)
|
||||
} else {
|
||||
formModelRef.value = cloneDeep(model) ?? ({} as T)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
@ -91,6 +101,9 @@ const useForm = <
|
||||
* 该方法可以实现重置表单的需求,因为在 vue 的设计理念中,表单的值绑定是直接绑定在每个组件上,
|
||||
* 而不是利用 Form 表单机制,所以需要这么去做表单的初始化操作维护机制。
|
||||
*
|
||||
* 在 5.2.2 版本中,新增了 formConditionRef 属性,现在可以解构获取一个 ref 包裹的响应式初始化表单对象值;
|
||||
* 这样就可以直接在 hook 中调用一个响应式的表单对象值。
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* interface FormModel {
|
||||
@ -109,7 +122,13 @@ const useForm = <
|
||||
* formModelRef.value = formModel()
|
||||
* }
|
||||
*/
|
||||
const formModel = () => cloneDeep(model) || ({} as T)
|
||||
const formModel = (): T & Recordable => {
|
||||
if (typeof model === 'function') {
|
||||
return model()
|
||||
}
|
||||
|
||||
return cloneDeep(model) || ({} as T)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@ -118,12 +137,17 @@ const useForm = <
|
||||
*
|
||||
* 调用该方法时,需要确保初始化 useForm 方法的时候传入了 rules,否则可能有意想不到的问题发生。
|
||||
*/
|
||||
const formRules = () => cloneDeep(rules) || ({} as R)
|
||||
const formRules = () => {
|
||||
if (typeof rules === 'function') {
|
||||
return rules()
|
||||
}
|
||||
|
||||
return cloneDeep(rules) || ({} as R)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param values 需要重置的表单值
|
||||
* @param extraValues 额外的表单值,当你需要初始化额外的表单值的时候,可以传入该参数
|
||||
* @param values 需要重置的表单值,该参数会覆盖初始化值
|
||||
*
|
||||
* @warning
|
||||
* 请注意初始化值的问题,如果设置初始化值为 undefined,
|
||||
@ -137,14 +161,80 @@ const useForm = <
|
||||
* 所以,最佳的实践应该是初始化 useForm 方法的时候,就应该确定好初始化值。
|
||||
* 然后,在需要重置表单的时候,直接调用该方法即可。
|
||||
*/
|
||||
const reset = <Values extends T = T>(
|
||||
values: Values & Recordable,
|
||||
extraValues?: Recordable,
|
||||
) => {
|
||||
Object.assign(values ?? {}, formModel(), extraValues)
|
||||
const reset = <Values extends T = T>(values?: Values & Recordable) => {
|
||||
formModelRef.value = Object.assign(
|
||||
formModelRef.value as T,
|
||||
formModel(),
|
||||
values,
|
||||
)
|
||||
restoreValidation()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key 需要验证的表单项的 key
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/form#partially-apply-rules.vue
|
||||
*
|
||||
* @description
|
||||
* 验证表单项的规则。
|
||||
*
|
||||
* 注意,该方法想要正常运转,需要在定义 rules 时定义唯一 key;
|
||||
* 否则,该逻辑执行会失败。
|
||||
*
|
||||
* @example
|
||||
* const [register, { validateTargetField }] = useForm(
|
||||
* {
|
||||
* name: null,
|
||||
* },
|
||||
* {
|
||||
* name: {
|
||||
* required: true,
|
||||
* message: 'name is required',
|
||||
* trigger: ['blur', 'change'],
|
||||
* type: 'string',
|
||||
* key: 'name',
|
||||
* },
|
||||
* },
|
||||
* )
|
||||
*
|
||||
* validateTargetField('name')
|
||||
*/
|
||||
const validateTargetField = (key: string) => {
|
||||
if (!key || typeof key !== 'string') {
|
||||
throw new Error(
|
||||
`[useForm-validateTargetField]: except key is string, but got ${typeof key}.`,
|
||||
)
|
||||
}
|
||||
|
||||
return validate(void 0, (rules) => {
|
||||
return rules?.key === key
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 更新表单的值,该方法会覆盖初始化值。
|
||||
* 推荐在表单组件中使用该方法,而不是直接修改表单的值,符合函数式的理念。
|
||||
*
|
||||
* @example
|
||||
* const [register, { updateFormCondition }] = useForm(
|
||||
* {
|
||||
* name: null,
|
||||
* },
|
||||
* )
|
||||
*
|
||||
* updateFormCondition({
|
||||
* name: 'John',
|
||||
* })
|
||||
*/
|
||||
const updateFormCondition = (values: T & Recordable) => {
|
||||
formModelRef.value = Object.assign(formModelRef.value as T, values)
|
||||
}
|
||||
|
||||
initialFormModel()
|
||||
|
||||
return [
|
||||
register,
|
||||
{
|
||||
@ -154,6 +244,9 @@ const useForm = <
|
||||
formModel,
|
||||
formRules,
|
||||
reset,
|
||||
validateTargetField,
|
||||
formConditionRef: formModelRef as Ref<T>,
|
||||
updateFormCondition,
|
||||
},
|
||||
] as const
|
||||
}
|
||||
|
@ -1,10 +1,75 @@
|
||||
import { formProps } from 'naive-ui'
|
||||
import { omit } from 'lodash-es'
|
||||
|
||||
import type { MaybeArray } from '@/types'
|
||||
import type { MaybeArray, AnyFC } from '@/types'
|
||||
import type { RFormInst } from './types'
|
||||
|
||||
const props = {
|
||||
...formProps,
|
||||
...omit(formProps, ['onSubmit']),
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 表单的加载状态。
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 表单的加载状态的描述。
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
loadingDescription: {
|
||||
type: String,
|
||||
default: void 0,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 表单的自动完成功能。
|
||||
*
|
||||
* @default 'off'
|
||||
*/
|
||||
autocomplete: {
|
||||
type: String as PropType<AutoFillBase>,
|
||||
default: 'off',
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 是否在按下回车键时自动触发表单的校验,如果校验成功则会自动触发 onFinish 事件。
|
||||
* 该功能需要结合 onFinish 属性使用。
|
||||
*
|
||||
* 注意,该属性不支持响应式更新,只依赖于初始化传入的值;
|
||||
* 因为该方法特性的原因,做响应式的更新意义不大。
|
||||
*
|
||||
* 并且该属性启用后,会自动的拦截 Enter 键的默认行为;
|
||||
* 例如 NSelect, NInput 等官方自带组件的默认快捷键功能,都会被阻止;
|
||||
* 但是不得不这么做,以避免一些奇奇怪怪的问题。
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
submitWhenEnter: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 表单校验成功后自动触发的事件,该事件的触发时机为 submitWhenEnter 属性为 true 时,按下回车键触发。
|
||||
* 该功能需要结合 submitWhenEnter 属性使用。
|
||||
*
|
||||
* @default null
|
||||
*/
|
||||
onFinish: {
|
||||
type: Function as PropType<AnyFC>,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
|
@ -31,8 +31,9 @@ import type { TransitionProps } from './types'
|
||||
|
||||
/**
|
||||
*
|
||||
* 使用宏编译模式时,可以使用 defineOptions 声明组件选项
|
||||
* 常用方法即是声明该组件的 name inheritAttrs 等属性
|
||||
* @description
|
||||
* 使用宏编译模式时,可以使用 defineOptions 声明组件选项。
|
||||
* 常用方法即是声明该组件的 name inheritAttrs 等属性。
|
||||
*/
|
||||
defineOptions({
|
||||
name: 'RTransitionComponent',
|
||||
|
@ -5,6 +5,26 @@ import collapseGridProps from '../../base/RCollapseGrid/src/props'
|
||||
|
||||
import type { GridProps } from 'naive-ui'
|
||||
|
||||
export const collapseProps = Object.assign({}, formProps, {
|
||||
...collapseGridProps,
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
cols: {
|
||||
type: [Number, String] as PropType<GridProps['cols']>,
|
||||
default: '4 xs:1 s:2 m:2 l:4 xl:4 2xl:6',
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
responsive: {
|
||||
type: String as PropType<GridProps['responsive']>,
|
||||
default: 'screen',
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
@ -13,25 +33,7 @@ import type { GridProps } from 'naive-ui'
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'RCollapse',
|
||||
props: Object.assign({}, formProps, {
|
||||
...collapseGridProps,
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
cols: {
|
||||
type: [Number, String] as PropType<GridProps['cols']>,
|
||||
default: '4 xs:1 s:2 m:2 l:4 xl:4 2xl:6',
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
responsive: {
|
||||
type: String as PropType<GridProps['responsive']>,
|
||||
default: 'screen',
|
||||
},
|
||||
}),
|
||||
props: collapseProps,
|
||||
render() {
|
||||
const { $slots, $props } = this
|
||||
const { labelPlacement, showFeedback, ...rest } = $props
|
||||
|
@ -5,6 +5,7 @@ import './app-components/provider/provider.scss' // 初始化 provider 包注入
|
||||
import 'vue3-next-qrcode/es/style.css' // vue3-next-qrcode 样式
|
||||
|
||||
import 'virtual:svg-icons-register' // vite-plugin-svg-icons 脚本,启用 svg 雪碧图
|
||||
import 'virtual:uno.css'
|
||||
|
||||
import { setupRouter } from './router'
|
||||
import { setupStore } from './store'
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
type RecordKey = string | number | symbol
|
||||
export type RecordKey = string | number | symbol
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -10,9 +10,12 @@ import {
|
||||
NRadio,
|
||||
NRadioGroup,
|
||||
NCard,
|
||||
NText,
|
||||
NSwitch,
|
||||
} from 'naive-ui'
|
||||
|
||||
import { useForm } from '@/components'
|
||||
import { useHookPlusRequest } from '@/axios'
|
||||
|
||||
interface FormModel {
|
||||
name: string | null
|
||||
@ -29,12 +32,12 @@ export default defineComponent({
|
||||
const [
|
||||
register,
|
||||
{
|
||||
getFormInstance,
|
||||
validate,
|
||||
restoreValidation,
|
||||
formModel,
|
||||
formRules,
|
||||
reset,
|
||||
validateTargetField,
|
||||
formConditionRef,
|
||||
},
|
||||
] = useForm<FormModel>(
|
||||
{
|
||||
@ -71,101 +74,124 @@ export default defineComponent({
|
||||
},
|
||||
)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 如果只是简单的数据,可以在初始化 useForm 的时候直接传入第一个参数;
|
||||
* 然后使用 formModel 方法获取到初始化 model 数据。
|
||||
*
|
||||
* 当然,在 vue 中,推荐使用该方法进行表单值的初始化操作;
|
||||
* 因为,可以在你需要的时候实现便捷的一键初始化表单需求。
|
||||
*/
|
||||
const condition = ref(formModel())
|
||||
const formLoading = ref(false)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key 需要校验的字段。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/form#partially-apply-rules.vue
|
||||
*
|
||||
* @description
|
||||
* 执行部分的校验规则。
|
||||
*/
|
||||
const onlyValidateSection = (key: string) => {
|
||||
validate(void 0, (rules) => {
|
||||
return rules?.key === key
|
||||
})
|
||||
}
|
||||
const { run: runHookPlusRequest } = useHookPlusRequest(
|
||||
() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
validate()
|
||||
.then(() => {
|
||||
formLoading.value = true
|
||||
|
||||
setTimeout(() => {
|
||||
window.$message.success('校验成功')
|
||||
resolve(true)
|
||||
}, 500)
|
||||
})
|
||||
.catch(reject)
|
||||
.finally(() => {
|
||||
formLoading.value = false
|
||||
})
|
||||
})
|
||||
},
|
||||
{
|
||||
manual: true,
|
||||
},
|
||||
)
|
||||
|
||||
return {
|
||||
register,
|
||||
condition,
|
||||
formConditionRef,
|
||||
restoreValidation,
|
||||
validate,
|
||||
formRules,
|
||||
onlyValidateSection,
|
||||
validateTargetField,
|
||||
reset,
|
||||
formLoading,
|
||||
runHookPlusRequest,
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { condition } = this
|
||||
const { formConditionRef } = this
|
||||
const {
|
||||
register,
|
||||
restoreValidation,
|
||||
validate,
|
||||
formRules,
|
||||
onlyValidateSection,
|
||||
validateTargetField,
|
||||
reset,
|
||||
runHookPlusRequest,
|
||||
} = this
|
||||
|
||||
return (
|
||||
<NCard title="useForm 表单校验">
|
||||
<RForm onRegister={register} rules={formRules()} model={condition}>
|
||||
<NGrid cols={24} xGap={24}>
|
||||
<NFormItemGi label="姓名" path="name" span={12}>
|
||||
<NInput v-model:value={condition.name} />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="年龄" path="age" span={12}>
|
||||
<NInputNumber
|
||||
v-model:value={condition.age}
|
||||
showButton={false}
|
||||
style="width: 100%"
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="出生日期" path="date" span={12}>
|
||||
<NDatePicker v-model:value={condition.date} style="width: 100%" />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="性别" path="gender" span={12}>
|
||||
<NRadioGroup v-model:value={condition.gender}>
|
||||
<NRadio value="girl">女</NRadio>
|
||||
<NRadio value="man">男</NRadio>
|
||||
</NRadioGroup>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="备注信息" span={24}>
|
||||
<NInput type="textarea" v-model:value={condition.remark} />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span={24}>
|
||||
<NFlex justify="flex-end" style="width: 100%">
|
||||
<NButton type="info" onClick={() => reset(this.condition)}>
|
||||
重置表单为初始状态
|
||||
</NButton>
|
||||
<NButton type="warning" onClick={restoreValidation.bind(this)}>
|
||||
移除校验状态
|
||||
</NButton>
|
||||
<NButton
|
||||
type="primary"
|
||||
onClick={() => onlyValidateSection('name')}
|
||||
>
|
||||
仅校验姓名字段
|
||||
</NButton>
|
||||
<NButton type="primary" onClick={() => validate()}>
|
||||
校验
|
||||
</NButton>
|
||||
<NButton attrType="reset">重置</NButton>
|
||||
</NFlex>
|
||||
</NFormItemGi>
|
||||
</NGrid>
|
||||
</RForm>
|
||||
<NCard
|
||||
title={() => (
|
||||
<NFlex align="center">
|
||||
<NText>useForm 表单校验</NText>
|
||||
<NSwitch v-model:value={this.formLoading} />
|
||||
</NFlex>
|
||||
)}
|
||||
>
|
||||
{{
|
||||
default: () => (
|
||||
<RForm
|
||||
onRegister={register}
|
||||
rules={formRules()}
|
||||
model={formConditionRef}
|
||||
submitWhenEnter
|
||||
onFinish={() => {
|
||||
window.$message.success('表单提交成功')
|
||||
}}
|
||||
loading={this.formLoading}
|
||||
>
|
||||
<NGrid cols={24} xGap={24}>
|
||||
<NFormItemGi label="姓名" path="name" span={12}>
|
||||
<NInput v-model:value={formConditionRef.name} />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="年龄" path="age" span={12}>
|
||||
<NInputNumber
|
||||
v-model:value={formConditionRef.age}
|
||||
showButton={false}
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="出生日期" path="date" span={12}>
|
||||
<NDatePicker v-model:value={formConditionRef.date} />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="性别" path="gender" span={12}>
|
||||
<NRadioGroup v-model:value={formConditionRef.gender}>
|
||||
<NRadio value="girl">女</NRadio>
|
||||
<NRadio value="man">男</NRadio>
|
||||
</NRadioGroup>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="备注信息" span={24}>
|
||||
<NInput
|
||||
type="textarea"
|
||||
v-model:value={formConditionRef.remark}
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span={24}>
|
||||
<NFlex>
|
||||
<NButton type="info" onClick={() => reset()}>
|
||||
重置表单为初始状态
|
||||
</NButton>
|
||||
<NButton type="warning" onClick={restoreValidation}>
|
||||
移除校验状态
|
||||
</NButton>
|
||||
<NButton
|
||||
type="primary"
|
||||
onClick={() => validateTargetField('name')}
|
||||
>
|
||||
仅校验姓名字段
|
||||
</NButton>
|
||||
<NButton type="primary" onClick={runHookPlusRequest}>
|
||||
校验
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</NFormItemGi>
|
||||
</NGrid>
|
||||
</RForm>
|
||||
),
|
||||
'header-extra': () => '输入表单的时候,试试按下 Enter 键',
|
||||
}}
|
||||
</NCard>
|
||||
)
|
||||
},
|
||||
|
5
uno.config.ts
Normal file
5
uno.config.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { defineConfig } from 'unocss'
|
||||
|
||||
export default defineConfig({
|
||||
safelist: ['w-full', 'h-full'],
|
||||
})
|
@ -88,6 +88,7 @@
|
||||
"useModel": true,
|
||||
"useTemplateRef": true,
|
||||
"Slot": true,
|
||||
"Slots": true
|
||||
"Slots": true,
|
||||
"NFormItem": true
|
||||
}
|
||||
}
|
||||
|
1
unplugin/auto-imports.d.ts
vendored
1
unplugin/auto-imports.d.ts
vendored
@ -7,6 +7,7 @@
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const NFormItem: typeof import('naive-ui')['NFormItem']
|
||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
|
@ -13,6 +13,7 @@ import viteEslint from 'vite-plugin-eslint'
|
||||
import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
||||
import unpluginViteComponents from 'unplugin-vue-components/vite'
|
||||
import unoCSS from 'unocss/vite'
|
||||
|
||||
import { cdn as viteCDNPlugin } from 'vite-plugin-cdn2'
|
||||
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
|
||||
@ -212,6 +213,7 @@ function baseOptions(mode: string): PluginOption[] {
|
||||
inject: 'body-last',
|
||||
customDomId: '__svg__icons__dom__',
|
||||
}),
|
||||
unoCSS(),
|
||||
]
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user