分步表单 和 自定义表单控件
结合前面所了解到的内容。这里分步分三个路由来实现。
先创建一个store的module。保存我们需要数据,然后引入到store的index.js中
form.js
1 import router from "../../router";
2 import request from "../../utils/request";
3 import { notification } from "ant-design-vue";
4
5 const state = {
6 step: {
7 payAccount: "12345",
8 receiverAccount: {
9 type: "bank",
10 number: ""
11 }
12 }
13 };
14
15 const actions = {
16 async submitStepForm({ commit }, payload) {
17 if (payload.payload.password == 123123) {
18 let res = await request({
19 url: "api/form",
20 method: "POST",
21 data: payload.payload
22 });
23 if (res.data.message == "成功") {
24 commit("saveStepFormData", payload);
25 router.push("/form/step-from/result");
26 }
27 } else {
28 notification.error({
29 message: "密码错误"
30 });
31 }
32 }
33 };
34
35 const mutations = {
36 saveStepFormData(state, { payload }) {
37 state.step = {
38 ...state.step,
39 ...payload
40 };
41 }
42 };
43 export default {
44 namespaced: true,
45 state,
46 actions,
47 mutations
48 };
这里的request也是用的之前的js函数模拟数据。
function form(method) {
let res = null;
switch (method) {
case "POST":
res = { message: "成功" };
break;
default:
res = null;
}
return res;
}
module.exports = form;
写第一步
<template>
<div>
<a-form layout="horizontal" :form="form">
<a-form-item>
<a-form-item
label="付款账户"
:label-col="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>
<a-input
v-decorator="['payAccount',{
initialValue:step.payAccount,
rules:[
{required:true,message:'请输入付款账户'}
]
}]"
placeholder="请输入内容"
/>
</a-form-item>
<a-form-item
label="收款账户"
:label-col="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>
<ReceiverAccount
v-decorator="['receiverAccount',{
initialValue:step.receiverAccount,
rules:[
{required:true,message:'请输入收款账户',
validator: (rule,value,callback) => {
if(value && value.number){
callback()
} else {
callback(false)
}
}}
]
}]"
placeholder="请输入内容"
/>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="handleSubmit">下一步</a-button>
</a-form-item>
</a-form-item>
</a-form>
</div>
</template>
<script>
import ReceiverAccount from "@/components/ReceiverAccount";
export default {
data() {
this.form = this.$form.createForm(this);
return {
formItemLayout: {
labelCol: { span: 4 },
wrapperCol: { span: 14 }
}
};
},
components: {
ReceiverAccount
},
computed: {
step() {
return this.$store.state.form.step;
}
},
methods: {
handleSubmit() {
const { form, $router, $store } = this;
form.validateFields((err, values) => {
if (!err) {
$store.commit({
type: "form/saveStepFormData",
payload: values
});
$router.push("/form/step-from/comfirm");
}
});
}
}
};
</script>
<style></style>
第二步
<template>
<div>
<a-form layout="horizontal" :form="form">
<a-form-item>
<a-form-item
label="付款账户"
:label-col="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>{{step.payAccount}}</a-form-item>
<a-form-item
label="收款账户"
:label-col="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>
<span style="color:#a12221">{{step.receiverAccount.type == 'alipay'? '支付宝' : '银行卡'}}</span>
<span>: {{step.receiverAccount.number}}</span>
</a-form-item>
<a-form-item
label="账户密码"
:label-col="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>
<a-input
type="password"
v-decorator="['password',{
rules:[
{required:true,message:'请输入付款账户密码'}
]
}]"
placeholder="请输入内容"
/>
</a-form-item>
<a-form-item>
<a-button style="margin-right:15px" type="dashed" @click="handleBack">上一步</a-button>
<a-button type="primary" @click="handleSubmit">提交</a-button>
</a-form-item>
</a-form-item>
</a-form>
</div>
</template>
<script>
export default {
data() {
this.form = this.$form.createForm(this);
return {
formItemLayout: {
labelCol: { span: 4 },
wrapperCol: { span: 14 }
}
};
},
computed: {
step() {
console.log(this.$store.state.form.step);
return this.$store.state.form.step;
}
},
methods: {
handleSubmit() {
const { form, $store, step } = this;
form.validateFields((err, values) => {
if (!err) {
$store.dispatch({
type: "form/submitStepForm",
payload: { ...step, ...values }
});
}
});
},
handleBack() {
this.$router.push("/form/step-from/info");
}
}
};
</script>
<style></style>
第三步
<template>
<div>
<h3>操作成功,预计两小时内到账</h3>
<div>{{time}}秒后将自动返回首页</div>
</div>
</template>
<script>
export default {
data() {
return {
time: 3
};
},
mounted() {
var timer = setInterval(() => {
this.time--;
if (this.time <= 0) {
clearInterval(timer);
this.$router.replace("/form/step-from/info");
}
}, 1000);
}
};
</script>
<style></style>
效果图:

在第一步中,有使用到自定义组件,插入到表单中,并且使用了表单自动校验。在antd的官网上,有相关的解释。
自定义或第三方的表单控件,也可以与 Form 组件一起使用。只要该组件遵循以下的约定:
- 提供受控属性
value或其它与valuePropName-参数) 的值同名的属性。 - 提供
onChange事件或trigger-参数) 的值同名的事件。 - 不能是函数式组件。
组件的代码
<template>
<div>
<a-input-group compact>
<a-select v-model="type" style="width :130px" @change="handleTypeChange">
<a-select-option value="alipay">支付宝</a-select-option>
<a-select-option value="bank">银行卡</a-select-option>
</a-select>
<a-input
v-model="number"
style="width: calc(100% - 130px)"
@change="handleInputChange"
placeholder="请输入账户"
/>
</a-input-group>
</div>
</template>
<script>
export default {
props: {
value: {
type: Object
}
},
data() {
const { type, number } = this.value || {};
return {
type: type || "alipay",
number: number || ""
};
},
watch: {
value(val) {
Object.assign(this, val);
}
},
methods: {
handleTypeChange(val) {
this.$emit("change", { ...this.value, type: val });
},
handleInputChange(e) {
this.$emit("change", { ...this.value, number: e.target.value });
}
}
};
</script>
<style>
</style>
来源:https://www.cnblogs.com/wangnothings/p/12596311.html