从Vuejs中的动态表单获取所有输入值

时间:2019-12-06 09:10:54

标签: vue.js vuejs2 vuetify.js

我有一些可重复使用的组件:

  • TextField
  • 表格

和我将它们都导入的组件。我将TextField组件作为道具传递给Form。在此Form组件中,我有一个提交按钮,该按钮需要从传递的TextField组件中获取所有值。据我在文档中所读的内容,我可以使用v-model来获取值。但是由于某种原因,我找不到如何在Form组件中获取这些值的方法。也许我缺少了一些东西,希望有人可以帮助我。我已经看过这个问题:Get all Input values - Vuejs。但是,这不能解决我的问题。

TextField组件如下所示:

<template>
  <v-text-field
    v-model="vModel"
    :rules="rules"
    :counter="counter"
    :label="label"
    :required="required"
    :placeholder="placeholder"
    :value="value"
  ></v-text-field>
</template>

<script>
export default {
  name: "TextField",
  props: {
    rules: Array,
    counter: Number,
    label: String,
    required: {
      type: Boolean,
      default: true
    },
    placeholder: String,
    value: String
  },
  data: () => ({
    vModel: '',
  }),
};
</script>

Form组件如下所示:

<template>
  <v-form>
    <v-container>
      <slot></slot>
      <v-btn class="mr-4" @click="submit">Submit</v-btn>
    </v-container>
  </v-form>
</template>

<script>
export default {
  methods: {
    submit () {
      // console.log form data
    }
  }
};
</script>

导入两个组件的组件:

<template>
  <Form>
      <v-row>
        <v-col cols="12" md="4">
          <TextField :label="'Email address'" :vModel="email"/>
        </v-col>
      </v-row>
  </Form>
</template>

<script>
import Form from "../../../components/Form/Form";
import TextField from "../../../components/Form/TextField";

export default {
  components: {
    Form,
    TextField,
  },
  data: () => ({
    email: '',
  })
};
</script>

我还创建了一个CodeSandBox

有人可以给我一些建议,我如何从v-model组件内的TextField组件中获取Form值吗?如果这是不可能的,或者我可能会以其他方式做得更好,请告诉我。

2 个答案:

答案 0 :(得分:1)

v-model只是创建两件事的简写:

  • :value绑定(作为对组件的支持传递)
  • @input事件处理程序

当前,您的TextField组件中的vModel变量可能会收到value,但不会将其发送回父组件。

您可以尝试如下操作:

TextField

<template>
  <v-text-field
    v-model="localValue"
    :rules="rules"
    :counter="counter"
    :label="label"
    :required="required"
    :placeholder="placeholder"
  ></v-text-field>
</template>

<script>
export default {
  name: "TextField",
  props: {
    rules: Array,
    counter: Number,
    label: String,
    required: {
      type: Boolean,
      default: true
    },
    placeholder: String,
    value: String
  },
  data: () => ({
    localValue: '',
  }),
  created() {
    this.localValue = this.value;
    this.$watch('localValue', (value) => {
       this.$emit('input', value);
    }
  }
};
</script>

表格

<template>
  <v-form>
    <v-container>
      <slot></slot>
      <v-btn class="mr-4" @click="submit">Submit</v-btn>
    </v-container>
  </v-form>
</template>

<script>
export default {
  props: ['form'],
  methods: {
    submit () {
      alert(JSON.stringify(this.form));
    }
  }
};
</script>

您的最终组成部分:

<template>
  <Form :form="form">
      <v-row>
        <v-col cols="12" md="4">
          <TextField :label="'Email address'" v-model="formvalentin@whatdafox.com"/>
        </v-col>
      </v-row>
  </Form>
</template>

<script>
import Form from "../../../components/Form/Form";
import TextField from "../../../components/Form/TextField";

export default {
  components: {
    Form,
    TextField,
  },
  data: () => ({
    form: {
      email: ''
    }
  })
};
</script>
  

有关v-model的更多信息:https://vuejs.org/v2/guide/forms.html

答案 1 :(得分:1)

不确定自己在代码中做什么,但是使用v-model简化模板和组件看起来像下面的代码。

ContactUs.vue


<template>     
    <form method="POST"
          autocomplete="off"
          class="form--container relative box-col-center w-full"
          name="contact"
          action="/form/contact"
          @submit.prevent="onSubmit">

        <input class="form--field font-poppins w-full"
               type="text"
               name="name"
               v-model="field.name"
               placeholder="Your name"
               autocomplete='name'>

        <input class="form--field font-poppins w-full"
               type="email"
               id="email"
               name="email"
               v-model="field.email"
               placeholder="Your email"
               autocomplete='email'>

        <textarea class="textarea form--field font-poppins w-full"
              id="body"
              name="body"
              placeholder="I'd like to know about ..."
              v-model="field.body"
              rows="5">
            </textarea>

        <button type="submit"
                @click.prevent="onSubmit()"
                class="container--row container--center btn--purple btn--040 w-2/3 lg:w-full">
            <span class="text--w-full uppercase">Submit</span>
        </button>

    </form>
</template>

<script>

    export default {
        name: 'ContactUs',
        data() {
            return {
                fields:{
                    name: '',
                    email: '',
                    body: ''
                },
            }
        },
        methods: {
            onSubmit() {
                let vm = this;

                return new Promise((resolve, reject) => {
                    axios.post('/forms/contact', vm.fields)
                        .then(response => {
                            resolve(response.data);

                        }).catch(err => {
                            reject(err.response);
                    });
                });
            },
        }
    }
</script>


如果您试图创建一个Form服务类,那么它将几乎相同,只是您将表单逻辑抽象到该类。

FormService.js


export default class Form {
    /**
     * Create a new Form instance.
     *
     * @param {object} data
     * @param type
     */
    constructor(data) {
        this.originalData = data;
        for (let field in data) {
            this[field] = data[field];
        }
    }

    /**
     * Submit the form.
     *
     * @param {string} requestType
     * @param {string} url
     */
    submit(requestType, url) {
        return new Promise((resolve, reject) => {
            axios[requestType](url, this.data())
                .then(response => {
                      resolve(response.data);

                }).catch(err => {
                    reject(err.response);
                });
        });
    }

}

然后在您的组件中,注入表单服务并使用数据

ContactUs.vue

    import Form from '../services/FormService.js';

    export default {
        name: 'ContactUs',

        data() {
            return {
                fields: new Form({
                    name: '',
                    email: '',
                    body: ''
                }),
            }
        },
        methods: {
            onSubmit() {
                let self = this;

                self.form.post('/forms/contact')
                    .then(response => {


                    }).catch((err) => {

                })
            },
         }