分步表单 和 自定义表单控件
结合前面所了解到的内容. 这里分步分三个路由来实现.
先创建一个 store 的 module. 保存我们需要数据, 然后引入到 store 的 index.JS 中
form.JS
- import router from "../../router";
- import request from "../../utils/request";
- import { notification } from "ant-design-vue";
- const state = {
- step: {
- payAccount: "12345",
- receiverAccount: {
- type: "bank",
- number: ""
- }
- }
- };
- const actions = {
- async submitStepForm({ commit }, payload) {
- if (payload.payload.password == 123123) {
- let res = await request({
- url: "api/form",
- method: "POST",
- data: payload.payload
- });
- if (res.data.message == "成功") {
- commit("saveStepFormData", payload);
- router.push("/form/step-from/result");
- }
- } else {
- notification.error({
- message: "密码错误"
- });
- }
- }
- };
- const mutations = {
- saveStepFormData(state, { payload }) {
- state.step = {
- ...state.step,
- ...payload
- };
- }
- };
- export default {
- namespaced: true,
- state,
- actions,
- mutations
- };
这里的 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>
来源: http://www.bubuko.com/infodetail-3483783.html