0

I want to load the authenticated user and use it accross all my vue components (without an unnecessary ajax request since I can load it directly from the back-end).

My Laravel home.blade.php references a Vue app and I tried binding the Auth::user() to the main vue:

<div id="app" :authuser="{{ Auth::user() ? : '[]' }}"></div>

My app.js file looks like this:

const app = new Vue({
  el: '#app',
  props: ['authuser'],
  data: { authuser: this.authuser }
});

But it seems you cannot pass props to the main Vue object. What is the best way to do it?

Note: I am open to other suggestions than passing through props. Ideally, I would like to reference an authuser object globally from all my vue components. Maybe through window.authuser for example?

Saurabh
  • 71,488
  • 40
  • 181
  • 244
BassMHL
  • 8,523
  • 9
  • 50
  • 67

3 Answers3

2

Adding this to the blade template before calling app.js does the trick:

<script>
  let authuser = {!! Auth::user() ? : '[]' !!};
</script>
<script src="{{asset('js/app.js') }}"></script>

This will allow you to use authuser directly and globally in any component, for example:

<template>
  <div class="answer" v-if="authUserAnswered">
     Edit Answer
  </div>
</template>

<script>
  export default {
    props: ['answer'],
    computed: {
      authUserAnswered() { return authuser.id == this.answer.user_id; }
    }
  }
</script>

This is cleaner than using this.$root every time.

You can learn more about Shared States here.

BassMHL
  • 8,523
  • 9
  • 50
  • 67
0

One way to do this can be using $root. As suggested here, you should be able to set in the app component and use it across components.

In your app.js:

const app = new Vue({
  el: '#app',
  created () {
    // will fire the first time the router is loaded,
    // and won't be called again until page refresh
    // maybe load in your data dynamically?
    this.$root.authuser = this.authuser;
  }
});

And then in your component:

this.$root.authuser

Other way to do this can be using a central state or vuex which is more popular among the community. You can have a look at similar answer here. You can commit to vuex mutation in the created/mounted block of app.js and later can access it in any components with help of getters.

tony19
  • 125,647
  • 18
  • 229
  • 307
Saurabh
  • 71,488
  • 40
  • 181
  • 244
  • In your example, how do you get the `this.authuser` from php into `const app`? – BassMHL Feb 25 '17 at 03:50
  • @BassemLhm [this](https://laracasts.com/discuss/channels/vue/pass-data-from-view-to-vue-instance?page=1) should help. – Saurabh Feb 25 '17 at 03:55
  • Thanks for your help, your answer combined with a laracast I watched made me find my answer. I wanted to avoid the repetition of this.$root.authuser all over my components. – BassMHL Feb 25 '17 at 04:39
0

In app.js, you can declare global variables.

For example:

// app.js
global.user = 'hello';

// anywhere else, you can access the user var
console.log(user);

You can also apply this to the vue object itself(if you want):

global.vm = new Vue({
    methods: {
        helloWorld(){}
    }
});

And you'll be able to access it's methods and so on from other components: vm.helloWorld();.

To get user into app.js, you may print it in JSON between script tags. Your app.js should be able to access it later. eg.

<script>
    var user="{{$user}}";
</script>
<script src="app.js" type="text/javascript"></script>

But maybe it would be better to use an AJAX request.

JC Lee
  • 2,337
  • 2
  • 18
  • 25