Este é uma aplicação Laravel utilizando a "extensão" Livewire. Uma extensão reativa, que agiliza o desenvolvimento
com componentes reativo "sem" o uso de javascript (Existe o javascript, mas não precisamos se preocupar com desenvolvimento).
Com livewire temos componentes responsivos e juntamente com o blade, temos uma ferramenta poderosa. Componentes que podemos atualizar sem precisar atualizar toda página de forma fácil e rápida.
- listagem de todas atividades Criação de compoenente
todoe busca de atividades porqueryewhenpara filtro e messagem de listagem vazia caso não tenha. - Filtro das atividades por
pendenteseconcluídasCriação de propriedadefiltercom statusall, pending, donepara querywhen. - Ordenação da listagem Utilização de
orderByporcheckedde atividades. Checkcom input da atividade concluída Criação de input do typocheckboxpara concluir atividade com novo componenteitemcom metodo updatedTodo da propriedade PropriedadeTodo $todo.- Reoordenação da listagem ao check da atividade Utilização de
eventlivewire no compoenteItemque vai aosalvarfazer orefreshna listagem do componentTodopelo eventoemitTo e listeners. - Creação de atividade A criação da atividade irá receber via
clicko titulo da atividade e refresh na listatodo. - Exclusão da atividade Uma deleção básica e refresh na lista
todo. - No frontend: Layout responsivo e mode dark usando
Tailwindcss.
Na versão 2.0 do app, além do layout novo, foi adicionado propriedades computadas do livewire, autorizações de usuários
para suas atividades, autenticação básica de login/logout para demonstração do que um usuário pode visualizar e interagir no app e por
fim notificações para cada ação.
- Autenticação de usuário Criação demonstrativa de usuário direto pelo id.
- Politicas de Autenticação de usuário Usuários só podem criar, editar e deletar se estiverem logados.
- Autorização de ações Usuário não pode visualizar a deleção da atividade se a atividade não foi criada por ele.
- Negação de ações Usuário não pode editar atividade que não foi criada por ele.
- Notificações Criar notificações na tela para ações.
- Parametros da url Criar parametros nos filtro da URL para um histórico na navegação.
- Php
8.2 - Laravel
9.52.5[Projeto laravel] composer create-project laravel/laravel name-project - Livewire
2.12[Livewire] composer require livewire/livewire - laravel debugbar
3.8[Debugbar] composer require barryvdh/laravel-debugbar --dev - Remixicon
2.5.0Docs - Tailwindcss
3.3.3[Tailwindcss] npm install -D tailwindcss postcss autoprefixer- Configuração do framework esta neste link Install Tailwind CSS with Laravel
- Alpine jS
2.8.2Docs
php artisan serve --port=8000[inicializando servidor]php artisan livewire:make todo[Criando componente todo]php artisan make:model Todo -m[Criado a tabela modelo para add propriedades]- checked boolean nullable false
- title string
php artisan make:factory TodoFactory --model=Todo[Criado a migration para tabela no banco]- checked => $this->faker->boolean
- title => $this->faker->sentence
php artisan migrate --seed[Criado a migration de todas tabelas no banco e seed populando dados fakes]- Criação do componentes de interação: A ideia é trabalhar com cada
componente livewirede modo separado e não no proprio componentetodo, para assim não ter um componente com muitas responsabilidades e desta forma cada componente tera a sua.php artisan livewire:make todo.item[Criando componente todo item] | Componente que terá a responsabilidade de realizar o checked da atividade.php artisan livewire:make todo.create[Criando componente todo create] | Componente que terá a responsabilidade de criar componente com seu titulo.php artisan livewire:make todo.delete[Criando componente todo delete] | Componente que terá a responsabilidade de deletar a tividade.
View blade *todo* - listagem
{{-- LIST TASKS --}}
@if(count($todos) > 0)
@foreach($todos as $todo)
<livewire:todo.item :todo="$todo" :key="$todo->id" />
@endforeach
@else
<div class="flex justify-center rounded-lg font-medium tracking-wide text-red-500 text-xs mt-6 mb-6">
<div>
Não existem tarefas registradas!
</div>
</div>
@endif
| Diretiva | Explicação |
|---|---|
@foreach($todos as $todo) |
Recebendo a listagem com todas atividades ou por filtro no componente todo com um foreach para mostrar cada um. |
<livewire:todo.item :todo="$todo" :key="$todo->id" /> |
Passando cada atividade para componente view item e para que cada tenha sua identificação para livewire, passamos o key do ID. |
View blade *create* - Como passar dados de input para metodo com click Enter.
<input wire:model.defer="title" wire:keydown.enter="save"
Controller *create*
public string $title ='';
public function save()
{
$this->validate(['title' => ['required', 'min:3']],
[
'title.required' => 'Descrição é obrigatória!',
'title.min'=> 'Mínimo de 3 letras, por favor!'
]);
Todo::create(['title' => $this->title]);
$this->reset('title');
$this->emitTo(\App\Http\Livewire\Todo::class, 'todo::created');
}
Controller *Todo*
protected $listeners = [
'todo::updated' => '$refresh',
'todo::created' => '$refresh',
'todo::deleted' => '$refresh'
];
| Classe | Explicação importantes |
|---|---|
validate(['title' => ['required', 'min:3']] |
* Validação de criação e mensagens personalizadas de cada tipo* |
$this->emitTo |
EmitTo é uma função que avisa um componente de alguma atividade realizada e apartir disso podemos por exemplo, realizar refresh |
- Estruturação de
migrateemodelda Todo.- Adição da foreignId
$table->foreignIdFor(\App\Models\User::class)->nullable(); - Adição da fillable user id
protected $fillable = ['title', 'checked', 'user_id'] - Metodo belongsTo da Todo pegar o usuário dono.
- Adição da foreignId
public function user(){
return $this->belongsTo(User::class);
}
- Criação de
factories e seederspara popular banco.- Exemplo
User::updateOrCreate([
'name'=> 'Rafael Blum',
'email'=> '[email protected]',
'email_verified_at' => now(),
'password'=> Hash::make('123'),
'remember_token' => Str::random(10),
]);
User::updateOrCreate([
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
]);
Todo::updateOrCreate([
'checked' => fake()->boolean,
'user_id' => User::where('email', '[email protected]')->first()->id,
'title' => fake()->sentence
]);
-
Criação de politica todo.
php artisan make:policy TodoPolicy --model=Todo[Criando politica] | Cria a policy e com o--model=Todocria todos metodos.
-
A criação de
notificaçõesseram acessados direto pelo componente que iráiniciar um eventoe assendo as props de componente do blade.
$this->emit('notifications', [
'type' => 'error',
'message' => 'Você precisa se logar para criar atividade'
]);
- Metodo da classe Notifications
protected $listeners = ['notifications'=>'notify'];
public function notify($props)
{
$this->message = $props['message'];
$this->type = $props['type'];
}
- view livewire e componente x-blade
<x-notification :type="$type">
{!! $message !!}
</x-notification>
@props([
'type'
])
<div {{$attributes->class([
'w-80 text-center text-sm mb-2 font-semibold tracking-wide cursor-pointer',
'text-yellow-500' => $type == 'warning',
'text-red-500' => $type == 'error',
'text-green-500' => $type == 'success',
'text-indigo-500' => $type == 'info',
])}} >
{{$slot}}
</div>
- Autorizações de ações.
- Atraves da Politica criada da todo, cada metodo ira retornar e verificar se o user id do user logado é igual ao id do user_id da tabela Todo.
return $user->is($todo->user);- Na classe Delete, por exemplo.
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use AuthorizesRequests;
$this->authorize('delete', $this->todo);
- Outra forma de autorização é utilizando o
can()
if(!auth()->check() || !auth()->user()->can('update', $this->todo)){
$this->emit('notifications', [
'type' => "error",
'message' => "Você não pode finalizar a atividade <br> {$this->todo->title}"
]);
return;
}
- Nas views podemos também usar o @can()
- Aqui se não é sua atividade, você não terá acesso a visualização do componente.
@can('update', $todo)
...
@endcan
- 👇🏼 [[email protected]]
