50

Using v2.2.2. I have the following structure in my VueJS app. How can I access all of the Account components from a method on my Post component? The number of Accounts is dynamic - I want to grab all of the loaded Account components and iterate over them.

I know it's got something to do with $refs and $children, I just can't seem to figure out the right path.

<Root>
    <Post>
        <AccountSelector>
            <Account ref="anAccount"></Account>
            <Account ref="anAccount"></Account>
            <Account ref="anAccount"></Account>
        </AccountSelector>
    </Post>
</Root>
Asef Hossini
  • 655
  • 8
  • 11
Luke Shaheen
  • 4,262
  • 12
  • 52
  • 82
  • The whole refs thing is extremely fragile if components are deeply nested and/or they get moved around during development. Check this way out instead: https://stackoverflow.com/a/47889841/34806 – Dexygen May 05 '21 at 12:43

2 Answers2

59

https://v2.vuejs.org/v2/guide/components.html#Child-Component-Refs

Despite the existence of props and events, sometimes you might still need to directly access a child component in JavaScript. To achieve this you have to assign a reference ID to the child component using ref. For example:

<div id="parent">
  <user-profile ref="profile"></user-profile>
</div>

var parent = new Vue({ el: '#parent' })
// access child component instance
var child = parent.$refs.profile

When ref is used together with v-for, the ref you get will be an array or an object containing the child components mirroring the data source.

Basically inside AccountSelector.vue you can do this.$refs.anAccount.map(account => doThingToAccount(account))

Edit The above answer is for accessing a direct child.

Currently there is no way to access a non direct parent / child component with $refs. The best way to get access to their data would be through events https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication or by using Vuex (Which i would recommend).

Non direct parent - child communication is very tricky without 1 of these 2 methods.

tony19
  • 125,647
  • 18
  • 229
  • 307
Dan Gamble
  • 3,965
  • 1
  • 24
  • 44
  • 1
    Thanks! But how can I bubble up that data to `Post`? I'm looking to access the data inside of Post, one level above AccountSelector. If I do `post.$refs.anAccount` I get undefined. I'm missing a level. – Luke Shaheen Mar 15 '17 at 15:52
  • 1
    Sorry i get you now, i'm not sure if you can get undirect children. The best way to get access to their data would be through events http://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication or by using Vuex (Which i would recommend). Non direct parent - child communication is very tricky without 1 of these 2 methods. – Dan Gamble Mar 15 '17 at 15:54
  • Thanks for the reference - that paragraph does indeed state that I'll need to use Vuex. I'm actually currently doing that, just thought there was a more direct way! Can you modify your answer so I can accept it as the answer? – Luke Shaheen Mar 15 '17 at 15:58
  • I've updated the answer to more directly match the question asked – Dan Gamble Mar 15 '17 at 16:02
  • I'm very late to the party, but would an **event bus** not be your best option here? – Jamie Marshall Mar 10 '21 at 20:02
12

You can access nested components data using $refs and if you want to access the refs inside of it you first have to target the first element of the first refs ([0])

example: parent.$refs[0].$refs.anAccount

James A Mohler
  • 11,060
  • 15
  • 46
  • 72