laravel 5.4 Vue Component not workng - php

I have a Chat-User.vue file in components like
<template lang="html">
<div class="chat-user">
×
<h1>Users in Chat Room</h1>
<hr />
Number of users = {{ usersInRoom.length }}
<div class="users" style="overflow: hidden;">
<div class="col-sm-3 w3-margin-bottom" v-for="userInRoom in usersInRoom" style="overflow: hidden;">
<div class="u-1">
<img :src="userInRoom.profile" width="50" height="50">
</div>
<div class="u-2">
{{ userInRoom.name }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['usersInRoom']
}
</script>
My app.js file
Vue.component('chat-user', require('./components/Chat-User.vue'));
const app = new Vue({
el: '#app',
data: {
usersInRoom: []
},
});
and the indx.blade.php file
<div id="app">
<chat-user v-bind:usersInRoom="usersInRoom"></chat-user>
</div>
In usersInRoom variable it will add data's automatically.
But when I look the browser I cannot see any thing in the place of <chat-user></chat-user>, Just only <!---->.
I think it was commented out by vue for some reason. I tried removing all {{ usersInRoom }} and then I can see the other things like <h1>Users in Chat Room</h1> and the <hr>.
if I am not wrong The component file is not recognizing any variable like usersInRoom, when I have a variable like that.
Please some one tell me how to fix this problem.

Html directives are case insensitive, in the documentation Vue mentions that you need to use kebab-case in binding props.
Try <chat-user v-bind:users-in-room="usersInRoom"></chat-user> Which will bind to the usersInRoom prop.

you cant use camel case for props. u need to to use kebab case.
and binding from vue 1, you can remove the "v-bind" string and just directly start at :
<chat-user :users-in-room="usersInRoom"></chat-user>

Related

How to show database info in Laravel Blade with VUE

Sorry for the next question, Im really new on VUE.
I have a button on my blade, when I do it click I want to retrieve the info of the customer depend of the ID that get on my controller, I get the ID #3 and I click on CUSTOMER INFO Button, I want to see the info of this customer from the database
This is my function on my Controller CustomersController.php
public function showcustomers($idcustomer)
{
$Customers = Customers::find($idcustomer);
return view('showcustomer',
['Customers' => $Customers]);
}
And this is my button on Blade showcustomer.blade.php :
<div id="cita">
<div class="container-fluid">
<div class="container">
<div class="row">
<div class="col-xs-6">
<button v-on:click="showinfo = !showinfo" type="button" class="w3-btn w3-blue" style="width:100%">CUSTOMER INFO</button>
</div>
</div>
</div>
</div>
<br/><br/>
<div class="container align-content-between">
<div class="row text-center">
<div class="col-md-12 col-xl-12">
<information v-if="!showinfo"></information>
</div>
</div>
</div>
</div>
My app.js
Vue.component('information', require('./components/information.vue').default);
var app = new Vue({
el: '#cita',
data: {
showinfo: true,
}
});
And finally my information.vue
<template>
<div id="information">
<h4>Information {{ Customers.name }}</h4>
</div>
</template>
<script>
export default {
name: "information"
}
</script>
<style scoped>
</style>
Standard way of doing that is you will be implementing an ajax request where your front-end or Vue will fetch the necessary information from back-end via ajax request.
Another way of achieving that is you will be using properties or attributes in VUE
from your information.vue add a props maybe customerName or orderId or both
<template>
<div id="information">
<h4>Information {{ customerName }}</h4>
<h4>ID {{ orderID }}</h4>
</div>
</template>
<script>
export default {
props:["customerName","orderID"],
name: "information"
}
</script>
<style scoped>
</style>
in you showcustomer.blade.php you can pass the data from php to your vue by adding attributes based on the property name declared on you vue template
<information customer-name="John Mahu" order-id="0099812-ABC" v-if="!showinfo"></information>
or populate from your PHP variable
<information customer-name="{{ $Customers->customer_name }}" order-id="{$Customers->some_order_id}" v-if="!showinfo"></information>
Read more about vue props
https://v2.vuejs.org/v2/guide/components-props.html

How to make Wire:loading for every components

I use Livewire, how can I put a loder on all pages but call it once
nav.blade.php
<html>
<head>
#livewireStyles
</head>
<body>
<livewire:layouts.header/>
{{ $slot }}
#livewireScripts
</body>
</html>
header.blade.php
<div>
<div class="spinner" wire:loading></div>
</div>
welcome.blade.php
<div>
<input wire:model="search" placeholder="Search">
</div>
When I write things in the input, it doesn't show the loder.
I want to call this loder only once and work on every page
As of today wire:loading only works in the scope of a single livewire component. There is no wire:loading.all.
Simple solution: create a blade component and name it e.g. x-loading
<div class="page-loading" wire:loading>
Loading...
</div>
Style the component such that it appears e.g. in the bottom right corner of the page. You might want to use position: absolute.
Place this component in the view of every livewire component you want to show the loading indicator for.
This solution comes with two drawbacks. First, if you try to position the loading indiator in a container that has absolute position (like a modal), it wont have the same position as you intended. Second, the loading blade component will be in every livewire component.
I just tested a more elegant solution. For this you have to use livewire js hooks: https://laravel-livewire.com/docs/2.x/reference
<script>
window.onload = function() {
Livewire.hook('message.sent', () => {
window.dispatchEvent(
new CustomEvent('loading', { detail: { loading: true }})
);
})
Livewire.hook('message.processed', (message, component) => {
window.dispatchEvent(
new CustomEvent('loading', { detail: { loading: false }})
);
})
}
</script>
<div
x-data="{ loading: false }"
x-show="loading"
#loading.window="loading = $event.detail.loading"
class="absolute z-50 bottom-20 right-20"
>
This is taking way too long...
</div>
Place this this code e.g. in your app layout.

Registering a 2nd component? Vue.js Laravel6

I have created a fresh Laravel6 project to work out how to register components...
I have cloned ExampleComponent.vue to ExampleComponent2.vue
// ExampleComponent2.vue
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example2 Component</div>
<div class="card-body">
I'm an example2 component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component2 mounted.')
}
}
</script>
// app.js
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('example-component2', require('./components/ExampleComponent2.vue').default);
// login.blade.php
- I have placed this under the closing tag and #endsection to test on the login page...
<example-component2></example-component2>
I have run "npm run watch" in command line and there are no error messages...
When I load the login route, I open the console to see this error message?
[Vue warn]: Unknown custom element: - did you
register the component correctly? For recursive components, make sure
to provide the "name" option.
(found in )
How do I register extra components???
// login.blade.php - I have placed this under the closing tag and #endsection to test on the login page...
You need an element with the id that you defined in your js/app.js:
const app = new Vue({
el: '#app', // you need an element with id="app". Your vue component will replace this
});
Then put your component inside that element.
//login.blade.php
#extends('layouts.authentication')
#section('content')
<div id="app">
<example-component2/>
</div>
#endsection

Blade - (Sage 9) probem when multiple #yield/#section

We are new to sage9 / Blade framework and we are trying to create a template logic with ACF. Everything was working well with 1 block but when we add more block the first 1 echoes 2-3 times.
Here's how we did it:
We use the default layouts.app from sage9:
web/app/themes/[theme-name]/resources/views/layouts/app.blade.php
...
<div class="vy_main uk-offcanvas-content">
<header>
#yield('dispatch_banner')
</header>
<div class="wrap container" role="document">
<div class="content">
<main class="main">
#yield('dispatch') //The one we currently working on
</main>
...
In the layout we are calling #yield('dispatch'). Inside page.blade.php we are extending the layouts and we add the dispatch section.
web/app/themes/[theme-name]/resources/views/page.blade.php
#extends('layouts.app')
#section('dispatch_banner')
#layouts('banners')
{!! App::banners() !!}
#endlayouts
#endsection
#section('dispatch')
#layouts('sections')
{!! App::sections() !!} //This call a controller where we can select the correct section to display.
#endlayouts
#endsection
Inside the controller,
web/app/themes/[theme-name]/app/Controllers/App.php we return a template to use and passing configurations/variables to use. :
public static function sections(){
...
$return .= \App\template('sections.'.$sections, $config);
}
return $return;
...
}
We create a standard block. This block include by the dispatcher :
web/app/themes/[theme-name]/resources/views/sections/std.blade.php
Inside this template, we created a new layouts "base", because all sections will have the same base structure, we extend this base inside the template and put a section content in it like so:
web/app/themes/[theme-name]/resources/views/sections/std.blade.php
#extends('layouts.base')
#section('section-content')
#if ($image)
<div class="uk-grid uk-flex-middle" data-uk-grid>
<div class="{!! $class_image !!}">
<img src="{!! $image['url'] !!}" alt="{!! $image['alt'] !!}">
</div>
<div class="{!! $class_content !!}">
#endif
<div class="{!! $content_class_content !!}">
#layouts('content')
{!! App::content() !!}
#endlayouts
</div>
#if ($image)
</div>
</div>
#endif
#endsection
And here the layout
web/app/themes/[theme-name]/resources/views/layouts/base.blade.php
<section {{ (( $section_id )?'id='.$section_id:'') }} class="{!! $class_section !!}">
#if($has_container)
<div class="uk-container uk-container-{!! $container !!}" data-uk-scrollspy="cls: uk-animation-fade;">
#yield('section-content')
</div>
#else
#yield('section-content')
#endif
</section>
As I said, everything was working fine with 1 block but as soon as we add a second block the data just keep repeating BUT only the #yield('section-content') from the base, the variables use inside the layout aren't repeating.
Here what we have in the html from :
<section {{ (( $section_id )?'id='.$section_id:'') }} class="{!! $class_section !!}">
We get :
<section class="uk-section vy_std uk-section-primary uk-section-xlarge">
<section class="uk-section vy_accordion uk-section-transparant">
<section class="uk-section vy_std uk-section-transparant">
Where is the problem with our logic and we the content from #yield('section-content') keep repeating instead of using the right data send from the controller?
If this can help I can send all the code from the controller, it's not big but to me it's wasn't where the problem is so I cut this part out.
Thank for your time!
I manage to work this out by using components/slots instead of layouts. Now I get the base from a component like so:
#component('layouts.base', $config)
/*Section code*/
#endcomponent
And everything is working again!

Laravel - passing data from master blade to partial doesn't work for all views

I am trying to pass data from my master blade to the partial depending where it is open. This is part of my master blade:
<div id="main-section">
#section('topBar')
#include('customer.layouts.partials.top-bar')
#show
#section('header')
#include('customer.layouts.partials.header')
#show
#section('carousel')
#include('customer.layouts.partials.carousel', ['function' => 'drawer'])
#show
</div>
<div id="drawer">
<div id="item-detail">
</div>
<div id="item-detail-carousel">
#section('carousel')
#include('customer.layouts.partials.carousel', ['function' => 'itemDetail'])
#show
</div>
</div>
So, as you can see I am using customer.layouts.partials.carousel in two places.
I am receiving data in my partial like this:
<div class="swiper-container {{ $function }}">
<div class="swiper-wrapper">
#foreach($issues as $issue)
<div class="swiper-slide">
<img
src="/imagecache/large/{{ $issue->first()->image }}"
onclick="{{ $function }}(
'{{ $issue->first()->magazine->id }}',
'{{ $issue->first()->magazine->name }}',
'{{ $issue->first()->magazine->summary ?: '' }}',
'{{ $issue->first()->magazine->image ?: '' }}',
'{{ $issue->first()->image }}'
)"
>
</div>
#endforeach
</div>
</div>
Div #drawer is hidden first, has display:none, and it is shown on click on an image in the slider in the main-section. And then #drawer gets slides over the main-section. But when I inspect the elements in the chrome I see that both in the main-section and in the drawer section, data that was passed is drawer. The #drawer didn't get data ['function' => 'drawer'] as I thought it would.
How can I achieve that?
I think you're misunderstanding how the #section directive is meant to work.
For starters, you shouldn't have multiple #section directives with the same name (think of it like ids with HTML - there should only be one with that name). Also, if your not going to be extending files with #extend there isn't much point in using #section at all.
If you remove the #section directives from around your #include('...') then they should work fine.
Hope this helps!

Categories