#laravel #laravel-blade #tailwind-css #alpine.js
#laravel #laravel-блейд #попутный ветер-css #alpine.js
Вопрос:
Я пытаюсь создать свой собственный компонент переключения. Этот компонент должен вести себя как обычный <input type="checkbox" >
. До сих пор я создал следующее:
toggle.blade.php
@props([
'id' => 1
])
<div class="flex justify-center items-center">
<div {{ $attributes->whereStartsWith('class')->merge(['class' => 'relative rounded-full transition duration-200 ease-linear' ]) }}
:class="[ $refs.toggle{{ $id }}.checked ? 'bg-green-400' : 'bg-gray-400' ]">
<label for="toggle{{ $id }}"
class="absolute left-0 bg-white border-2 mb-2 w-1/2 h-full rounded-full transition transform duration-100 ease-linear cursor-pointer"
:class="[ $refs.toggle{{ $id }}.checked ? 'translate-x-full border-green-400' : 'translate-x-0 border-gray-400' ]"></label>
<input x-ref="toggle{{ $id }}" type="checkbox" id="toggle{{ $id }}" class="appearance-none w-full h-full active:outline-none focus:outline-none"
{{ $attributes }} x-init="console.log('test')" />
</div>
</div>
Как я это называю:
<div>
<x-inputs.toggle class="w-8 h-4" value="{{ $permission['id'] }}"
id="{{ $permission['id'] }}" x-model="permissions" /> <-- this one
<input class="form-checkbox" value="{{ $permission['id'] }}" type="checkbox" x-model="permissions">
</div>
Я хочу иметь возможность поместить x-model в свой компонент. Чтобы я мог использовать обычную двустороннюю привязку из ввода флажка.
Приведенный выше код работает, но потому, что ссылка (ввод) инициализируется позже, чем $refs
вызовы. Вызывая неправильные классы в переключателе, пока не будет нажат один из флажков / переключателей (ссылки обновлены), см. Изображение:
Обычно я бы просто предоставил компоненту x-данные и проверил, не переключен ли он и т.д. Но тогда я не могу использовать x-model, потому что модель не существует в свойстве x-data компонента.
Что я также пробовал, так это передавать значение x-model
в свойстве класса, например: :class="[ {{ $attirubtes->whereStartsWith('x-model')->first() ? ... : ... ]"
. Но это тоже не работает, потому что я передаю массив в флажок x-model, где alpine.js делает какие-то необычные вещи и правильно с этим справляется.
Есть идеи, как я могу решить эту проблему?
Заранее спасибо.
Ответ №1:
Вы почти на месте. Это немного сложно, не видя вашего x-data
, но используя refs
вы как бы проходите долгий путь, вместо того, чтобы использовать встроенную реактивность, поэтому вы видите отложенное обновление.
Я думаю, вы сказали, что ваша permissions
переменная является массивом. Если это так, вы можете получить имя переменной alpine и значение вашего флажка в блейд-компоненте и использовать их, чтобы определить, следует ли устанавливать флажок.
В блейд-компоненте
<?php
// Here we get the name of your alpine variable and the
// value for the toggle
$alpineVar = $attributes->whereStartsWith('x-model')->first();
$value = $attributes->whereStartsWith('value')->first();
// Here we build the javascript expression used to check
// our permissions array for the toggle value
$expression = "$alpineVar.includes('$value')";
?>
<div class="flex justify-center items-center">
<div
{{ $attributes->whereStartsWith('class')->merge(['class' => 'relative rounded-full transition duration-200 ease-linear' ]) }}
:class="[
{{ $expression }} ? 'bg-green-400' : 'bg-gray-400'
]">
<label
for="toggle{{ $id }}"
class="absolute left-0 bg-white border-2 mb-2 w-1/2 h-full rounded-full transition transform duration-100 ease-linear cursor-pointer"
:class="[
{{ $expression }} ? 'translate-x-full border-green-400' : 'translate-x-0 border-gray-400'
]"></label>
<input id="toggle{{ $id }}" type="checkbox" class="appearance-none w-full h-full active:outline-none focus:outline-none" {{ $attributes }} />
</div>
</div>
Здесь мы получаем имя переменной экземпляра AlpineJs из вашего x-model
атрибута и используем его для проверки наличия value
в массиве, чтобы мы могли переключаться между классами в элементах div
и label
.
На странице
<div
x-data="{
permissions: ['view','read','create']
}">
<x-inputs.toggle class="w-8 h-4" value="view" x-model="permissions" />
</div>
Я, очевидно, использую x-data
здесь пример экземпляра, поэтому настройте его в соответствии с вашими потребностями. Здесь мы передаем значение view
, найденное в permissions
объекте и связанное с x-model, чтобы дать нам необходимую реактивность.
Я надеюсь, что все имеет смысл и отвечает на ваш вопрос 👍🏼