<script>

    export default {
        data() {
            return {
                form: {
                    name: '',
                    type: '',
                    isPublic: false,
                    extra: [],
                    pro: ''
                },
                validateStateBtn: true,
                ruleForm: {
                    input1: '',
                    select1: '',
                    checkbox1: [],
                    input2: '',
                    input4: '',
                    checkbox2: [],
                    radio1: '1'
                },

                anotherForm: {
                    name: '',
                    sex: '',
                    cities: [],
                    isPublic: false,
                    description: '',
                    hobby: ''
                },
                rules: {
                    input1: [
                        { required: true, message: '请输入input的内容', trigger: 'blur' },
                        { min: 3, max: 15, message: '长度需要大于3小于15', trigger: 'blur' }
                    ],
                    select1: { required: true, message: '请添加select的内容', trigger: 'change' },
                    checkbox1: [
                        { type: 'array', required: true, message: '请至少选择一个checkbox', trigger: 'change' },
                        { type: 'array', max: 3, message: '请最多选择三个checkbox', trigger: 'change' }
                    ],
                    input2: { validator: this.checkInput2},
                    input4: [
                        {required: true, message: '请输入文本域内容', trigger: 'blur'},
                        {min: 3, max: 10, message: '长度需要大于3小于10', trigger: 'blur', type: 'string' }
                    ],
                    checkbox2: [{required: true, message: '必须选一个', type: 'array'}]
                },
                selectData: [
                    {
                        name: 'chrome',
                        value: 'webkit'
                    },
                    {
                        name: 'firefox',
                        value: 'ff'
                    },
                    {
                        name: 'Internet Explorer',
                        value: 'IE'
                    }
                ]
            }
        },
        watch: {
            ruleForm: {
                deep: true,
                handler(){
                    this.$nextTick(()=>{
                        this.validateAllHideVisual();
                    })
                }
            }
        },
        methods: {
            validatorAll(){
                this.$refs['ruleForm'].validate((valid) => {
                    if (valid) {
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            validateAllHideVisual(){
                this.$refs['ruleForm'].validate((valid) => {
                    if (valid) {
                        this.validateStateBtn = false;
                        console.log('success!');
                    } else {
                        this.validateStateBtn = true;
                        console.log('error!!');
                        return false;
                    }
                }, {hideVisual: true}); //hideVisual为true时，代表只校验，但是不会影响当前表单的错误内容显示
            },
            validatorReset(){
                this.$refs.ruleForm.resetFields()
            },
            async checkInput2(rule, value, callback, source, options){
                //这里使用了同步写法
                let result = await new Promise(resolve => {
                    setTimeout(()=>{
                        resolve(/^\d+/.test(value))
                    }, 500);
                });

                if(!result){
                    callback(['必须以数字开头'])
                }
            }
        }
    }
</script>
<style scoped>
	.source {
		width: 600px;
		padding-top: 30px;
	}
</style>
## Form 表单
由输入框、选择器、单选框、多选框等控件组成，用以收集、校验、提交数据

### 典型表单
下面的例子展示了一个最典型的表单是例，包括了多种控件

:::demo 在 Form 组件中，每一个表单域由一个 Form-Item 组件构成，表单域中可以放置各种类型的表单控件，包括 Input、Select、Checkbox、Radio、Switch
```html
<mc-form label-width="140px" :model="form">
    <mc-form-item label="组织名称">
        <mc-input placeholder="填写组织名称" v-model="form.name"></mc-input>
    </mc-form-item>
    <mc-form-item label="组织类型">
        <mc-select v-model="form.type" placeholder="选择组织结构">
            <mc-select-option label="企业" value="group"></mc-select-option>
            <mc-select-option label="品牌" value="brand"></mc-select-option>
            <mc-select-option label="地区" value="area"></mc-select-option>
        </mc-select>
    </mc-form-item>
    <mc-form-item label="是否公开">
        <mc-switch v-model="form.isPublic"></mc-switch>
    </mc-form-item>
    <mc-form-item label="组织属性">
        <mc-checkbox-group v-model="form.extra">
            <mc-checkbox label="peihuo">配货中心</mc-checkbox>
            <mc-checkbox label="jisan">集散中心</mc-checkbox>
            <mc-checkbox label="cangcu">仓储中心</mc-checkbox>
        </mc-checkbox-group>
    </mc-form-item>
    <mc-form-item label="高级类型">
        <mc-radio-group v-model="form.pro">
            <mc-radio label="online">线上资源</mc-radio>
            <mc-radio label="offline">线下场景</mc-radio>
        </mc-radio-group>
    </mc-form-item>
    <mc-form-item label="详细说明">
        <mc-input type="textarea" :max-number="20" placeholder="组织详细说明"></mc-input>
    </mc-form-item>
    <mc-form-item>
        <mc-btn>创建组织</mc-btn>
        <mc-btn type="ghost">取消</mc-btn>
    </mc-form-item>
</mc-form>
<script>
    export default {
        data(){
            return {
                form: {
                    name: '',
                    type: '',
                    isPublic: false,
                    extra: [],
                    pro: ''
                }
            }
        }

    }

</script>

```
:::

### 修改label位置
可以通过`label-position`属性来修改label的位置，`label-position`的取值范围是`left(默认)/top`

:::demo 该例子中展示了`label-position`为`top`时form表单的样子
```html
<div class="upright">
    <mc-form label-position="top" >
        <mc-form-item label="姓名">
            <mc-input placeholder="请输入姓名" v-model="anotherForm.name"></mc-input>
        </mc-form-item>
        <mc-form-item label="性别">
            <mc-radio-group name="sex" v-model="anotherForm.sex">
                <mc-radio label="male">男</mc-radio>
                <mc-radio label="female">女</mc-radio>
            </mc-radio-group>
        </mc-form-item>
        <mc-form-item label="去过的城市">
            <mc-checkbox-group v-model="anotherForm.cities">
                <mc-checkbox label="bj">北京</mc-checkbox>
                <mc-checkbox label="sh">上海</mc-checkbox>
                <mc-checkbox label="gd">广州</mc-checkbox>
                <mc-checkbox label="sz">深圳</mc-checkbox>
            </mc-checkbox-group>
        </mc-form-item>
        <mc-form-item label="是否公开信息">
            <mc-switch v-model="anotherForm.isPublic"></mc-switch>
        </mc-form-item>
        <mc-form-item label="个人爱好">
            <mc-input type="textarea" placeholder="请输入个人爱好" :max-number="100" v-model="anotherForm.hobby"></mc-input>
        </mc-form-item>
    </mc-form>
</div>
<style>
    .upright {
        padding-left: 30px;
    }
</style>
<script>
    export default {
        data: function () {
            return {
                anotherForm: {
                    name: '',
                    sex: '',
                    cities: [],
                    isPublic: false,
                    description: '',
                    hobby: ''
                }
            }
        }
    }
</script>
```
:::


### 表单校验
表单组件提供了表单校验功能，校验规则的语法引入了[async-validator](https://github.com/yiminghe/async-validator)

:::demo 该例子中展示了各种组件在表单内校验规则的设置方式
```html
<mc-form :model="ruleForm" :rules="rules" label-width="140px" ref="ruleForm">
    <mc-form-item label="输入框" prop="input1">
        <mc-input v-model="ruleForm.input1" :clearable="true"></mc-input>
    </mc-form-item>
    <mc-form-item label="下拉选择" prop="select1">
        <mc-select v-model="ruleForm.select1">
            <mc-select-option v-for="(item, index) in selectData" :key="index" :label="item.value" :value="item.name"></mc-select-option>
        </mc-select>
    </mc-form-item>
    <mc-form-item label="checkbox" prop="checkbox1">
        <mc-checkbox-group v-model="ruleForm.checkbox1">
            <mc-checkbox label="pc">PC端</mc-checkbox>
            <mc-checkbox label="mobile">手机</mc-checkbox>
            <mc-checkbox label="pad">平板电脑</mc-checkbox>
            <mc-checkbox label="tv">电视</mc-checkbox>
        </mc-checkbox-group>
    </mc-form-item>
    <mc-form-item label="异步校验" prop="input2">
        <mc-input v-model="ruleForm.input2" placeholder="异步校验,必须以数字开头"></mc-input>
    </mc-form-item>


    <mc-form-item label="文本域" prop="input4">
        <mc-input v-model="ruleForm.input4"
                  type="textarea"
                  placeholder="输入字符不得超过10" :max-number="10"></mc-input>
    </mc-form-item>


    <mc-form-item label="测试checkbox" prop="checkbox2">
        <mc-checkbox-group v-model="ruleForm.checkbox2">
            <mc-checkbox label="plane">飞机</mc-checkbox>
            <mc-checkbox label="train">火车</mc-checkbox>
            <mc-checkbox label="bus">汽车</mc-checkbox>
        </mc-checkbox-group>
    </mc-form-item>

	<mc-form-item label="Radio" prop="radio1">
		<mc-radio-group v-model="ruleForm.radio1">
			<mc-radio label="1">test1</mc-radio>
			<mc-radio label="2">test2</mc-radio>
		</mc-radio-group>
	</mc-form-item>

    <mc-form-item>
        <mc-btn @click="validatorAll">点击校验</mc-btn>
        <mc-btn @click="validatorReset">重置表单</mc-btn>
        <mc-btn :disabled="validateStateBtn">表单状态</mc-btn>
    </mc-form-item>

</mc-form>
<script>
    export default {
        data: function() {
            return {
                validateStateBtn: true,
                ruleForm: {
                    input1: '',
                    select1: '',
                    checkbox1: [],
                    input2: '',
                    input4: '',
                    checkbox2: [],
                    radio1: '1'
                },
                rules: {
                    input1: [
                        { required: true, message: '请输入input的内容', trigger: 'blur' },
                        { min: 3, max: 15, message: '长度需要大于3小于15', trigger: 'blur' }
                    ],
                    select1: { required: true, message: '请添加select的内容', trigger: 'change' },
                    checkbox1: [
                        { type: 'array', required: true, message: '请至少选择一个checkbox', trigger: 'change' },
                        { type: 'array', max: 3, message: '请最多选择三个checkbox', trigger: 'change' }
                    ],
                    input2: { validator: this.checkInput2},
                    input4: [
                        {required: true, message: '请输入文本域内容', trigger: 'blur'},
                        {min: 3, max: 10, message: '长度需要大于3小于10', trigger: 'blur', type: 'string' }
                    ],
                    checkbox2: [{required: true, message: '必须选一个', type: 'array'}]
                },
                selectData: [
                    {
                        name: 'chrome',
                        value: 'webkit'
                    },
                    {
                        name: 'firefox',
                        value: 'ff'
                    },
                    {
                        name: 'Internet Explorer',
                        value: 'IE'
                    }
                ]
            }
        },
        mounted: function() {
        },
        watch: {
            //通过深度监听整个表单的数据变化来实现实时更新按钮状态，
            //！！！但是强烈不建议你这样做，因为每次数据的变化都会调用一次全表单校验，这样十分消耗性能
            //如果校验包括请求后端接口的话，更是对服务器的一种巨大消耗
            ruleForm: {
                deep: true,
                handler(){
                    this.$nextTick(()=>{
                        this.validateAllHideVisual();
                    })
                }
            }
        },
        methods: {
            validatorAll(){
                this.$refs['ruleForm'].validate((valid) => {
                    if (valid) {
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            validateAllHideVisual(){
                this.$refs['ruleForm'].validate((valid) => {
                    if (valid) {
                        this.validateStateBtn = false;
                        console.log('success!');
                    } else {
                        this.validateStateBtn = true;
                        console.log('error!!');
                        return false;
                    }
                }, {hideVisual: true}); //hideVisual为true时，代表只校验，但是不会影响当前表单的错误内容显示
            },
            validatorReset(){
                this.$refs.ruleForm.resetFields()
            },
            async checkInput2(rule, value, callback, source, options){
                //这里使用了同步写法
                let result = await new Promise(resolve => {
                    setTimeout(()=>{
                        resolve(/^\d+/.test(value))
                    }, 500);
                });

                if(!result){
                    callback(['必须以数字开头'])
                }
            }
        }
    }
</script>
```
:::



### Form属性

|参数		|说明		|类型		|可选值		|默认值		|
|-----------|-----------|-----------|-----------|-----------|
|model		| 表单数据对象 		|Object		| — 		| — 		|
|rules		| 表单校验规则 		|Object		| — 		| — 		|
|labelPosition		| 表单域标签的位置 		|String		| — 		| — 		|
|labelWidth		| 表单域标签的宽度，作为 Form 直接子元素的 form-item 会继承该值 		|String		| — 		| — 		|
|labelSuffix		| — 		|String		| — 		| — 		|
|inline		| 行内表单模式 		|Boolean		| — 		| — 		|
|inlineMessage		| 是否以行内形式展示校验信息 		|Boolean		| — 		| — 		|
|statusIcon		| — 		|Boolean		| — 		| — 		|
|showMessage		| 是否显示校验错误信息 		|Boolean		| — 		|true		|
|size		| — 		|String		| — 		| — 		|
|disabled		| — 		|Boolean		| — 		| — 		|
|validateOnRuleChange		| 是否在`rules`属性改变后立即触发一次验证 		|Boolean		| — 		|true		|

### FormItem 属性

|参数		|说明		|类型		|可选值		|默认值		|
|-----------|-----------|-----------|-----------|-----------|
|label		| — 		|String		| — 		| — 		|
|labelWidth		| — 		|String		| — 		| — 		|
|prop		| — 		|String		| — 		| — 		|
|required		| — 		|Boolean		| — 		| — 		|
|rules		| — 		|Object/Array		| — 		| — 		|
|error		| — 		|String		| — 		| — 		|
|validateStatus		| — 		|String		| — 		| — 		|
|for		| — 		|String		| — 		| — 		|
|inlineMessage		| — 		|String/Boolean		| — 		| — 		|
|showMessage		| — 		|Boolean		| — 		|true		|
|size		| — 		|String		| — 		| — 		|