Skip to content
全部文档

wire:ref

Livewire 中的 Refs 提供了一种命名方式,进而可定位 Livewire 内的单个元素或组件。

它们适用于向特定元素派发事件或流式传输内容。

它们是用 class/id 定位元素的更整洁替代方案,但概念上类似。

常见用例包括:

  • 向特定组件派发事件
  • 使用 `$refs` 定位元素
  • 向特定元素流式传输内容

下面逐一说明。

派发事件

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

考虑下面这个监听 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 元素

给 HTML 元素加上 wire:ref 后,可通过 $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"

此指令没有修饰符。