Как я могу создать динамические общедоступные свойства и данные через родительский компонент для дочернего компонента в livewire / laravel?

#php #laravel #laravel-livewire

#php #laravel #laravel-livewire

Вопрос:

В приложении Laravel 8 у меня есть два компонента. Input.php и Form.php

Input.php

 <?php

namespace AppHttpLivewireGeneral;

use LivewireComponent;

class Input extends Component
{
    public $name;
    public $model;
    public $label;

    public function render()
    {
        return view('livewire.general.input');
    }
}
  

input.blade.php

 <div class="mt-3">
    <label
        for="{{ $name }}"
        class="sr-only"
    >
        $label
    </label>
    <input
        wire:model="{{ $model }}"
        id="{{ $name }}"
        placeholder="{{ $label }}"
        autocomplete="off"
        class="w-100 text-lg leading-6 text-gray-500 border border-grey-500 px-4 py-2 rounded"
    />
    @error($name)
        <p class="text-red-500 mt-1">{{ $message }}</p>
    @enderror
</div>
  

Form.php

 <?php

namespace AppHttpLivewireEvent;

use LivewireComponent;

class Form extends Component
{
    public $eventName;

    public function render()
    {
        return view('events.livewire.form');
    }
}
  

form.blade.php

 <form wire:submit.prevent="submit" method="POST">
    @csrf
    <livewire:general.input
        :name="'event-name'"
        :label="'Event Name'"
        :model="'eventName'"
    />
</form>
  

Как вы можете видеть, я пытаюсь использовать свойство, переданное из form.php $eventName компонента input <livewire:general.input :model="'eventName'" /> , тогда я ожидаю, что оно будет передано input.php общедоступному свойству $model , которое будет привязано к wire:model директиве в его собственном шаблоне.

Я очень новичок в livewire и некоторое время не использовал PHP, поэтому, возможно, я на неверном пути. Я рассмотрел события, но не уверен, что это правильный подход.

Я пытаюсь сделать дочерний компонент в livewire динамичным, чтобы его родительский шаблон мог определять его реактивные свойства и передавать их значения обратно для оценки и т. Д…

Я проверил документы livewire и просмотрел связанные, но не совсем похожие статьи на laracasts и различных других форумах laravel безрезультатно. Я также разговаривал с экспертами по PHP в моем офисе, и они говорят, что это технически возможно, но я могу быть ограничен тем, как livewire реализует свои события жизненного цикла.

Опять же, любая информация, указывающая мне на документацию или в правильном направлении, приветствуется.

Редактировать: я нашел: привязка вложенных данных

на сайте livewire https://laravel-livewire.com/docs/2.x/properties Однако в моем случае это не работает… Есть ли кто-нибудь, кто может показать (используя мой код, пример этой работы?)

Ответ №1:

Я получил желаемый результат, теперь мой родительский компонент реагирует на дочерние изменения.

Это не происходит автоматически в Livewire согласно их документации:

Вложенные компоненты Livewire поддерживает вложенные компоненты. Вложение компонентов может быть чрезвычайно мощным методом, но есть несколько ошибок, о которых стоит упомянуть заранее:

Вложенные компоненты МОГУТ принимать параметры данных от своих родителей, ОДНАКО они не реагируют, как реквизит из компонента Vue. j Это означает, что мне нужно было распространять свои собственные события с ключом и значением, о которых мне нужно, чтобы родитель знал.

Я сделал это, добавив явную настройку ключа в шаблон.

     @livewire('general.input', ['key' => 'eventName'])
  

Примечание: мне пришлось перейти на синтаксис стиля блейда, поскольку стиль тегов не работает с этим подходом (я не знаю почему).

Затем это передается в общедоступное свойство Inputs $key .
Это используется при распространении события, чтобы сообщить родительскому элементу, какой ключ изменяется.

form.php

     <?php

    namespace AppHttpLivewireEvent;

    use LivewireComponent;

    class Form extends Component
    {
        public $eventName;

        public $listeners = ['change' => 'change'];

        public function change($data)
        {
            $this->{$data['key']} = $data['value'];
        }

        public function render()
        {
            return view('events.livewire.form');
        }
    }
  

form.blade.php

     <form wire:submit.prevent="submit" method="POST">
        @csrf
        {{ $eventName }}
        @livewire('general.input', ['key' => 'eventName'])
    </form>
  

input.php

     <?php

    namespace AppHttpLivewireGeneral;

    use LivewireComponent;

    class Input extends Component
    {
        public $name = 'NAME';
        public $model;
        public $key;
        public $label = 'LABEL';

        public $listeners = ['change' => 'change'];

        public function change()
        {
            $this->emitUp('change', [
                'key' => $this->key,
                'value' => $this->model
            ]);
        }

        public function render()
        {
            return view('livewire.general.input');
        }
    }
  

input.blade.php

     <div class="mt-3">
        <label
            for="{{ $name }}"
            class="sr-only"
        >
            {{ $label }}
        </label>
        <input
            wire:keyup="change"
            wire:model="model"
            id="{{ $name }}"
            placeholder="{{ $label }}"
            autocomplete="off"
            class="w-100 text-lg leading-6 text-gray-500 border border-grey-500 px-4 py-2 rounded"
        />
        @error($name)
            <p class="text-red-500 mt-1">{{ $message }}</p>
        @enderror
    </div>
  

Некоторые значения жестко запрограммированы для краткости.

Комментарии:

1. Ваш ответ работает, но приводит к снижению производительности. Вы нашли какой-нибудь лучший способ сделать это?