Check out the following casts from Jeffrey: https://laracasts.com/series/learning-vue-step-by-step
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!
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.
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?
@ejdelmonico Thanks for your reply. So are you saying that all interactions with Vue.js should be via components?
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
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!
Did you solve this? I am facing the same question...
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?
Did you solve this? I am facing the same question...
There's a response to my question here if you're interested: http://stackoverflow.com/questions/39708680/using-vue-js-in-laravel-5-3
@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>
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
});
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?
@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.
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.
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) ?
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
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.
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.
Here are the relevant files:
-
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Console/stubs/make/views/layouts/app.stub (check lines 14 and 85)
-
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Console/MakeAuthCommand.php (the
make:authcommand source code) -
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Console/stubs/make/views/home.stub (the layout being used)
-
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Console/stubs/make/controllers/HomeController.stub (the
homeview being used) -
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Console/stubs/make/routes.stub (the
homeroute)
It is explained in this episode: https://laracasts.com/series/learning-vue-step-by-step/episodes/10
Please or to participate in this conversation.