Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue js 2 - Accessing data in App.vue from child components

I'm pretty new to Vue and I'm trying to create my first app with it (I have worked through a whole tutorial though so it's not like I'm completely new to it). I come from a Java/Grails background so this new "frontend oriented webapps" is still pretty confusing to me. I'm using Vue 2 with webpack.

The problem I'm having is running methods when the app initializes which creates data in the App.vue component (which I'm assuming is the root component, is that correct?) and then accessing this data in child components. So specifically what I'm trying to do is on in the 'created' life cycle hook I want to check if the user is logged in or not and then I want to update my navbar accordingly (show a login button if not, else show the user's name, for example).

I haven't even quite figured out how exactly I'm gonna determine if the user is logged in yet coz so far I've only been trying to create dummy data in the App.vue component and then accessing it in child components. Everywhere that I've researched says that I should use an event bus but (I think) that's not gonna work for me (correct me if I'm wrong) coz the only examples I can find is all $emit functions being called on user events (like button clicks) and I want it to have the data globally accessible (and mutate-able) everywhere all the time.

So I'll try to show you some code of what I had in mind:

App.vue:

...stuff...
data() {
  return {
    authToken = '',
    userdetails = {},
    loggedIn = false
  }
},
created: function() {
  // check browser storage for authToken
  if(authToken) {
    // call rest service (through Vue Resource) to Grails backend that I set up 
    // beforehand and set this.userdetails to the data that gets returned  
    if(this.userdetails) {
      this.loggedIn = true;
    }
  }
}
...stuff...

Home.vue:

<template>
  <div class="home">
    <nav-bar></nav-bar>
  </div>
</template>
...stuff

NavBar.vue:

<template>
  <div class="navBar">
    <div v-if="loggedIn">Hi {{ userdetails.name }}</div>
    <div v-else>Please log in before continuing.</div>
  </div>
</template>

Please excuse if any of that code has any mistakes in it, it's just to show more or less what I'm trying to do and I made most of it up right now. So the main question: How do I go about getting the v-if="loggedIn" and {{ userdetails.name }} part to work (coz obviously the way it's set up now that won't work, right?). And then besides that, any general advice on "global variables" and data flow in Vue js will be appreciated coz I believe that my server-side app mentality might not work in front-end javascript apps.

like image 378
SeriousLee Avatar asked Jul 21 '17 11:07

SeriousLee


People also ask

How do you pass data between child components in Vue?

By adding the state isOpen to the parent, we can facilitate communication between the two sibling components. When the Button component is clicked it emits an event that updates the isOpen variable. That variable is then passed down to the Toggle component as a prop.


2 Answers

To get Data from parent component you can use this.$parent.userdetails in the child component.

But a much better way is to use props like this

https://vuejs.org/v2/guide/components.html#Passing-Data-with-Props

like image 58
NMathar Avatar answered Nov 10 '22 20:11

NMathar


Lite pattern, not for complex sharing tasks

You can access global app component everywhere (routes, components, nested components) with the predisposed field:

this.$root

Notes for overengineers: It is officially suggested as "lite" approach in vue guide: http://vuejs.org/v2/guide/state-management.html.

Obviously, it is not a architectural patternized solution, but ok for just sharing a variable or two.

In these case this lean approach avoids developer to import a full sharing framework like vuex, heaving development, know-how requirement and page download, just for such a trivial sharing task.

If you dislike lite approaches, even when appropriated and officially suggested, maybe is not how to share the problem, but which framework to use.

For instance, Angular is probably best fitted for heavy engineered approach, and I not mean one is better than the other, I mean different instruments suite best for different task and approaches, I too use it when need to realize a heavier and more complex solution, in these case even with vuex I could not handle all the components interaction and realtime data sharing.

like image 21
Luca C. Avatar answered Nov 10 '22 20:11

Luca C.