Skip to content

wire:ref

Livewire 中的 Refs 提供了一种在 Livewire 内部命名然后定位单个元素或组件的方法。

它们对于将事件分派或将内容流式传输到特定元素很有用。

它们是一个整洁的替代方案,但在概念上类似于使用类/ID 来定位元素。

以下是用例列表:

  • 将事件分派到特定组件
  • 使用 $refs 定位元素
  • 将内容流式传输到特定元素

让我们逐一介绍这些。

分派事件

Refs 是在 Livewire 的事件系统中定位特定子组件的好方法。

考虑以下监听 close 事件的 Livewire 模态框组件:

php
<?php

new class extends Livewire\Component {
    public bool $isOpen = false;

    // ...

    #[On('close')]
    public function close()
    {
        $this->isOpen = false;
    }
};
?>

<div wire:show="isOpen">
    {{ $slot }}
</div>

通过将 wire:ref 添加到组件标签,你现在可以使用 ref: 参数直接将 close 事件分派给它:

php
<?php

new class extends Livewire\Component {
    public function save()
    {
        //

        $this->dispatch('close')->to(ref: 'modal');
    }
};
?>

<div>
    <!-- ... -->

    <livewire:modal wire:ref="modal">
        <!-- ... -->

        <button wire:click="save">Save</button>
    </livewire:modal>
</div>

访问 DOM 元素

当你将 wire:ref 添加到 HTML 元素时,可以通过 $refs 魔术属性访问它。

考虑一个实时更新的字符计数器:

php
<div>
    <textarea wire:model="message" wire:ref="message"></textarea>

    Characters: <span wire:ref="count">0</span>

    <!-- ... -->
</div>

<script>
    this.$refs.message.addEventListener('input', (e) => {
        this.$refs.count.textContent = e.target.value.length
    })
</script>

访问 $wire

如果你希望访问带有 ref 的组件的 $wire,可以通过元素上的 .$wire 属性执行此操作:

php
<div>
    <!-- ... -->

    <livewire:modal wire:ref="modal">
        <!-- ... -->

        <button wire:click="save()">Save</button>
    </livewire:modal>
</div>

<script>
    this.$intercept('save', ({ onFinish }) => {
        onFinish(() => {
            this.$refs.modal.$wire.close()
        })
    })
</script>

流式传输内容

Livewire 支持使用 CSS 选择器将内容直接流式传输到组件内的元素,但是,wire:ref 是一种更方便和可发现的方法。

考虑以下组件,它在生成时直接从 LLM 流式传输答案:

php
<?php

new class extends Livewire\Component {
    public $question = '';

    public function ask()
    {
        Ai::ask($this->question, function ($chunk) {
            $this->stream($chunk)->to(ref: 'answer');
        });

        $this->reset('question');
    }
};
?>

<div>
    <input type="text" wire:model="question">

    <button wire:click="ask"></button>

    <h2>Answer:</h2>

    <p wire:ref="answer"></p>
</div>

动态 refs

Refs 在循环和其他动态上下文中完美工作。

以下是具有多个模态框实例的示例:

php
@foreach($users as $index => $user)
    <livewire:modal
        wire:key="{{ $user->id }}"
        wire:ref="{{ 'user-modal-' . $user->id }}"
    >
        <!-- ... -->
    </livewire>
@endforeach

作用域行为

Refs 的作用域限定为当前组件。这意味着你可以定位组件内的任何元素,但不能定位页面上其他组件中的元素。

如果组件内的多个元素具有相同的 ref 名称,则将使用遇到的第一个。