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 名称,将使用遇到的第一个。

参考

blade
wire:ref="name"

此指令没有修饰符。