element-plus/website/docs/jp/form.md
三咲智子 55348b30b6
style: use prettier (#3228)
* style: use prettier

* style: just prettier format, no code changes

* style: eslint fix
object-shorthand, prefer-const

* style: fix no-void

* style: no-console
2021-09-04 19:29:28 +08:00

781 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## フォーム
フォームは `input`, `radio`, `select`, `checkbox` などから構成されています。フォームを使うと、データを収集したり、検証したり、送信したりすることができます。
:::tip
The component has been upgraded with a flex layout to replace the old float layout.
:::
### 基本フォーム
これには、`input`, `select`, `radio`, `checkbox` などのあらゆる種類の入力項目が含まれます。
:::demo 各 `form` コンポーネントには、入力項目のコンテナとなる `form-item` フィールドが必要です。
```html
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="Activity name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker
type="date"
placeholder="Pick a date"
v-model="form.date1"
style="width: 100%;"
></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker
placeholder="Pick a time"
v-model="form.date2"
style="width: 100%;"
></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type"></el-checkbox>
<el-checkbox label="Promotion activities" name="type"></el-checkbox>
<el-checkbox label="Offline activities" name="type"></el-checkbox>
<el-checkbox label="Simple brand exposure" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor"></el-radio>
<el-radio label="Venue"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button>Cancel</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: '',
},
}
},
methods: {
onSubmit() {
console.log('submit!')
},
},
}
</script>
```
:::
:::tip
[W3C](https://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2) は規制しているのは
> <i>フォーム内に 1 つの単一行テキスト入力フィールドしかない場合、ユーザエージェントは、そのフィールドでの Enter をフォームの送信要求として受け入れるべきである。</i>
この動作を防ぐには、`<el-form>` に `@submit.prevent` を追加します。
:::
### インラインフォーム
縦のスペースが限られていて、比較的シンプルな形の場合は、一行にまとめることができます。
:::demo `inline` 属性を `true` に設定すると、フォームがインラインになります。
```html
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="Approved by">
<el-input v-model="formInline.user" placeholder="Approved by"></el-input>
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="formInline.region" placeholder="Activity zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Query</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
formInline: {
user: '',
region: '',
},
}
},
methods: {
onSubmit() {
console.log('submit!')
},
},
}
</script>
```
:::
### アライメント
デザインに応じて、ラベル要素を揃える方法はいくつかあります。
:::demo `label-position` 属性はラベルの配置を決定します。`top`に設定すると、ラベルはフォームフィールドの一番上に配置されます。
```html
<el-radio-group v-model="labelPosition" size="small">
<el-radio-button label="left">Left</el-radio-button>
<el-radio-button label="right">Right</el-radio-button>
<el-radio-button label="top">Top</el-radio-button>
</el-radio-group>
<div style="margin: 20px;"></div>
<el-form
:label-position="labelPosition"
label-width="100px"
:model="formLabelAlign"
>
<el-form-item label="Name">
<el-input v-model="formLabelAlign.name"></el-input>
</el-form-item>
<el-form-item label="Activity zone">
<el-input v-model="formLabelAlign.region"></el-input>
</el-form-item>
<el-form-item label="Activity form">
<el-input v-model="formLabelAlign.type"></el-input>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
labelPosition: 'right',
formLabelAlign: {
name: '',
region: '',
type: '',
},
}
},
}
</script>
```
:::
### バリデーション
フォームコンポーネントを使用すると、データを検証してエラーを発見したり修正したりすることができます。
:::demo `Form` コンポーネントに `rules` 属性を追加して検証ルールを渡し、`Form-Item`に `prop` 属性を検証が必要な特定のキーとして設定するだけです。詳細は [async-validator](https://github.com/yiminghe/async-validator) を参照してください。
```html
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="120px"
class="demo-ruleForm"
>
<el-form-item label="Activity name" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="Activity zone" prop="region">
<el-select v-model="ruleForm.region" placeholder="Activity zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Activity time" required>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker
type="date"
placeholder="Pick a date"
v-model="ruleForm.date1"
style="width: 100%;"
></el-date-picker>
</el-form-item>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker
placeholder="Pick a time"
v-model="ruleForm.date2"
style="width: 100%;"
></el-time-picker>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery" prop="delivery">
<el-switch v-model="ruleForm.delivery"></el-switch>
</el-form-item>
<el-form-item label="Activity type" prop="type">
<el-checkbox-group v-model="ruleForm.type">
<el-checkbox label="Online activities" name="type"></el-checkbox>
<el-checkbox label="Promotion activities" name="type"></el-checkbox>
<el-checkbox label="Offline activities" name="type"></el-checkbox>
<el-checkbox label="Simple brand exposure" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources" prop="resource">
<el-radio-group v-model="ruleForm.resource">
<el-radio label="Sponsorship"></el-radio>
<el-radio label="Venue"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">Create</el-button>
<el-button @click="resetForm('ruleForm')">Reset</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
ruleForm: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: '',
},
rules: {
name: [
{
required: true,
message: 'Please input Activity name',
trigger: 'blur',
},
{
min: 3,
max: 5,
message: 'Length should be 3 to 5',
trigger: 'blur',
},
],
region: [
{
required: true,
message: 'Please select Activity zone',
trigger: 'change',
},
],
date1: [
{
type: 'date',
required: true,
message: 'Please pick a date',
trigger: 'change',
},
],
date2: [
{
type: 'date',
required: true,
message: 'Please pick a time',
trigger: 'change',
},
],
type: [
{
type: 'array',
required: true,
message: 'Please select at least one activity type',
trigger: 'change',
},
],
resource: [
{
required: true,
message: 'Please select activity resource',
trigger: 'change',
},
],
desc: [
{
required: true,
message: 'Please input activity form',
trigger: 'blur',
},
],
},
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
},
}
</script>
```
:::
### カスタムバリデーションルール
この例では、独自の検証ルールをカスタマイズして、2 ファクタのパスワード検証を完了させる方法を示しています。
:::demo ここでは、検証結果をアイコンとして反映させるために `status-icon` を用いる。
```html
<el-form
:model="ruleForm"
status-icon
:rules="rules"
ref="ruleForm"
label-width="120px"
class="demo-ruleForm"
>
<el-form-item label="Password" prop="pass">
<el-input
type="password"
v-model="ruleForm.pass"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="Confirm" prop="checkPass">
<el-input
type="password"
v-model="ruleForm.checkPass"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="Age" prop="age">
<el-input v-model.number="ruleForm.age"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">Submit</el-button>
<el-button @click="resetForm('ruleForm')">Reset</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
var checkAge = (rule, value, callback) => {
if (!value) {
return callback(new Error('Please input the age'))
}
setTimeout(() => {
if (!Number.isInteger(value)) {
callback(new Error('Please input digits'))
} else {
if (value < 18) {
callback(new Error('Age must be greater than 18'))
} else {
callback()
}
}
}, 1000)
}
var validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('Please input the password'))
} else {
if (this.ruleForm.checkPass !== '') {
this.$refs.ruleForm.validateField('checkPass')
}
callback()
}
}
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('Please input the password again'))
} else if (value !== this.ruleForm.pass) {
callback(new Error("Two inputs don't match!"))
} else {
callback()
}
}
return {
ruleForm: {
pass: '',
checkPass: '',
age: '',
},
rules: {
pass: [{ validator: validatePass, trigger: 'blur' }],
checkPass: [{ validator: validatePass2, trigger: 'blur' }],
age: [{ validator: checkAge, trigger: 'blur' }],
},
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
},
}
</script>
```
:::
:::tip
カスタムバリデートコールバック関数を呼び出す必要があります。より高度な使い方は [async-validator](https://github.com/yiminghe/async-validator) を参照してください。
:::
### フォーム項目を動的に削除または追加
:::demo フォームコンポーネントにすべてのバリデーションルールを一度に渡すことに加えて、単一のフォームフィールドにバリデーションルールを動的に渡したり削除したりすることもできます。
```html
<el-form
:model="dynamicValidateForm"
ref="dynamicValidateForm"
label-width="120px"
class="demo-dynamic"
>
<el-form-item
prop="email"
label="Email"
:rules="[
{ required: true, message: 'Please input email address', trigger: 'blur' },
{ type: 'email', message: 'Please input correct email address', trigger: ['blur', 'change'] }
]"
>
<el-input v-model="dynamicValidateForm.email"></el-input>
</el-form-item>
<el-form-item
v-for="(domain, index) in dynamicValidateForm.domains"
:label="'Domain' + index"
:key="domain.key"
:prop="'domains.' + index + '.value'"
:rules="{
required: true, message: 'domain can not be null', trigger: 'blur'
}"
>
<el-input v-model="domain.value"></el-input
><el-button @click.prevent="removeDomain(domain)">Delete</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('dynamicValidateForm')"
>Submit</el-button
>
<el-button @click="addDomain">New domain</el-button>
<el-button @click="resetForm('dynamicValidateForm')">Reset</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
dynamicValidateForm: {
domains: [
{
key: 1,
value: '',
},
],
email: '',
},
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
removeDomain(item) {
var index = this.dynamicValidateForm.domains.indexOf(item)
if (index !== -1) {
this.dynamicValidateForm.domains.splice(index, 1)
}
},
addDomain() {
this.dynamicValidateForm.domains.push({
key: Date.now(),
value: '',
})
},
},
}
</script>
```
:::
### ナンバーの検証(Number Validate)
:::demo Number Validate では、入力された `v-model` バインディングに `.number` という修飾子を追加する必要がありますが、これは文字列の値を Vuejs が提供する数値に変換するために使われます。
```html
<el-form
:model="numberValidateForm"
ref="numberValidateForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item
label="age"
prop="age"
:rules="[
{ required: true, message: 'age is required'},
{ type: 'number', message: 'age must be a number'}
]"
>
<el-input
type="age"
v-model.number="numberValidateForm.age"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('numberValidateForm')"
>Submit</el-button
>
<el-button @click="resetForm('numberValidateForm')">Reset</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
numberValidateForm: {
age: '',
},
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
},
}
</script>
```
:::
:::tip
`el-form-item` が別の `el-form-item` に入れ子になっている場合、そのラベルの幅は `0` になります。必要であれば、その `el-form-item``label-width` を設定することもできる。
:::
### サイズコントロール
フォームのすべてのコンポーネントはそのフォームから `size` 属性を継承します。同様に、FormItem にも `size` 属性があります。
:::demo それでも、コンポーネントのサイズを From や FormIten から継承させたくない場合は、各コンポーネントの `size` を微調整することができます。
```html
<el-form ref="form" :model="sizeForm" label-width="120px" size="mini">
<el-form-item label="Activity name">
<el-input v-model="sizeForm.name"></el-input>
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="sizeForm.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker
type="date"
placeholder="Pick a date"
v-model="sizeForm.date1"
style="width: 100%;"
></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker
placeholder="Pick a time"
v-model="sizeForm.date2"
style="width: 100%;"
></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="sizeForm.type">
<el-checkbox-button
label="Online activities"
name="type"
></el-checkbox-button>
<el-checkbox-button
label="Promotion activities"
name="type"
></el-checkbox-button>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="sizeForm.resource" size="medium">
<el-radio border label="Sponsor"></el-radio>
<el-radio border label="Venue"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item size="large">
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button>Cancel</el-button>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
sizeForm: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: '',
},
}
},
methods: {
onSubmit() {
console.log('submit!')
},
},
}
</script>
```
:::
### フォーム属性
| Attribute | Description | Type | Accepted Values | Default |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | --------------------- | ------- |
| model | フォームコンポーネントのデータ | object | — | — |
| rules | フォームのバリデーションルール | object | — | — |
| inline | フォームがインラインであるかどうか | boolean | — | false |
| label-position | ラベルの位置。left'、right もしくは`label-width`が設定されている場合は prop も必要です。 | string | left / right / top | right |
| label-width | ラベルの幅、例えば '50px'。直接の子フォーム項目はすべてこの値を継承します。Width `auto` がサポートされています。 | string / number | — | — |
| label-suffix | ラベルの接尾辞 | string | — | — |
| hide-required-asterisk | 必須フィールドのラベルの横に赤いアスタリスク(星)を付けるかどうか | boolean | — | false |
| show-message | エラーメッセージを表示するかどうか | boolean | — | true |
| inline-message | エラーメッセージをフォーム項目とインラインで表示するかどうか。 | boolean | — | false |
| status-icon | バリデーション結果を示すアイコンを表示するかどうか | boolean | — | false |
| validate-on-rule-change | `rules` prop が変更されたときにバリデーションをトリガするかどうか。 | boolean | — | true |
| size | コンポーネントのサイズを制御する形式 | string | medium / small / mini | — |
| disabled | このフォームのすべてのコンポーネントを無効にするかどうかを指定します。true に設定されている場合、内部のコンポーネントの `disabled` プロップで上書きすることはできません。 | boolean | — | false |
### フォームメソッド
| Method | Description | Parameters |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| validate | バリデートはフォーム全体を検証します。パラメータとしてコールバックを受け取ります。バリデーションが通過したかどうかを示すブール値と、バリデーションに失敗したすべてのフィールドを含むオブジェクトです。コールバックが省略された場合は promise を返します。 | Function(callback: Function(boolean, object)) |
| validateField | フォーム項目を検証する | Function(props: string \| array, callback: Function(errorMessage: string)) |
| resetFields | すべてのフィールドをリセットし、検証結果を削除します。 | — |
| scrollToField | 指定されたフォームフィールドまでスクロールします | Function(prop: string) |
| clearValidate | 特定のフィールドのバリデーションメッセージをクリアします。パラメータは prop 名、または検証メッセージが削除されるフォーム項目の prop 名の配列です。省略された場合、すべてのフィールドのバリデーションメッセージがクリアされます。 | Function(props: string \| array) |
### フォームイベント
| Event Name | Description | Parameters |
| ---------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| validate | フォーム項目バリデーション後にトリガされます。 | prop name of the form item being validated, whether validation is passed and the error message if not |
### フォームアイテム属性
| Attribute | Description | Type | Accepted Values | Default |
| -------------- | ------------------------------------------------------------------------------------------------------------ | --------------- | ----------------------------------- | ------- |
| prop | `model` のキーです。validate メソッドと resetFields メソッドを利用する際には、この属性が必須です。 | string | keys of model that passed to `form` |
| label | ラベル | string | — | — |
| label-width | ラベルの幅。Width `auto` がサポートされています。 | string / number | — | — |
| required | フィールドが必須かどうか、省略された場合はバリデーションルールによって決定されます。 | boolean | — | false |
| rules | フォームのバリデーションルール | object / array | — | — |
| error | フィールドのエラーメッセージ、値を設定すると、フィールドはエラーを検証し、このメッセージをすぐに表示します。 | string | — | — |
| show-message | エラーメッセージを表示するかどうか | boolean | — | true |
| inline-message | インラインスタイルバリデートメッセージ | boolean | — | false |
| size | フォームアイテムのコンポーネントのサイズを制御します。 | string | medium / small / mini | — |
### Rules
| Attribute | Description | Type | Accepted Values | Default |
| --------- | ------------------------------ | ------ | --------------- | ------- |
| trigger | how the validator is triggered | string | blur / change | — |
### フォームアイテムスロット
| Name | Description |
| ----- | ------------------------------------------------------------------------------ |
| — | フォームアイテムの内容 |
| label | Custom content to display on label. The scope parameter is { label } |
| error | Custom content to display validation message. The scope parameter is { error } |
### フォームアイテムのメソッド
| Method | Description | Parameters |
| ------------- | ---------------------------------------------------------- | ---------- |
| resetField | 現在のフィールドをリセットしてバリデーション結果を削除する | — |
| clearValidate | フィールドのバリデーションステータスを削除する | — |