2018-05-06 10:32:40 +00:00
|
|
|
|
<cn>
|
|
|
|
|
#### 自定义表单控件
|
|
|
|
|
自定义或第三方的表单控件,也可以与 Form 组件一起使用。只要该组件遵循以下的约定:
|
2019-02-16 08:51:21 +00:00
|
|
|
|
> * 提供受控属性 `value` 或其它与 [`valuePropName`](/components/form-cn/#getFieldDecorator(id,-options)-参数) 的值同名的属性。
|
|
|
|
|
> * 提供 `onChange` 事件或 [`trigger`](/components/form-cn/#getFieldDecorator(id,-options)-参数) 的值同名的事件。
|
2018-05-06 10:32:40 +00:00
|
|
|
|
> * 不能是函数式组件。
|
|
|
|
|
</cn>
|
|
|
|
|
|
|
|
|
|
<us>
|
|
|
|
|
#### Customized Form Controls
|
|
|
|
|
Customized or third-party form controls can be used in Form, too. Controls must follow these conventions:
|
2019-02-16 08:51:21 +00:00
|
|
|
|
> * It has a controlled property `value` or other name which is equal to the value of [`valuePropName`](/components/form/#getFieldDecorator(id,-options)-parameters).
|
|
|
|
|
> * It has event `onChange` or an event which name is equal to the value of [`trigger`](/components/form/#getFieldDecorator(id,-options)-parameters).
|
2018-05-06 10:32:40 +00:00
|
|
|
|
> * It must be a class component.
|
|
|
|
|
</us>
|
|
|
|
|
|
2018-05-08 03:20:07 +00:00
|
|
|
|
|
2018-12-07 13:27:47 +00:00
|
|
|
|
<template>
|
2019-02-01 09:23:00 +00:00
|
|
|
|
<a-form
|
|
|
|
|
layout="inline"
|
|
|
|
|
:form="form"
|
|
|
|
|
@submit="handleSubmit"
|
|
|
|
|
>
|
|
|
|
|
<a-form-item label="Price">
|
2018-12-07 13:27:47 +00:00
|
|
|
|
<price-input
|
|
|
|
|
v-decorator="[
|
|
|
|
|
'price',
|
|
|
|
|
{
|
|
|
|
|
initialValue: { number: 0, currency: 'rmb' },
|
|
|
|
|
rules: [{ validator: checkPrice }],
|
|
|
|
|
}
|
|
|
|
|
]"
|
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item>
|
2019-02-01 09:23:00 +00:00
|
|
|
|
<a-button
|
|
|
|
|
type="primary"
|
|
|
|
|
html-type="submit"
|
|
|
|
|
>
|
|
|
|
|
Submit
|
|
|
|
|
</a-button>
|
2018-12-07 13:27:47 +00:00
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</template>
|
2018-05-06 10:32:40 +00:00
|
|
|
|
|
2018-12-07 13:27:47 +00:00
|
|
|
|
<script>
|
2018-05-06 10:32:40 +00:00
|
|
|
|
const hasProp = (instance, prop) => {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
const $options = instance.$options || {};
|
|
|
|
|
const propsData = $options.propsData || {};
|
|
|
|
|
return prop in propsData;
|
|
|
|
|
};
|
2018-05-06 10:32:40 +00:00
|
|
|
|
const PriceInput = {
|
|
|
|
|
props: ['value'],
|
2018-12-07 13:27:47 +00:00
|
|
|
|
template: `
|
|
|
|
|
<span>
|
|
|
|
|
<a-input
|
|
|
|
|
type='text'
|
|
|
|
|
:value="number"
|
|
|
|
|
@change="handleNumberChange"
|
|
|
|
|
style="width: 63%; margin-right: 2%;"
|
|
|
|
|
/>
|
|
|
|
|
<a-select
|
|
|
|
|
:value="currency"
|
|
|
|
|
style="width: 32%"
|
|
|
|
|
@change="handleCurrencyChange"
|
|
|
|
|
>
|
|
|
|
|
<a-select-option value='rmb'>RMB</a-select-option>
|
|
|
|
|
<a-select-option value='dollar'>Dollar</a-select-option>
|
|
|
|
|
</a-select>
|
|
|
|
|
</span>
|
|
|
|
|
`,
|
2018-05-06 10:32:40 +00:00
|
|
|
|
data () {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
const value = this.value || {};
|
2018-05-06 10:32:40 +00:00
|
|
|
|
return {
|
|
|
|
|
number: value.number || 0,
|
|
|
|
|
currency: value.currency || 'rmb',
|
2019-01-12 03:33:27 +00:00
|
|
|
|
};
|
2018-05-06 10:32:40 +00:00
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
value (val = {}) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
this.number = val.number || 0;
|
|
|
|
|
this.currency = val.currency || 'rmb';
|
2018-05-06 10:32:40 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
handleNumberChange (e) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
const number = parseInt(e.target.value || 0, 10);
|
2018-05-06 10:32:40 +00:00
|
|
|
|
if (isNaN(number)) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
return;
|
2018-05-06 10:32:40 +00:00
|
|
|
|
}
|
|
|
|
|
if (!hasProp(this, 'value')) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
this.number = number;
|
2018-05-06 10:32:40 +00:00
|
|
|
|
}
|
2019-01-12 03:33:27 +00:00
|
|
|
|
this.triggerChange({ number });
|
2018-05-06 10:32:40 +00:00
|
|
|
|
},
|
|
|
|
|
handleCurrencyChange (currency) {
|
|
|
|
|
if (!hasProp(this, 'value')) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
this.currency = currency;
|
2018-05-06 10:32:40 +00:00
|
|
|
|
}
|
2019-01-12 03:33:27 +00:00
|
|
|
|
this.triggerChange({ currency });
|
2018-05-06 10:32:40 +00:00
|
|
|
|
},
|
|
|
|
|
triggerChange (changedValue) {
|
2018-12-07 13:27:47 +00:00
|
|
|
|
// Should provide an event to pass value to Form.
|
2019-01-12 03:33:27 +00:00
|
|
|
|
this.$emit('change', Object.assign({}, this.$data, changedValue));
|
2018-05-06 10:32:40 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
2019-01-12 03:33:27 +00:00
|
|
|
|
};
|
2018-05-06 10:32:40 +00:00
|
|
|
|
|
2018-12-07 13:27:47 +00:00
|
|
|
|
export default {
|
2019-02-01 09:23:00 +00:00
|
|
|
|
components: {
|
|
|
|
|
PriceInput,
|
|
|
|
|
},
|
2018-12-07 13:27:47 +00:00
|
|
|
|
beforeCreate () {
|
2019-04-20 06:19:13 +00:00
|
|
|
|
this.form = this.$form.createForm(this, { name: 'customized_form_controls' });
|
2018-12-07 13:27:47 +00:00
|
|
|
|
},
|
2018-05-06 10:32:40 +00:00
|
|
|
|
methods: {
|
|
|
|
|
handleSubmit (e) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
e.preventDefault();
|
2018-05-06 10:32:40 +00:00
|
|
|
|
this.form.validateFields((err, values) => {
|
|
|
|
|
if (!err) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
console.log('Received values of form: ', values);
|
2018-05-06 10:32:40 +00:00
|
|
|
|
}
|
2019-01-12 03:33:27 +00:00
|
|
|
|
});
|
2018-05-06 10:32:40 +00:00
|
|
|
|
},
|
|
|
|
|
checkPrice (rule, value, callback) {
|
|
|
|
|
if (value.number > 0) {
|
2019-01-12 03:33:27 +00:00
|
|
|
|
callback();
|
|
|
|
|
return;
|
2018-05-06 10:32:40 +00:00
|
|
|
|
}
|
2019-01-12 03:33:27 +00:00
|
|
|
|
callback('Price must greater than zero!');
|
2018-05-06 10:32:40 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
2019-01-12 03:33:27 +00:00
|
|
|
|
};
|
2018-05-06 10:32:40 +00:00
|
|
|
|
|
|
|
|
|
</script>
|
2018-05-08 03:20:07 +00:00
|
|
|
|
|
2018-05-06 10:32:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|