4

I am building an interface using Vue.js. I have a form, this form contains an address, and other bits of miscellaneous data. So I created two components in Vue, UserData and UserAddress. UserData contains an instance of UserAddress as a child component. I want to specialize the behaviour of the "Submit" button for the form depending on the page, so these components don't contain the submit button -- the outer component, representing the page (UserPage) contains the submit button, and just includes the UserData template.

So the hierarchy goes, UserPage => UserData => UserAddress.

Now I need to get ALL the form data within some method on UserPage. I would just say that I need to get it within the submit handler, but the only way that I can think to do this without directly accessing the data of the child components is the following:

  • Use $broadcast to propagate an event e1 downwards from the submit handler
  • Listen for the e1 event in UserAddress
  • Use $dispatch to send an event e2 and bundle the address data with the message
  • Listen for e2 in UserData, add the other form data to the message, and propagate or re-dispatch the event
  • Listen for e2 in UserPage and find the full aggregated data there.

Is this a normal method for dealing with a situation like this? It seems like overkill, but accessing child $data is explicitly non-recommended by the manual.

3
  • Later I realized that dealing with this at all is insane. Whenever you want to do this it's a sign that you should be using Vuex. Also, events are gone in Vue 2.0, so don't rely on them. Commented Sep 20, 2016 at 19:54
  • events are not gone in 2, you just have to use a hub instead of broadcast and dispatch Commented Oct 9, 2016 at 15:55
  • Not gone, but marked as deprecated on the migration guide. I experimented with the hub pattern, but it quickly got out of control. Vuex is much better. Commented Oct 10, 2016 at 14:03

1 Answer 1

4

Use twoWay props. If you declare twoWay: true in a child property, and pass a variable from the parent like :child-prop.sync="parent-data", then the value of the property is written on the parent. You can make a chain with this. The code would be like this

child

<template>
  <input v-model="address">
</template>
<script>
export default {
  props: {
    address: {
      type: String,
      twoWay: true
    }
  }
}
</script>

parent

<template>
  <div>
    <input v-model="uname">
    <user-address :address.sync="uaddress"></user-address>
  </div>
</template>
<script>
export default () {
  components: {
    'user-address': userAddress
  },
  props: {
    uaddress: {
        type: String,
      twoWay: true
    },
    uname: {
        type: String,
      twoWay: true
    }
  }
}
</script>

check this fiddle with the chain userPage => userData => userAddress

Sign up to request clarification or add additional context in comments.

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.