Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

haakym's avatar

Using Vue.js in Laravel 5.3

In previous Laravel projects, I've dropped Vue.js into a page and created a Vue instance specific for that page. Something like this at the bottom of my page:

<div id="app">
    @{{ message }}
</div>
...
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.27/vue.js"></script>
<script>
        new Vue({
          el: '#app',
          data: {
            message: 'Hello Vue.js!'
          }
        });
</script>

Now in Laravel 5.3 Vue.js comes bundled up with it and I have got a slight grasp on how I can create components which I can then drop into a page. However, I am struggling to understand how I can create a Vue.js instance like the aforementioned, i.e. where I just need to drop a vue instance into a page instead of creating a whole component.

Can I utilise Vue that gets incorporated into app.js when running gulp or do I need to pull in Vue as I did before with the script tag?

Thanks!

0 likes
20 replies
ejdelmonico's avatar

You can open app.js and write something like this:

Vue.component('Alert', require('./components/Alert.vue'));

const app = new Vue({
  el: 'body'
});

Then webpack will handle the rest.

4 likes
mniblett's avatar

I'm really not sure how to start using Vue with laravel 5.3 and the laracasts haven't helped a lot because they seem to be pre-5.3 and talk about bringing in vueify so you can put all your code into a single file. Is this already part of laravel 5.3? the sample component seems to be set up that way, yet I don't see any vueify package in the node_modules folder, so is there some other way this is happening now?

The sample component is not that helpful because it's not using any props or methods so I am not sure how to get going with a component that actually does something.It would be a lot more helpful if it contained some data and methods so we could see where to put those.

So, do we put that stuff in the component constructor as is shown in the laracasts where it looks something like this:

Vue.component('example', {
    template: 'example template',
    data: function() {
        ...
    }
});

In the sample it looks like we are pointing to the separate .vue file with: Vue.component('example', require('./components/Example.vue'));

So, does it then go in here:

<script>
    export default {
        ready() {
            console.log('Component ready.')
        }
    }
</script>

and if so how? If not, where do you put the data and the props?

haakym's avatar

@ejdelmonico Thanks for your reply. So are you saying that all interactions with Vue.js should be via components?

Laraveldeep's avatar

@haakym

If you have fresh installation, check out the resources\assets\js\components\Example.vue

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>

                    <div class="panel-body">
                        I'm an example component!
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        ready() {
            console.log('Component ready.')
        }
    }
</script>


<style>
    // your component styling
</style>

you can create your Vue component like this in separate file including styling.

Then in your app.js you have to include that file as component like this

Vue.component('example', require('./components/Example.vue'));

const app = new Vue({
    el: 'body'
});

Now you can use the component in your blade as

<example></example>

Behind the scene webpack will take care of the rest when you gulp or gulp watch it as mentioned by @ejdelmonico

Hope this helps

3 likes
haakym's avatar

I'm going to repeat the question again as based on some of the answers it seems as I didn't get my point across. Hope this makes things clearer.

In Laravel projects prior to 5.3 I've utilised Vue.js using the script tag like this:

<script type="text/javascript" src="../js/vue.js"></script>

I would then create a Vue instance specific for that page like this:

<script>
    new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue.js!'
      }
    });
</script>

and then bind it to the relevant div#id in my HTML.

Now, in Laravel 5.3 Vue.js comes bundled and I am fully aware that I can use components as described in the docs, however, my question is if I want to create a Vue.js instance like I just mentioned, i.e. where I create a Vue.js instance strictly for a given page (not a component) how do I do it?

Do I set it up like I used to by importing the vue.js library in a script tag firstly or can I use generated app.js?

Am I not supposed to do it, should I be creating components for everything?

For me, it doesn't make sense to make a component for something I am only using once - I thought the purpose of components was that they are reusable. As mentioned in the Vue.js docs:

Components are one of the most powerful features of Vue.js. They help you extend basic HTML elements to encapsulate reusable code.

Any advice would be appreciated, thanks!

5 likes
Raido's avatar

Did you solve this? I am facing the same question...

1 like
farindra's avatar

Maybe you should turn off all Vue require from laravel gulp

Try This: in resources.assets.js -> app.js

//Vue.component('example', require('./components/Example.vue'));

// const app = new Vue({
//     el: 'body'
// });

->bootstrap.js

//window.Vue = require('vue');
//require('vue-resource');

// Vue.http.interceptors.push((request, next) => {
//     request.headers['X-CSRF-TOKEN'] = Laravel.csrfToken;
//
//     next();
// });

in gulpfile.js

//require('laravel-elixir-vue');

rebuild gulp

then put your vue.js .etc on the page you want, and try to use your vue stuff,

I do not why laravel combine all vue components into one js? instead will make the application more slowly when first loading, or is there a way so that it can be done independently by the page we want to use?

1 like
dealer's avatar

@haakym ... just incase you still need an answer to your question, simply try this option:

keeping everything in the component. This option worked for me ...

<template>
.....
</template>

<script>
    export default {
        data : function(){
            return { test: "test"};
        }
    
    }
</script>
3 likes
georaldc's avatar

It doesn't look like the question was answered. From what I understand, the default setup of 5.3 + vue + the single entry point equals a Single Page Application. To support what @haakym needs (and what I require too at the moment), one needs to create multiple entry points. It seems to be possible with webpack via configuration (https://webpack.github.io/docs/multiple-entry-points.html), but it doesn't look like elixir allows it (or well, I haven't figured out how to do it there yet).

EDIT: Here is what I do right now: I register components in the app.js file based on the current pathname value. This way, I get unique components in the pages I need them to appear and not have other code like component styles leaking into other pages. Seems to work well for me:

var components = {};

if (location.pathname === "/") {
    components = {
        foo: require('./components/Foo.vue')
    };
} else if (location.pathname.substr(0, 4) === '/foobar') {
    components = {
        bar: require('./components/Bar.vue'),
        foobar: require('./components/FooBar.vue'),
    };
}

const app = new Vue({
    el: '#app',
    components: components
});

1 like
ricardoarg's avatar

does it goes against speed / performance / memory usage / something else to use the way that uses the original app.js:

Vue.component('example', require('./components/Examplevue'));
Vue.component('example2', require('./components/Examplevue2'));
Vue.component('example3', require('./components/Examplevue3'));
Vue.component('example4', require('./components/Examplevue4'));
//and so on a couple dozens of components

const app = new Vue({
    el: '#app',
});

instead of require-ing like @georaldc is using in his edit?

georaldc's avatar

@ricardoarg That is fine if those components are actual global components that need to be used everytime you use vue in your site (eg. a login/logout component that appears on every page). As for me, I have a typical multi page website where some pages would have components unique only to those pages (a grid component for instance to render tabular data). I could globally require them like in your example, but I noticed that means that the code would get applied to pages that do not need these page specific components. Styles for instance found in registered components' VUE files would still be rendered even if said components were never used in that page.

If there's a better way of achieving this, then I'm all for it. For now, I either check a part of the pathname (or do a regex check to be more granular) to know when to require certain components that page is expecting.

1 like
clay's avatar

Just go to resources\assets\js open app.js and bootstrap.js, comment out any lines that pertain to vue. Then drop it in from a cdn and use however you want.

ricardoarg's avatar

nice, thanks for your insight!

as a matter of fact me too have lots of components that are used in 1 or 2 pages of a multi-page app. So I'll see to implement your way of requiring.

as a side-note, how do you pass data to your FooBar component ? Do you load all the needed data async with ajax? Do you have some <script>window.mydata = {....}</script> and get it in the ready() method of the component? via props with json_encode($my_php_var) ?

georaldc's avatar

At the moment, I haven't had the need to pass anything to my components yet but if I needed to, I probably would use props so that I could easily send stuff to them from my blade views. If my component needs to render data from the server (tabular data again for instance), I defer loading to an ajax call.

@clay wouldn't I lose out the benefits of just doing a "npm run dev/prod" call while developing out of the box, to have elixir handling compilation of my vue files? It seems easier to just have a single <script src="/js/app.js"></script>in my layout file

clay's avatar

I actually just use the default implementation with Elixir but instead of global components, I have one parent component, then I just add the components I need as child components. As to your question, to load data to a component, I have a data property on my component that is set via an ajax call in the 'mounted' method of the component or for data that is needed sitewide from the backend, I may have a global object available to my javascript. It depends.

jbruni's avatar

It worths mentioning that it is the Artisan command "make:auth" which brings the bundled Vue + Bootstrap assets into usage.

php artisan make:auth

Please check documentation here:

While it seems unrelated to Vue + Elixir, it is this command which brings the "HomeController", the "home" view, the "app" layout, etc. These are the ones which make usage of the "app.js" and "app.css" we can find under assets and public folders, after a fresh install.

1 like

Please or to participate in this conversation.