doc(form): zh-cn

This commit is contained in:
07akioni 2020-02-05 12:14:05 +08:00
parent fd1073a55e
commit 833fc5c2ed
14 changed files with 823 additions and 35 deletions

View File

@ -1,4 +1,5 @@
# Custom Rules
You can custom you valiation by setting custom trigger in rules.
```html
<n-form :model="model" ref="form" :rules="rules">
<n-form-item-row path="age" label="Age">
@ -8,6 +9,7 @@
<n-input v-model="model.password" @input="handlePasswordInput" type="password"/>
</n-form-item-row>
<n-form-item-row
first
path="reenteredPassword"
label="Re-enter Password"
ref="reenteredPassword"
@ -54,6 +56,11 @@ export default {
}
],
reenteredPassword: [
{
required: true,
message: 'Re-entered Password is required',
trigger: ['input', 'blur']
},
{
validator: this.validatePasswordStartWith,
message: 'Password is not same as re-entered password!',
@ -63,11 +70,6 @@ export default {
validator: this.validatePasswordSame,
message: 'Password is not same as re-entered password!',
trigger: ['blur', 'password-input']
},
{
required: true,
message: 'Re-entered Password is required',
trigger: ['input', 'blur']
}
]
}

View File

@ -1,10 +1,79 @@
# Form
<!--single-column-->
Collect & validate data.
## Demos
```demo
inline
custom-rule
debug
top
left
change-debug
required-mark-debug
```
```
## Props
### Form Props
|Name|Type|Default|Description|
|-|-|-|-|
|inline|`boolean`|`false`||
|label-width|`number`|`null`|The width of label. Can be useful when `label-placement` is `'left'`.|
|label-align|`'left' \| 'right'`|`'left'`|Text align in label.|
|label-placement|`'left' \| 'top'`|`'top'`||
|model|`object`||The object to get collected value from form items. **required**|
|rules|`type FormRules = { [itemValidatePath: string]: FormItemRule \| Array<FormItemRule> \| FormRules }`|`{}`|The rules to validate form items.|
|show-require-mark|`boolean`|`true`|Whether to show require mark when form item is required.|
#### FormItemRule Type
|Property|Type|Description|
|-|-|-|
|required|`boolean`||
|validator|`(rule: FormItemRule, value: any) => boolean \| Error`||
|trigger|`string \| Array<string>`||
|message|`string`||
### Form Item Props
|Name|Type|Default|Description|
|-|-|-|-|
|label|`string`|`null`||
|label-width|`number`|`null`|If not set, use label-align from wrapper form.|
|label-style|`object`|`{}`||
|label-align|`'left' \| 'right'`|`null`|Text align in label. If not set, use label-align from wrapper form.|
|label-placement|`'left' \| 'top'`|`null`|If not set, use label-placement from wrapper form.|
|path|`string`|`null`|The path to collect item value to wrapper form's model object.|
|rule-path|`string`|`null`|The path to get rule from wrapper form's rule object. If not set, use path of the form item instead.|
|required|`boolean`|`false`|Whether to show required mark. Note: a required rule has higher priority than this props & this prop **won't** change the validation process. The validation still depends on the rules.|
|show-require-mark|`boolean`|`true`|Whether to show require mark when form item is required. If not set, use show-require-mark from wrapper form.|
|rule|`FormItemRule \| Array<FormItemRule>`|`null`|The rule to validate the form item. It will be merged with the rules acquired by rule-path from wrapper form's rules. It's recommend to set all rules on wrapper form.|
|first|`boolean`|`false`|Whether only to show the first validation error message.|
### Form Item Row Props
Accept all props from form-item & [Row](n-row#Row-Props)
### Form Item Col Props
Accept all props from form-item & [Col](n-row#Col-Props)
## Methods
### Form Methods
<n-alert type="warning" title="Caveat on Validate Method" style="margin-bottom: 16px;">
<n-ol align-text>
<n-li>Validation will only be executed on form items which have a `path`</n-li>
<n-li>Validation will use the path to get collected value from form `model`, then use `path` or `rule-path`(if specified) to get validation rules</n-li>
<n-li>Validation will use all rules regardless of the triggers of form items.</n-li>
</n-ol>
</n-alert>
|Name|Type|Description|
|-|-|-|
|validate|`(validateCallback?: (errors?: Array<ValidationError>) => any) => Promise<void>`|Validate the form.The rejection value type of returned promise is `Array<ValidationError>`.|
|clearValidationEffect|`() => void`||
### Form Item, Form Item Row, Form Item Col Methods
|Name|Type|Description|
|-|-|-|
|validate|`(trigger?: string, validateCallback?: (errors?: Array<ValidationError>) => any, options?: AsyncValidatorOptions) => Promise<void>`|Validate the form item. The rejection value type of returned promise is `Array<ValidationError>`. If trigger is not passed, all rules of the item will be applied.|
|clearValidationEffect|`() => void`||
About AsyncValidatorOptions, see [async-validator](https://github.com/yiminghe/async-validator).
## Slots
### Form, Form Item, Form Item Row, Form Item Col Methods
|Name|Parameters|Description|
|-|-|-|
|default|`()`||

View File

@ -1,4 +1,5 @@
# Inline Form
A Example of inline form.
```html
<n-form
inline

View File

@ -1,4 +1,4 @@
# Horiziontal
# Label Placement Left
```html
<n-form
:model="model"

View File

@ -0,0 +1,110 @@
# 自定义规则
你可以通过设定自定的 trigger 来控制验证。
```html
<n-form :model="model" ref="form" :rules="rules">
<n-form-item-row path="age" label="Age">
<n-input v-model="model.age"/>
</n-form-item-row>
<n-form-item-row path="password" label="Password">
<n-input v-model="model.password" @input="handlePasswordInput" type="password"/>
</n-form-item-row>
<n-form-item-row
first
path="reenteredPassword"
label="Re-enter Password"
ref="reenteredPassword"
>
<n-input :disabled="!model.password" v-model="model.reenteredPassword" type="password"/>
</n-form-item-row>
<n-row :gutter="[0, 24]">
<n-col :span="24">
<div style="display: flex; justify-content: flex-end;">
<n-button @click="handleValidateButtonClick" round type="primary">Validate</n-button>
</div>
</n-col>
</n-row>
</n-form>
<pre>
{{ JSON.stringify(model, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
model: {
age: null,
password: null,
reenteredPassword: null
},
rules: {
age: [
{
required: true,
validator (rule, value) {
if (!value) {
return new Error('Age is required')
} else if (!/^\d*$/.test(value)) {
return new Error('Age should be an integer')
} else if (Number(value) < 18) {
return new Error('Age should be above 18')
}
return true
},
trigger: ['input', 'blur']
}
],
reenteredPassword: [
{
required: true,
message: 'Re-entered Password is required',
trigger: ['input', 'blur']
},
{
validator: this.validatePasswordStartWith,
message: 'Password is not same as re-entered password!',
trigger: 'input'
},
{
validator: this.validatePasswordSame,
message: 'Password is not same as re-entered password!',
trigger: ['blur', 'password-input']
}
]
}
}
},
methods: {
handlePasswordInput () {
if (this.model.reenteredPassword) {
this.$refs.reenteredPassword.validate('password-input', (errors => {
if (!errors) {
this.$NMessage.success('Valid')
} else {
console.log(errors)
this.$NMessage.error('Invalid')
}
}))
}
},
handleValidateButtonClick (e) {
e.preventDefault()
this.$refs.form.validate(errors => {
if (!errors) {
this.$NMessage.success('Valid')
} else {
console.log(errors)
this.$NMessage.error('Invalid')
}
})
},
validatePasswordStartWith (rule, value) {
return this.model.password && this.model.password.startsWith(value) && this.model.password.length >= value.length
},
validatePasswordSame (rule, value) {
return value === this.model.password
}
}
}
```

View File

@ -0,0 +1,79 @@
# 表单 Form
<!--single-column-->
收集、验证信息
## 演示
```demo
inline
custom-rule
top
left
```
## Props
### Form Props
|名称|类型|默认值|介绍|
|-|-|-|-|
|inline|`boolean`|`false`||
|label-width|`number`|`null`|标签的宽度,在 `label-placement``'left'` 的时候可能会有用|
|label-align|`'left' \| 'right'`|`'left'`|标签的文本对齐方式|
|label-placement|`'left' \| 'top'`|`'top'`||
|model|`object`||获取表项中收集到的值的对象|
|rules|`type FormRules = { [itemValidatePath: string]: FormItemRule \| Array<FormItemRule> \| FormRules }`|`{}`|验证表项的规则|
|show-require-mark|`boolean`|`true`|在表项是必填的时候是不是展示星号|
#### FormItemRule Type
|属性|类型|介绍|
|-|-|-|
|required|`boolean`||
|validator|`(rule: FormItemRule, value: any) => boolean \| Error`||
|trigger|`string \| Array<string>`||
|message|`string`||
### Form Item Props
|名称|类型|默认值|介绍|
|-|-|-|-|
|label|`string`|`null`||
|label-width|`number`|`null`|如果没有被设定,使用外层表单的 label-align|
|label-style|`object`|`{}`||
|label-align|`'left' \| 'right'`|`null`|标签的文本对齐方式。如果没有被设定,使用外层表单的 label-align|
|label-placement|`'left' \| 'top'`|`null`|如果没有被设定,使用外层表单的 label-placement|
|path|`string`|`null`|将值收集到外层表单 `model` 对象的路径|
|rule-path|`string`|`null`|从外层表单的 `rules` 对象获取规则的路径。如果没有设定,使用表项的 `path` 代替。|
|required|`boolean`|`false`|是否展示必填的星号。注意:一个 required 的规则比这个属性有更高的优先级 & 这个属性不会影响表单的验证。验证完全依赖于规则。|
|show-require-mark|`boolean`|`true`|在表项是必填的时候是不是展示星号。如果没有被设定,使用外层表单的 show-require-mark|
|rule|`FormItemRule \| Array<FormItemRule>`|`null`|验证表项的规则,它会被通过 `rule-path` 从外层表单获取的规则合并来作为表项的验证规则。推荐还是在外层表单设置所有规则。|
|first|`boolean`|`false`|是否只展示首个出错信息。|
### Form Item Row Props
接受 Form Item & [Row](n-row#Row-Props) 所有的 Props。
### Form Item Col Props
接受 Form Item & [Col](n-row#Col-Props) 所有的 Props。
## Methods
### Form Methods
<n-alert type="warning" title="Validate 方法的注意事项" style="margin-bottom: 16px;">
<n-ol align-text>
<n-li>验证只会在有 `path` 属性的表项上执行</n-li>
<n-li>验证会使用 `path``model` 获取收集到的值,使用 `path` 或者 `rule-path`(如果声明了)去获取验证规则</n-li>
<n-li>验证将会在合法表项的所有规则上进行,不管规则的 trigger 是什么</n-li>
</n-ol>
</n-alert>
|名称|类型|介绍|
|-|-|-|
|validate|`(validateCallback?: (errors?: Array<ValidationError>) => any) => Promise<void>`|验证表单。Promise rejection 的返回值类型是 `Array<ValidationError>`。|
|clearValidationEffect|`() => void`||
### Form Item, Form Item Row, Form Item Col Methods
|名称|类型|介绍|
|-|-|-|
|validate|`(trigger?: string, validateCallback?: (errors?: Array<ValidationError>) => any, options?: AsyncValidatorOptions) => Promise<void>`|验证表项Promise rejection 的返回值类型是 `Array<ValidationError>`。如果不传 trigger这一个表项全部的 Rules 都会被使用。|
|clearValidationEffect|`() => void`||
关于 AsyncValidatorOptions参考 [async-validator](https://github.com/yiminghe/async-validator)。
## Slots
### Form, Form Item, Form Item Row, Form Item Col Methods
|名称|参数|介绍|
|-|-|-|
|default|`()`||

View File

@ -0,0 +1,75 @@
# 行内表单
一个行内表单的例子。
```html
<n-form
inline
:label-width="80"
:model="formValue"
:rules="rules"
ref="form"
>
<n-form-item label="Name" path="user.name">
<n-input v-model="formValue.user.name" placeholder="Input Name" />
</n-form-item>
<n-form-item label="Age" path="user.age">
<n-input placeholder="Input Age" v-model="formValue.user.age"/>
</n-form-item>
<n-form-item label="Phone" path="phone">
<n-input placeholder="Phone Number" v-model="formValue.phone"/>
</n-form-item>
<n-form-item v-model="formValue.phone">
<n-button @click="handleValidateClick">Validate</n-button>
</n-form-item>
</n-form>
<pre>
{{ JSON.stringify(formValue, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
formValue: {
user: {
name: '',
age: ''
},
phone: ''
},
rules: {
user: {
name: {
required: true,
message: 'Please input your name',
trigger: 'blur'
},
age: {
required: true,
message: 'Please input your age',
trigger: ['input', 'blur']
}
},
phone: {
required: true,
message: 'Please input your number',
trigger: ['input']
}
}
}
},
methods: {
handleValidateClick (e) {
e.preventDefault()
this.$refs.form.validate(errors => {
if (!errors) {
this.$NMessage.success('Valid')
} else {
console.log(errors)
this.$NMessage.error('Invalid')
}
})
}
}
}
```

View File

@ -0,0 +1,221 @@
# 标签左置
```html
<n-form
:model="model"
:rules="rules"
ref="form"
label-placement="left"
label-align="right"
:label-width="160"
:style="{
maxWidth: '640px'
}"
>
<n-form-item-row label="Input" path="inputValue">
<n-input placeholder="Input" v-model="model.inputValue" />
</n-form-item-row>
<n-form-item-row label="Textarea" path="textareaValue">
<n-input placeholder="Textarea" v-model="model.textareaValue" type="textarea"
:autosize="{
minRows: 3,
maxRows: 5
}"
/>
</n-form-item-row>
<n-form-item-row label="Select" path="selectValue">
<n-select placeholder="Select" :options="generalOptions" v-model="model.selectValue"/>
</n-form-item-row>
<n-form-item-row label="Multiple Select" path="multipleSelectValue">
<n-select placeholder="Select" :options="generalOptions" v-model="model.multipleSelectValue" multiple/>
</n-form-item-row>
<n-form-item-row label="Datetime" path="datetimeValue">
<n-date-picker type="datetime" v-model="model.datetimeValue"/>
</n-form-item-row>
<n-form-item-row label="Switch" path="switchValue">
<n-switch v-model="model.switchValue" />
</n-form-item-row>
<n-form-item-row label="Checkbox Group" path="checkboxGroupValue">
<n-checkbox-group v-model="model.checkboxGroupValue">
<n-checkbox value="Option 1">Option 1</n-checkbox>
<n-checkbox value="Option 2">Option 2</n-checkbox>
<n-checkbox value="Option 3">Option 3</n-checkbox>
</n-checkbox-group>
</n-form-item-row>
<n-form-item-row label="Radio Group" path="radioGroupValue">
<n-radio-group v-model="model.radioGroupValue">
<n-radio value="Radio 1">Radio 1</n-radio>
<n-radio value="Radio 2">Radio 2</n-radio>
<n-radio value="Radio 3">Radio 3</n-radio>
</n-radio-group>
</n-form-item-row>
<n-form-item-row label="Radio Button Group" path="radioGroupValue">
<n-radio-group v-model="model.radioGroupValue">
<n-radio-button value="Radio 1">Radio 1</n-radio-button>
<n-radio-button value="Radio 2">Radio 2</n-radio-button>
<n-radio-button value="Radio 3">Radio 3</n-radio-button>
</n-radio-group>
</n-form-item-row>
<n-form-item-row label="Input Number" path="inputNumberValue">
<n-input-number v-model="model.inputNumberValue"/>
</n-form-item-row>
<n-form-item-row label="Time Picker" path="timePickerValue">
<n-time-picker v-model="model.timePickerValue" />
</n-form-item-row>
<n-form-item-row label="Slider" path="sliderValue">
<n-slider v-model="model.sliderValue" :step="5"/>
</n-form-item-row>
<n-form-item-row label="Transfer" path="transferValue">
<n-transfer
v-model="model.transferValue"
:options="generalOptions"
/>
</n-form-item-row>
<n-form-item-row :gutter="[28, 0]" label="Nested Path">
<n-row :gutter="[28, 0]" >
<n-form-item-col :span="12" path="nestedValue.path1">
<n-input placeholder="Nested Path 1" v-model="model.nestedValue.path1"/>
</n-form-item-col>
<n-form-item-col :span="12" path="nestedValue.path2">
<n-select placeholder="Nested Path 2" :options="generalOptions" v-model="model.nestedValue.path2"/>
</n-form-item-col>
</n-row>
</n-form-item-row>
<n-row>
<n-col :span="24">
<div style="display: flex; justify-content: flex-end;">
<n-button @click="handleValidateButtonClick" round type="primary">Validate</n-button>
</div>
</n-col>
</n-row>
</n-form>
<pre>
{{ JSON.stringify(model, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
model: {
inputValue: null,
textareaValue: null,
selectValue: null,
multipleSelectValue: null,
datetimeValue: null,
nestedValue: {
path1: null,
path2: null
},
switchValue: false,
checkboxGroupValue: null,
radioGroupValue: null,
radioButtonGroupValue: null,
inputNumberValue: null,
timePickerValue: null,
sliderValue: 0,
transferValue: null
},
generalOptions: [
'groode',
'veli good',
'emazing',
'lidiculous'
].map(v => ({
label: v,
value: v
})),
rules: {
inputValue: {
required: true,
trigger: ['blur', 'input'],
message: 'Please input inputValue'
},
textareaValue: {
required: true,
trigger: ['blur', 'input'],
message: 'Please input textareaValue'
},
selectValue: {
required: true,
trigger: ['blur', 'change'],
message: 'Please select selectValue'
},
multipleSelectValue: {
type: 'array',
required: true,
trigger: ['blur', 'change'],
message: 'Please select multipleSelectValue'
},
datetimeValue: {
type: 'number',
required: true,
trigger: ['blur', 'change'],
message: 'Please input datetimeValue'
},
nestedValue: {
path1: {
required: true,
trigger: ['blur', 'input'],
message: 'Please input nestedValue.path1'
},
path2: {
required: true,
trigger: ['blur', 'change'],
message: 'Please input nestedValue.path2'
}
},
checkboxGroupValue: {
type: 'array',
required: true,
trigger: 'change',
message: 'Please select checkboxGroupValue'
},
radioGroupValue: {
required: true,
trigger: 'change',
message: 'Please select radioGroupValue'
},
radioButtonGroupValue: {
required: true,
trigger: 'change',
message: 'Please select radioButtonGroupValue'
},
inputNumberValue: {
type: 'number',
required: true,
trigger: ['blur', 'change'],
message: 'Please input inputNumberValue'
},
timePickerValue: {
type: 'number',
required: true,
trigger: ['blur', 'change'],
message: 'Please input timePickerValue'
},
sliderValue: 0,
transferValue: {
type: 'array',
required: true,
trigger: 'change',
message: 'Please input transferValue'
}
}
}
},
methods: {
handleValidateButtonClick (e) {
e.preventDefault()
this.$refs.form.validate(errors => {
if (!errors) {
this.$NMessage.success('Valid')
} else {
console.log(errors)
this.$NMessage.error('Invalid')
}
})
}
}
}
```

View File

@ -0,0 +1,226 @@
# 标签上置
```html
<n-form
:model="model"
:rules="rules"
ref="form"
label-placement="top"
>
<n-row :gutter="24">
<n-form-item-col :span="12" label="Input" path="inputValue">
<n-input placeholder="Input" v-model="model.inputValue" />
</n-form-item-col :span="12">
<n-form-item-col :span="12" label="Textarea" path="textareaValue">
<n-input placeholder="Textarea" v-model="model.textareaValue" type="textarea"
:autosize="{
minRows: 3,
maxRows: 5
}"
/>
</n-form-item-col>
</n-row>
<n-row :gutter="24">
<n-form-item-col :span="12" label="Select" path="selectValue">
<n-select placeholder="Select" :options="generalOptions" v-model="model.selectValue"/>
</n-form-item-col>
<n-form-item-col :span="12" label="Multiple Select" path="multipleSelectValue">
<n-select placeholder="Select" :options="generalOptions" v-model="model.multipleSelectValue" multiple/>
</n-form-item-col>
</n-row>
<n-row :gutter="24">
<n-form-item-col :span="12" label="Datetime" path="datetimeValue">
<n-date-picker type="datetime" v-model="model.datetimeValue"/>
</n-form-item-col>
<n-form-item-col :span="12" label="Switch" path="switchValue">
<n-switch v-model="model.switchValue" />
</n-form-item-col>
</n-row>
<n-row :gutter="24">
<n-form-item-col :span="12" label="Checkbox Group" path="checkboxGroupValue">
<n-checkbox-group v-model="model.checkboxGroupValue">
<n-checkbox value="Option 1">Option 1</n-checkbox>
<n-checkbox value="Option 2">Option 2</n-checkbox>
<n-checkbox value="Option 3">Option 3</n-checkbox>
</n-checkbox-group>
</n-form-item-col>
<n-form-item-col :span="12" label="Radio Group" path="radioGroupValue">
<n-radio-group v-model="model.radioGroupValue">
<n-radio value="Radio 1">Radio 1</n-radio>
<n-radio value="Radio 2">Radio 2</n-radio>
<n-radio value="Radio 3">Radio 3</n-radio>
</n-radio-group>
</n-form-item-col>
</n-row>
<n-row :gutter="24">
<n-form-item-col :span="12" label="Radio Button Group" path="radioGroupValue">
<n-radio-group v-model="model.radioGroupValue">
<n-radio-button value="Radio 1">Radio 1</n-radio-button>
<n-radio-button value="Radio 2">Radio 2</n-radio-button>
<n-radio-button value="Radio 3">Radio 3</n-radio-button>
</n-radio-group>
</n-form-item-col>
<n-form-item-col :span="12" label="Input Number" path="inputNumberValue">
<n-input-number v-model="model.inputNumberValue"/>
</n-form-item-col>
</n-row>
<n-row :gutter="24">
<n-form-item-col :span="12" label="Time Picker" path="timePickerValue">
<n-time-picker v-model="model.timePickerValue" />
</n-form-item-col>
<n-form-item-col :span="12" label="Slider" path="sliderValue">
<n-slider v-model="model.sliderValue" :step="5"/>
</n-form-item-col>
</n-row>
<n-row :gutter="24">
<n-form-item-col :span="14" label="Transfer" path="transferValue">
<n-transfer
v-model="model.transferValue"
:options="generalOptions"
/>
</n-form-item-col>
<n-form-item-col :span="5" label="Nested Path" path="nestedValue.path1">
<n-input placeholder="Nested Path 1" v-model="model.nestedValue.path1"/>
</n-form-item-col>
<n-form-item-col :span="5" path="nestedValue.path2">
<n-select placeholder="Nested Path 2" :options="generalOptions" v-model="model.nestedValue.path2"/>
</n-form-item-col>
</n-row>
<n-row>
<n-col :span="24">
<div style="display: flex; justify-content: flex-end;">
<n-button @click="handleValidateButtonClick" round type="primary">Validate</n-button>
</div>
</n-col>
</n-row>
</n-form>
<pre>
{{ JSON.stringify(model, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
model: {
inputValue: null,
textareaValue: null,
selectValue: null,
multipleSelectValue: null,
datetimeValue: null,
nestedValue: {
path1: null,
path2: null
},
switchValue: false,
checkboxGroupValue: null,
radioGroupValue: null,
radioButtonGroupValue: null,
inputNumberValue: null,
timePickerValue: null,
sliderValue: 0,
transferValue: null
},
generalOptions: [
'groode',
'veli good',
'emazing',
'lidiculous'
].map(v => ({
label: v,
value: v
})),
rules: {
inputValue: {
required: true,
trigger: ['blur', 'input'],
message: 'Please input inputValue'
},
textareaValue: {
required: true,
trigger: ['blur', 'input'],
message: 'Please input textareaValue'
},
selectValue: {
required: true,
trigger: ['blur', 'change'],
message: 'Please select selectValue'
},
multipleSelectValue: {
type: 'array',
required: true,
trigger: ['blur', 'change'],
message: 'Please select multipleSelectValue'
},
datetimeValue: {
type: 'number',
required: true,
trigger: ['blur', 'change'],
message: 'Please input datetimeValue'
},
nestedValue: {
path1: {
required: true,
trigger: ['blur', 'input'],
message: 'Please input nestedValue.path1'
},
path2: {
required: true,
trigger: ['blur', 'change'],
message: 'Please input nestedValue.path2'
}
},
checkboxGroupValue: {
type: 'array',
required: true,
trigger: 'change',
message: 'Please select checkboxGroupValue'
},
radioGroupValue: {
required: true,
trigger: 'change',
message: 'Please select radioGroupValue'
},
radioButtonGroupValue: {
required: true,
trigger: 'change',
message: 'Please select radioButtonGroupValue'
},
inputNumberValue: {
type: 'number',
required: true,
trigger: ['blur', 'change'],
message: 'Please input inputNumberValue'
},
timePickerValue: {
type: 'number',
required: true,
trigger: ['blur', 'change'],
message: 'Please input timePickerValue'
},
sliderValue: 0,
transferValue: {
type: 'array',
required: true,
trigger: 'change',
message: 'Please input transferValue'
}
}
}
},
methods: {
handleValidateButtonClick (e) {
e.preventDefault()
this.$refs.form.validate(errors => {
if (!errors) {
this.$NMessage.success('Valid')
} else {
console.log(errors)
this.$NMessage.error('Invalid')
}
})
}
}
}
```

View File

@ -38,9 +38,7 @@ export default {
},
model: {
type: Object,
default: function () {
return {}
}
required: true
},
rules: {
type: Object,
@ -55,7 +53,6 @@ export default {
},
data () {
return {
initialValue: null,
items: {}
}
},
@ -63,14 +60,6 @@ export default {
this.initialValue = cloneDeep(this.model)
},
methods: {
/**
* form validation, validate all prop-elements by default,
* can use specify the scope of validation by param part.
*
* @param {Funtion} callback callback
* @param {Array} scope to specify the scope of validation
* @return {Boolean} validation passed or not
*/
validate (afterValidate, shouldFieldBeValidated = () => true) {
return new Promise((resolve, reject) => {
const formItemValidationPromises = []
@ -101,14 +90,14 @@ export default {
})
})
},
resetForm (target = this) {
for (const key of Object.keys(this.items)) {
const formItemInstances = this.items[key]
clearValidationEffect () {
const formItems = this.items
for (const key of Object.keys(formItems)) {
const formItemInstances = formItems[key]
for (const formItemInstance of formItemInstances) {
formItemInstance.cleanValidationEffect()
formItemInstance.clearValidationEffect()
}
}
this.value = this.initialValue
},
handleKeyDownEnter (e) {
if (e.target.tagName === 'INPUT' && e.target.getAttribute('type')) {

View File

@ -4,7 +4,7 @@
:class="{
[`n-form-item--${synthesizedLabelPlacement}-labelled`]: synthesizedLabelPlacement,
[`n-form-item--${synthesizedLabelAlign}-label-aligned`]: synthesizedLabelAlign,
[`n-form-item--required`]: synthesizedRequired && showRequireMark,
[`n-form-item--required`]: synthesizedRequired && synthesizedShowRequireMark,
[`n-form-item--no-label`]: !(label || $slots.label),
[`n-form-item--has-feedback`]: hasFeedback,
[`n-${synthesizedTheme}-theme`]: synthesizedTheme
@ -71,8 +71,8 @@ export default {
default: null
},
labelStyle: {
type: String,
default: null
type: Object,
default: () => {}
},
labelAlign: {
type: String,
@ -100,7 +100,7 @@ export default {
},
showRequireMark: {
type: Boolean,
default: true
default: null
},
rule: {
type: [Object, Array],
@ -133,6 +133,12 @@ export default {
}
}
},
synthesizedShowRequireMark () {
if (this.showRequireMark === null) {
return this.NForm.showRequireMark
}
return this.showRequireMark
},
synthesizedLabelStyle () {
return {
...this.labelWidthStyle,
@ -277,8 +283,8 @@ export default {
}
if (!options) {
options = {}
options.first = this.first
options.supressWarning = this.supressWarning
} else {
if (!options.first) options.first = this.first
}
const rules = this.synthesizedRules
const path = this.path
@ -320,7 +326,7 @@ export default {
errors
})
} else {
this.cleanValidationEffect()
this.clearValidationEffect()
resolve({
valid: true
})
@ -328,7 +334,7 @@ export default {
})
})
},
cleanValidationEffect () {
clearValidationEffect () {
this.explains = []
this.validated = false
},

View File

@ -13,6 +13,11 @@ export default {
if (this.$refs.formItem) {
return this.$refs.formItem.validate(...args)
}
},
clearValidationEffect (...args) {
if (this.$refs.formItem) {
return this.$refs.formItem.clearValidationEffect(...args)
}
}
},
render (h) {

View File

@ -14,6 +14,11 @@ export default {
if (this.$refs.formItemCol) {
return this.$refs.formItemCol.validate(...args)
}
},
clearValidationEffect (...args) {
if (this.$refs.formItem) {
return this.$refs.formItem.clearValidationEffect(...args)
}
}
},
render (h) {