25

I need to build an application using laravel 5.3 and vuejs 2, because I need to use two-way binding rather than use jquery.

I need to set up the views with blade templates. Then, I need to use vuejs in each page as mentioned below.

resources/asserts/js/components/List.vue

<script>
    const panel = new Vue({
        el: '#list-panel',
        name: 'list',
        data: {               
           message: 'Test message'
        },
        methods: {
            setMessage: function(){
                this.message = 'New message';
            }
        }
   })
</script>

resources/asserts/views/post/index.blade.php

<div id="panel" class="panel panel-default">
    <div class="panel-heading">Posts</div>

    <div class="panel-body">
       <p>{{ message }}</p>
       <button v-on:click="setMessage">SET</button>
    </div>
</div>

There is Add.vue to create.blade.php etc... In Add.vue el: '#add-panel'

This is my app.js. I already commented default code like follows.

Vue.component('list', require('./components/List.vue'));
Vue.component('add', require('./components/Add.vue'));

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

I hardly checked most of documentations and tutorials. But they use a single js file. They use components for small elements with template, not only js.

Is it possible to use vuejs this way? Do I need to use app.js. What is the best way to do this?

LeCodex
  • 1,636
  • 14
  • 20
Dinuka Thilanga
  • 4,220
  • 10
  • 56
  • 93
  • I'm not quite sure about your problem, however it is not meant to only create single page applications using vue. By default you do not even get the vue router. I'd suggest to simply define an inline componenet (usually a "home" component) in your blade layout file. You register your vue to an outer element (body or #app). All the other components are simply added as your already did using Vue.component. You can then define your blade templates and simply use everything of vue inside. – Frnak Jan 09 '17 at 07:42

2 Answers2

40

If you want to sprinkle a bit of vuejs within your blade files you have basically two options:

Option #1

Declare global Vue components

Example

// in laravel built in app.js file

Vue.component('foo', require('./components/Foo.vue'));
Vue.component('bar', require('./components/Bar.vue'));

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

create a main layout file where the root div has an id of #app

// layout.blade.php

<html>
  <header></header>
  <body>
    <div id="app">
      @yield('content')
    </div>
  </body>
</html>

Finally in your views:

//some-view.blade.php

@extends('layout')

@section('content')
 <foo :prop="{{ $someVarFromController }}"></foo>
@endsection

Option #2

This is what I am currently using, and gives me more flexibility actually

// in laravel built in app.js file

const app = new Vue({
    el: '#app',
    components: {
      Foo: require('./components/Foo.vue'),
      Bar: require('./components/Bar.vue')
    }
});

In the layout file you will be using vuejs dynamic components

<html>
  <header></header>
  <body>
    <div id="app">
      @if (isset($component))
        <component :is={{ $component }} inline-template>
      @endif

         @yield('content')

     @if (isset($component))
       </component>
     @endif
    </div>
  </body>
</html>

In your views:

//some-view.blade.php

@extends('layout', ['component' => 'foo'])

@section('content')
   // all the vue stuff available in blade
   // don't forget to use the @ symbol every time you don't want blade to parse the expression.
  // Example: @{{ some.vue.propertie }}
@endsection

And finally you can create the vue components like you always would

// resources/assets/js/components/foo.vue

<script>
export default {
 // the component
}
</script>
Helder Lucas
  • 3,273
  • 2
  • 21
  • 26
  • 1
    Option 2 seems an interesting approach.. specially for multi-page applications. However, my concern is ,if I have 50 components in my app I would end up loading all those in app.js even when i dont need them ... I was trying to find something that could be more dynamic where components could load on demand – Prakhar Jun 09 '17 at 15:45
  • 3
    To solve that you can declare your components in an async way like so: `Vue.component('my-component', () => import('./my-component'))`. See it in more detail at: http://vuejs.org/v2/guide/components.html#Async-Components – Helder Lucas Jun 09 '17 at 21:25
  • What about SEO in this case? – general666 Nov 24 '19 at 11:10
  • do we need to use the route declaration of VueJS in a file i.e. `router.js` and import it in `app.js` as we do for a SPA (Single Page application) ? – Istiaque Ahmed Dec 10 '19 at 20:16
  • Regarding option 2: `@extends('layout', ['component' => 'foo'])` - how can the Laravel blade get the `foo` variable here ? – Istiaque Ahmed Dec 11 '19 at 15:59
  • I'm getting an error `Property or method "[component name]" is not defined on the instance but referenced during render.` The [component name] is what is set as the `@extends('layout', ['component' => 'componentname`])`. Any ideas? – xslibx May 28 '20 at 21:22
  • @xslibx did you register your component? `Vue.component('componentname', Component...)` ? – Helder Lucas May 31 '20 at 14:08
15
  1. Create your 'app' for every page in seperate JS files. Good practice would be using the same name as page name to get it clear where it belongs.
  2. Name you main div the same as the file (fileName.php + assets/js/fileName.js).
  3. Use #fileName' as yourel`
  4. in blade use @{{ vue expressions }} to let Blade skip this and allow VueJS handle that.

Done. Good luck!

Marek Urbanowicz
  • 12,659
  • 16
  • 62
  • 87
  • 2
    You are essentially creating a new instance of Vue for every page. right? – Jeffrey Jun 29 '17 at 01:21
  • @Pyol7 Yes, that's what he's describing. – Mihai Sep 26 '17 at 18:58
  • 1
    So what will the `app.js` file contain ? Can you elaborate it with a folder structure with files ? – Istiaque Ahmed Dec 10 '19 at 19:54
  • can you answer this question with the related topic : https://stackoverflow.com/questions/59289548/laravel-vuejs-building-multi-page-app-without-resorting-to-single-page-applicat ? – Istiaque Ahmed Dec 11 '19 at 17:51
  • take care that this is not best practice and you will run into issues since this will create a new vue instance for every page. With this setup you'll not be able to use vuex store correctly, since the store cannot be shared across vue instances. – leachim Sep 06 '21 at 12:30