简体   繁体   中英

Vuejs v-model for an entire form instead of individual input?

I am creating a single Vue.js component that's purpose is to create "custom" forms.

This component is basically one form by itself with multiple input fields. In this form you can choose to add questions, define the input type, etc. The entire data is stored in an array, where the data represents a form.

In the future, this array of questions can be parsed and used to display a form. This allows users to create their own forms without hardcoding it.

The problem:

As mentioned, the entire data that I want to store is an array of questions, where each question is represented by an object. For example [ { 'question_name': "How are you", 'input_type': "text" }, ... ] etc etc.

However, because this form is not an input field by itself, and instead the data comprises of many smaller inputs, I cannot do a v-model on my form component easily.

Thus there is no way to make the entire form data "reactive" from the parent component, the same way input fields are reactive with the v-model variable they are binded to.

For example, in my Parent.vue I might want this

<CustomFormComponent v-model="formData" /> # form data is the array I mentioned

and be able to interact with the "formData" from the parent directly, with the CustomFormComponent being reactive to such changes.

A good solution but not the best:

One way of course is to add a setter and getter method to my custom form component. When I need the data for submission I can call the getter. When I need to add pre-determined questions I can use the setter.

Does anyone know if what I want to do is possible?

You don't specify the version of VueJS you're running. I'll assume it's VueJS 2, which is the one I've used most, but surely it can be done with 3 too:

<template>
  <div id="app">
    <p>My Form</p>
    <CustomForm v-model="questions" />
  </div>
</template>

<script>
import CustomForm from "./components/CustomForm";

export default {
  name: "App",
  data() {
    return {
      questions: [
        { id: 1, label: "1", answer: "" },
        { id: 2, label: "2", answer: "" },
        { id: 3, label: "3", answer: "" },
        { id: 4, label: "4", answer: "" },
        { id: 5, label: "5", answer: "" },
      ],
    };
  },
  components: {
    CustomForm,
  },
};
</script>

And then CustomForm.vue :

<template>
  <form>
    <div v-for="question in value" :key="question.id">
      <p>{{ question.label }}</p>
      <input
        :id="question.id"
        :value="question.answer"
        @input="(e) => (question.answer = e.target.value)"
      />
    </div>
  </form>
</template>

<script>
export default {
  name: "CustomForm",
  props: {
    value: Array,
  },
};
</script>

Obviously, you could change this to also have other types of DOM elements, like select , checkbox ... It's a simple example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM