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 by using gulp/elixir, 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 or can I use generated app.js?
Am I not supposed to do it this way, 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 - you can use it in more than one place. 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!
vue component is there, so basically, Laravel provides VueJS support out of the box. However, we can use other JS frameworks like ReactJS or AngularJS. This component is required in the external JS file called app.
On the Vue side, we'll make use of components, templates, and root elements, and more. We will use PHP to generate the form we need, as well as to handle form processing, in addition to making use of the substr_count() function to provide the data we need. You might also like how to use vuejs in laravel as well.
I'd leave Laravel the way it comes, with Webpack. This gives you the ability to add some good Webpack configuration. Plus gulp watch
works inside the Homestead vagrant VM now since it will be using Webpack to watch the file changes. And also check out async components.
Now on to your question regarding separate Vue instances per page...let's start with app.js...
App.js
When you first install Laravel 5.3, you'll find an app.js
entry point. Let's comment out the main Vue instance:
resources/assets/js/app.js
/** * First we will load all of this project's JavaScript dependencies which * include Vue and Vue Resource. This gives a great starting point for * building robust, powerful web applications using Vue and Laravel. */ require('./bootstrap'); /** * Next, we will create a fresh Vue application instance and attach it to * the page. Then, you may begin adding components to this application * or customize the JavaScript scaffolding to fit your unique needs. */ Vue.component('example', require('./components/Example.vue')); // Let's comment this out, each page will be its own main Vue instance. // // const app = new Vue({ // el: '#app' // });
The app.js
file still remains a place to for global stuff, so components added here are available (such as the example
component seen above) to any page script that includes it.
Welcome Page Script
Now let's create a script that represents a Welcome Page:
resources/assets/js/pages/welcome.js
require('../app') import Greeting from '../components/Greeting.vue' var app = new Vue({ name: 'App', el: '#app', components: { Greeting }, data: { test: 'This is from the welcome page component' } })
Blog Page Script
Now let's create another script that represents a Blog Page:
resources/assets/js/pages/blog.js
require('../app') import Greeting from '../components/Greeting.vue' var app = new Vue({ name: 'App', el: '#app', components: { Greeting }, data: { test: 'This is from the blog page component' } })
Greeting Component
resources/assets/js/components/Greeting.vue
<template> <div class="greeting"> {{ message }} </div> </template> <script> export default { name: 'Greeting', data: () => { return { message: 'This is greeting component' } } } </script>
Welcome Blade View
Let's update the welcome blade view that ships with Laravel:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> </head> <body> <div id="app"> <example></example> @{{ pageMessage }} <greeting></greeting> </div> <script src="/js/welcome.js"></script> </body> </html>
The idea would be the same for the blog view.
Elixir
Now bring it all together in your gulp file using Elixir's ability to merge Webpack config options with its own (read more about that here):
gulpfile.js
const elixir = require('laravel-elixir'); require('laravel-elixir-vue-2'); /* |-------------------------------------------------------------------------- | Elixir Asset Management |-------------------------------------------------------------------------- | | Elixir provides a clean, fluent API for defining some basic Gulp tasks | for your Laravel application. By default, we are compiling the Sass | file for our application, as well as publishing vendor resources. | */ elixir(mix => { var config = elixir.webpack.mergeConfig({ entry: { welcome: './resources/assets/js/pages/welcome.js', blog: './resources/assets/js/pages/blog.js' }, output: { filename: '[name].js' // Template based on keys in entry above } }); mix.sass('app.scss') .webpack('app.js', null, null, null, config); });
Run gulp
or gulp watch
and you'll see both welcome.js
and blog.js
published.
Thoughts
I'm currently going the SPA route when it comes to "web apps" and just using Laravel as the backend API (or any other language/framework). I've seen some examples where Vue SPA is built in Laravel, but I really think it should be a completely seperate repo/project, independent of the backend. There's no Laravel/PHP templating views involved in an SPA, so build out the SPA separately. BTW, the SPA would have "page" components (which are usually called by VueRouter and of course would be made up of more nested components...see my example project link below).
However, for the "web site" I think Laravel is still a good choice for serving blade views and no need to go SPA for that. You can do what I've described in this answer. Also, you can connect your website to your webapp. On your website, you would have a "login" link that will take a user from the website to the webapp SPA to login. Your website remains SEO friendly (although there is good proof that Google is seeing content on SPA javascript sites as well).
For a look at an SPA approach, I've put up an example in Vue 2.0 here: https://github.com/prograhammer/example-vue-project (it works great, but still in progress).
Edit:
You may want to also checkout the Commons Chunk Plugin. This way browsers can cache some shared module dependencies separately. Webpack automatically can pull out shared imported dependencies and put them in a separate file. So that you have a both a common.js
(shared stuff) and a welcome.js
on a page. Then on another page you would again have common.js
and blog.js
and the browser can reuse the cached common.js
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With