I am developing a classic MPA webpage using Laravel and Blade templates. But in some of the pages, I would like to add some reactivity to improve the user experiencie, using the Vue framework for that.
So far so good, if I import Vue and JS code in a normal script
tag at the end of the corresponding blade templates, I get it done.
But my problem is that I need all the JS code to be minified and processed by webpack (Laravel Mix) so that javascript source is not exposed.
Any ideas? Thanks in advance.
If you ran the following artisan commands to install Vue in Laravel:
composer require laravel/ui
php artisan ui vue
your app.js file which comes standard with Laravel will have been updated automatically to import Vue. It will look something like this (but with comments):
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
const app = new Vue({
el: '#app',
});
So with that, you could begin creating Vue components for different sections of your website.
However, if your issue is that you want to have multiple different Vue instances throughout your application based on the page, you would begin by taking the same layout as the code block above (minus the bootstrap require statement) and choose a different element id for the new instance. Then you would create a new Javascript file to house the specific components/functions you desire and add them to your webpack.mix.js like this:
mix.js('resources/js/app.js', 'public/js') // old line
.js('resources/js/header/header.js', 'public/js') // additional line
then in your blade file, you would simply use the new script like so:
<script src="{{ asset('js/header.js') }}"></script>
Edit: Based on Comment
Probably the easiest way to pass the data from your blade file to the specific Vue instance would be to prop the data on the element the Vue instance is initiated one (comparable to propping a blade variable through to a Vue component as well). If this was your element:
const app = new Vue({
el: '#show-order',
});
You could prop the id of the order ($id needs passed from the controller/view)
<div id="show-order" order_id="{{ $id }}">
...
</div>
Then you set up the prop within the Vue instance:
const app = new Vue({
el: '#show-order',
props: ['order_id'],
});
and maybe used in a method like so:
const app = new Vue({
el: '#show-order',
props: ['order_id'],
methods: {
logMyProp: function() {
console.log(this.order_id);
}
}
});
Alternatively you could create a method within your instance that's responsible for calling a method that loads the data directly into the instance instead of passing the data from the controller => blade => vue component.
...
data: function() {
return {
order: {},
}
},
methods: {
loadMyData: function() {
let vm = this;
$.ajax({
url: '/orders/load/'
}).done(function(response) {
vm.order = response;
});
}
},
...