Day 33 | 常见 Livewire 问题:解决 Livewire.on() 没有作用的问题

这个问题其实在 Day8 的文章有稍微提到过,但大多数人看文件时都大致看一下而会忽略一些小细节,包含我也是 XD。且 Livewire 官方文件并没有清楚列出避免这个问题的方法。因此再拉出来讲解,希望能帮助到遇到这个问题的人。


一、何时会用到 Livewire.on()

在使用 $emit('foo') 触发後端的 Listener 的同时也会触发到前端的 Livewire.on('foo'),可以理解是注册成一个监听。

注:不管是在页面按钮上的 wire:click="$emit('foo')" 或是後端的 $this->emit('foo') 都是一样的!

<script>
Livewire.on('foo', () => {
    ...
})
</script>

二、找出无效的原因

先来看一下错误讯息:

Uncaught ReferenceError: Livewire is not defined

嗯嗯,看起来是没有定义 Livewire 呢!那为什麽会没有定义呢,不是外面早就引入过 @livewireScripts了吗?

照官方文件给的 Layout布局 会像是这样子:

<head>
    @livewireStyles
</head>
<body>
    {{ $slot }}
 
    @livewireScripts
</body>

写在 Livewire元件 中的程序码都会被填在 {{ $slot }} 的位置,因此等於在 JavaScript 还没引入 Livewire 时就先用到了 Livewire,从而导致出错。


三、解决方法

知道问题後要解决也很简单。

第一种、直接把 @livewireScripts 提到 {{ $slot }} 上面。

不过不是推荐,因为还是建议把 JS 都放在 <Body> 的最下面。

<body>
	@livewireScripts
	{{ $slot }}
</body>

第二种、使用 @stack 跟 @push

或是使用 @yield 跟 @section,这两者差别是在於 @stack/push 可以堆栈多组来自不同 components 的内容。而 @yield/section 只能用一次。为了日後有可能会用到导致要改就要全部改,不如一开始就直接用 @stack

<body>
    {{ $slot }}

    @livewireScripts
    
    @stack('scripts')
</body>

在 Livewire Blade 内:

<div>
    <button wire:click="$emit('foo')">CLICK</button>
</div>

@push('scripts')
	<script>
	    Livewire.on('foo', () => {
	        ...
	    })
	</script>
@endpush

结论: @livewireScripts 引入的位置要比你的 <script> 还上面


<<:  JavaScript Day21 - AJAX(3)

>>:  Day 21 - canvas 玩拼图 P5.js

【从实作学习ASP.NET Core】Day21 | 前台 | 用检视元件建立选单

今天要进一步完成商店页面,会用到 ViewComponent 来完成类别选单 ViewCompone...

予焦啦!参数与环境变数

本节是以 Golang 上游 8854368cb076ea9a2b71c8b3c8f675a8e1...

Day3 AR其实在生活中很常见?他们又有那些好处哩(成为史莱姆猎人的萌新)

上期大略介绍了VR,知道VR是藉由装置,让使用者脱离现实,进入到虚拟的空间。这期就来介绍AR啦~~~...

[Day02] Vue i18n - 导入 & 基础用法

i18n 全写为 internationalization,俗称的多国语系也常被称之为本地化 (L...

Day_05 opkg套件管理

在往下继续讲其他网路架构之前,想先来介绍OpenWrt的套件管理系统。常见的Linux发行版几乎都会...