1

I have a simple Form component with just a select option. Whenever I choose an option, a child component is rendered inside my main component. My problem is I can't get Vue to bind my parent component data with child component data.

form.settings is dynamic so I can not set the properties before hand at Form.vue.

This form is submitted to a Spring-boot web application via axios and I see that form.settings is null on client side when I submit the form.

I am new to Vue and here is my attempt:

Form.vue

<template>
  <div>
    <form>
      <div>
        <select v-model="form.type">
          <option></option>
          <option value="1">1</option>
          <option value="2">2</option>
        </select>
      </div>
      <PresetOne v-if="form.type == '1'" :settings="form.settings"/>
      <PresetTwo v-if="form.type == '2'" :settings="form.settings"/>
    </form>
  </div>
</template>

<script>
import PresetOne from "@/components/PresetOne"
import PresetTwo from "@/components/PresetTwo"

export default {
  name: "SettingsForm",
  data: () => ({
    form: {
      type: null,
      settings: null
    }
  }),
  components: {
    PresetOne,
    PresetTwo
  }
}
</script>

PresetOne.vue

<template>
  <div>
    <input v-model="settings.username" />
    <input v-model="settings.password" />
  </div>
</template>

<script>
export default {
  name: "PresetOne",
  data: () => ({
    settings: {
      username: null,
      password: null
    }
  })
}
</script>

PresetTwo.vue

<template>
  <div>
    <input v-model="settings.email" />
    <input v-model="settings.password" />
  </div>
</template>

<script>
export default {
  name: "PresetTwo",
  data: () => ({
    settings: {
      email: null,
      password: null
    }
  })
}
</script>

3 Answers 3

1

You can send data to child components as properties

<PresetOne v-if="form.type == '1'" :settings="form.settings"/>

To use the property in child component, you need to receive the property like

export default {
  name: "PresetOne",
  props:["settings"]
}

You can also communicate from child component to parent component using the $emit() option.

Reference : props, emit

Also, you can use your data section as follows:

data:()=>{
  return {
    // add your variables here
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Basically what are you doing in the child components is changing the Data state of that component only, that's the reason why you couldn't bind that to the parent.

Try this:

PresetOne.vue & PresetTwo.vue

<template>
  <div>
    <input v-model="settings.email" />
    <input v-model="settings.password" />
  </div>
</template>

<script>
export default {
  props: ['settings']
}
</script>

Update: remember to set settings's default value in form.vue to be an empty object so you can be able to assign the properties from the child components.

3 Comments

This causes error. TypeError: Cannot read property 'email' of null. Probably because settings object have no keys defined right now.
Yes! that was the reason for the error, a fast solution is to set the settings value to be empty object, like this: settings: {} in form.vue
What I ended up doing is define every possible key for settings object in parent and bind them via props. Your answer has led me to a solution so I accept it.
0

Have a look at codesandbox link, this might be helpful.

Basically, form.settings that you're sending is null which is not even being used in the child component. So, no where form.settings is being updated.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.