【问题标题】:Get all input values from dynamic form in Vuejs从Vuejs中的动态表单获取所有输入值
【发布时间】:2019-12-06 09:10:54
【问题描述】:

我有一些可重用的组件:

  • 文本字段
  • 表格

还有一个我将它们都导入的组件。我将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

谁能给我一些建议,告诉我如何从Form 组件中的TextField 组件中获取v-model 值?如果不可能,或者我可能会以另一种方式做得更好,请告诉我。

【问题讨论】:

  • 我不是 vuejs/vuetify 专家 - 但 :vModel="email" 看起来不像我见过的任何语法
  • 我也查看了您的沙盒。您还必须将数据作为道具传递给表单组件,然后从那里提交:codesandbox.io/s/late-forest-7pd8q

标签: vue.js vuejs2 vuetify.js


【解决方案1】:

v-model 只是创建两个东西的简写:

  • :value 绑定(作为道具传递给您的组件)
  • @input 事件处理程序

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

你可以试试这样的:

文本字段

<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

【讨论】:

  • 看看我创建的沙箱:codesandbox.io/s/late-forest-7pd8q。此外,您可能希望命名表单数据以轻松传递它:codesandbox.io/s/condescending-kepler-9c40q
  • 我不知道为什么,但是如果我将该代码复制到我自己的项目中,它会提醒undefined。我试图找出原因,但您的沙盒就像我希望的那样工作。
  • 确保将数据作为道具传递给最终组件中的表单组件。我更新了答案以反映这些变化。
  • 非常感谢!现在可以了,完全忘记传递数据了
【解决方案2】:

不完全确定您在代码中做了什么,但是使用 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>


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

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) => {

                })
            },
         }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多