How to import js libraries in laravel - blade template? - laravel

I want to import this library into my laravel project. I have run npm install vue-simple-lightbox and then in my blade template i have this code
#extends('layouts.app')
#section('content')
{{-- some html code --}}
<div class="row">
</div>
<div class="row">
<lightbox id="mylightbox" :images="images" :image_class="'img-responsive img-rounded'" :album_class=" 'my-album-class' " :options="options"></lightbox>
{{-- more html code --}}
</div>
#endsection
<style type="text/css">
.dropdown, .dropdown-menu {
width: 100%;
}
</style>
#section('scripts')
// import the library here?
<script type="text/javascript">
let app = new Vue({
el: '#app',
data() {
return {
images : [
{
src : 'https://cdn.rawgit.com/vrajroham/vrajroham.github.io/85d64ac5/imgs/img1.jpg',
title : 'Image 2'
},
{
src : 'https://cdn.rawgit.com/vrajroham/vrajroham.github.io/85d64ac5/imgs/img2.jpg',
title : 'Image 3'
},
{
src : 'https://cdn.rawgit.com/vrajroham/vrajroham.github.io/85d64ac5/imgs/img3.jpg',
title : ''
},
{
src : 'https://cdn.rawgit.com/vrajroham/vrajroham.github.io/85d64ac5/imgs/img4.jpg',
title : ''
},
],
options : {
closeText : 'X'
}
};
},
mounted() {
},
});
</script>
#endsection
Where should i import the library? I tried to import it into app.js file using this code window.Lightbox = require('vue-simple-lightbox');, but then how do i use it? It seems the blade template have no idea what is 'lightbox'.
I am getting this error
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
What is the correct way of importing the library and then use it inside the blade template? Thanks!

Extract your js code to a single file, blade templates are not compiled and it wont work if you import it there.
So copy everything over to say, app.js, then include it via a script tag
Inside app.js you can import lightbox from 'vue-simple-lightbox'
Now, make sure you add it to your webpack.mix file through
.js('path/to/app.js', 'public/js/app.js')
That way the library will get compiled into the asset.
Now, regarding the VUE tempalte not finding the lightbox component.
You forgot to add the component part of the Vue instance:
import Lightbox from 'vue-simple-lightbox'
export default {
components: {
Lightbox //HERE
},
...

You can import the file directly from GitHub:
<script src="https://github.com/vrajroham/vue-simple-lightbox/blob/master/dist/vue-simple-lightbox.js"></script>

Related

Laravel, VueJS [Vue warn]: Unknown custom element: did you register the component correctly?

I'm not sure what I am missing, everything seems to be set up correctly:
app.js
window.Vue = require('vue');
import CategoriesDataTable from './components/categories/CategoriesDataTable.vue';
const app = new Vue({
el: '#app',
components : {
CategoriesDataTable,
},
});
CategoriesDataTable.vue:
<template>
<section class="table-container">
<table>
<thead></thead>
</table>
</section>
</template>
<script>
export default {
name : 'CategoriesDataTable',
data() {
return {}
}
}
</script>
<style>
</style>
test.blade.php
#extends('master')
#section('title', 'Add Category')
#section('app')
<CategoriesDataTable></CategoriesDataTable>
#endsection
Doubled checked the spelling but still get
app.js:37926 [Vue warn]: Unknown custom element: <categoriesdatatable> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
In your blade template you can try this:
<categories-data-table></categories-data-table>
Then execute npm run watch.
I faced the same problem , in my case i forget command :
Npm run watch

Laravel local vue component registration

I know I can register global components in the file located in resources/js/app.js.
I know when I do this I can use these component in any place (because they are global).
But I don't want that. I have a big application and different functionalities solved in different routes. So I don't want the whole components available in all my views.
How can I register locally the components I want to be available only in one view?
Thanks
Vue js register component in local:
step-1 ) storing the component object in a variable:
var demo = {
data: function() {
return {
message: 'This is a local components.'
};
},
template: `
<div>
<h1>Component: {{ message }}</h1>
</div>
`
};
Step-2 ) Add a component property with the components that we want to register locally.
new Vue({
el: '#app1',
components: { /*Here we have added property*/
'demo': demo
}
});
Step-3 ) Template
<div id="app1">
<demo></demo>
</div>
*Notice: This property should be an object and contain key-value pairs of tag names and configuration objects.
You can do it by importing the component in your parent vue component
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from '#/folder/ChildComponent'
export default {
components: {
ChildComponent
},
}
</script>
Here is the approach that I follow.
Create a new file in your components folder in resources/js/components/YourComponent.vue
<template>
<div>
<h2>My awesome component</h2>
</div>
</template>
<script>
export default {
}
</script>
And in the view where you want the component, you can import it like below
<template>
<div>
<h2>Import another component</h2>
<awesome-component></awesome-component>
</div>
</template>
<script>
import awesomeComponent from "./components/YourComponent.vue";
export default {
components: {
'awesome-component': awesomeComponent
}
}
</script>

How to use a Laravel Nova Component in a Custom Nova Tool

I'd like to use the same loader as Laravel Nova uses when it's components are loading. I can't get it to compile. It never recognizes where to load the LoadingCard component from. Any help would be appreciated.
<template>
<div>
<heading class="mb-6">Tax Calculator</heading>
<loading-card :loading="loading" class="card relative overflow-hidden w-1/3">
<div v-if="countries.length">
<!--Make form-->
</div>
</loading-card>
</div>
</template>
<script>
import LoadingCard from 'laravel-nova'
export default {
mounted() {
let vue = this;
Nova.request().get('/nova-vendor/tax-calculator/mount')
.then(response => {
vue.countries = response.data.countries;
vue.states = response.data.states;
});
},
}
</script>
<style>
/* Scoped Styles */
</style>
Figured it out. Apparently all the Nova built-in components are available globally. Didn't realize this. All I needed to do to get it to compile was remove the import statement. I modified the code as follows:
<template>
<div>
<heading class="mb-6">Tax Calculator</heading>
<loading-card :loading="loading" class="card relative overflow-hidden w-1/3">
<!--Make form-->
</loading-card>
</div>
</template>
<script>
export default {
mounted() {
let vue = this;
Nova.request().get('/nova-vendor/tax-calculator/mount')
.then(response => {
vue.countries = response.data.countries;
vue.states = response.data.states;
});
},
}
</script>
<style>
/* Scoped Styles */
</style>
For those looking for the list of all the global laravel nova vue components, you can find here:
nova/resources/js/components.js

Vuejs js for multiple pages, not for a single page application

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?
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>
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.
Name you main div the same as the file (fileName.php + assets/js/fileName.js).
Use #fileName' as yourel`
in blade use #{{ vue expressions }} to let Blade skip this and allow VueJS handle that.
Done. Good luck!

Laravel & vue.js - not rendering imported component

I'm starting to play around with vue.js on top of the laravel framework.
But im having trouble with rendering of a component which is imported.
My app.js (main entry point)
// app.js
var Vue = require('vue');
var Router = require('vue-router');
Vue.use(Router);
var router = new Router();
var ContractsOverview = Vue.extend({
template: '<p>contract page</p>'
});
var ContractDetail = Vue.extend({
template: '<p>detail page</p>'
});
import DashboardView from './app/components/DashboardView.vue';
router.map({
'/dashboard': {
component: DashboardView
},
'/contracts': {
component: ContractsOverview
},
'/contracts/:id': {
component: ContractDetail
}
});
var App = Vue.extend({
});
router.redirect({
'*': '/dashboard'
});
router.start(App, '#reminder-app');
This is my Dashboard component
(located at resources/assets/js/app/components/DashboardView.vue)
<template>
<section class="content-header">
<h1>
Dashboard
<small>Control panel</small>
</h1>
<ol class="breadcrumb">
<li><i class="fa fa-dashboard"></i> Home</li>
<li class="active">Dashboard</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<!-- .. some html -->
</section>
</template>
<script>
export default {}
</script>
and in my master layout i have a normal blade template with the <router-view></router-view> tag at one point.
At the end i build my app.js with laravels elixir and the following gulpfile:
var elixir = require('laravel-elixir');
elixir.config.js.browserify.transformers.push({
name: 'vueify',
options: {}
});
elixir(function(mix) {
mix.less(['bootstrap.less', 'app.less']);
mix.scripts([
'admin-lte/plugins/jQuery/jQuery-2.1.4.min.js',
'admin-lte/plugins/jQueryUI/jquery-ui-1.10.3.min.js',
// some more scripts,
'admin-lte/app.js',
'admin-lte/pages/dashboard.js',
'admin-lte/demo.js'
], 'public/js/ui.js');
mix.browserify('app.js');
});
When i go to the page the routes /contracts and contracts/:id the templates are shown as expected.
But when i go the /dashboard route, i dont see anything (besides the layout).
Am I missing something? Did I forget to import or require something?
Ok, i spent at least 4 hours finding my error, but it was just a simple typo somewhere.
But if you run gulp inside the virtual machine (homestead), you dont get the same output as if you run gulp locally. On my local machine it told what went wrong.
Also gulp watch doesn't work on the homestead machine.

Resources