在Livewire v2中,有一个using Livewire within a package美元的doctor .我找不到任何与v3相关的文档.我try 了v2文档中提到的方法,但它不适用于v3.
我需要注册来自多个自定义路径/命名空间的Livewire组件.我想要手动注册那些.
在Livewire v2中,有一个using Livewire within a package美元的doctor .我找不到任何与v3相关的文档.我try 了v2文档中提到的方法,但它不适用于v3.
我需要注册来自多个自定义路径/命名空间的Livewire组件.我想要手动注册那些.
是的,我的 comments 有点蹩脚.所以,我从来没有做过这件事,也没有经验可以做些什么.但是有这么多使用Livewire和注册组件的包,所以让我们来弄清这一点.
让我以laravel/jetstream为例,使用自测试版发布以来的livewire 3.0.
在这JetstreamServiceProvider个中,他们注册Livewire组件的方式与您上面的示例完全不同.将register()
与callAfterResolving
回调一起使用,而不是boot()
.
public function register()
{
$this->mergeConfigFrom(__DIR__.'/../config/jetstream.php', 'jetstream');
$this->callAfterResolving(BladeCompiler::class, function () {
if (config('jetstream.stack') === 'livewire' && class_exists(Livewire::class)) {
Livewire::component('navigation-menu', NavigationMenu::class);
// .. other Livewire components
}
});
}
现在,如果我们沿着这条路走下go ,看看Livewire是如何注册其组件的,他们做出这个 Select 的原因就很明显了.最后降到了these 3 lines.
app()->make('view.engine.resolver')->register('blade', function () {
return new ExtendedCompilerEngine(app('blade.compiler'));
});
因此,简单地说,只有使用服务提供者的REGISTER方法使包中的任何组件可用才有意义,以确保BladeCompiler
被解析.为什么Livewire v2 documentation说的是完全不同的东西(Livewire v3文档甚至没有提到它)对我来说是假的,也许他们写它的 idea 是大约standards从未在Livewire中实现,因为Livewire内部发生了如此多的变化,我会把所有的责任都归咎于只有blip in文档,这是不幸的发生.
这就是在服务Provider 中注册Livewire组件应该是什么样子.
namespace SomePackage;
use SomePackage\Livewire\SomeComponent;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\Support\ServiceProvider;
use Livewire\Livewire;
class SomePackageServiceProvider extends ServiceProvider {
public function register() {
$this->callAfterResolving(BladeCompiler::class, function () {
// 1.
// Check the existence of the Livewire class ..
if(class_exists(Livewire::class)) {
Livewire::component('some-component', SomeComponent::class);
}
// 2.
// where 1. might be redundant because Livewire obviously set as a dependency in your composer.json, just skip Livewire existence check.
Livewire::component('some-component', SomeComponent::class);
});
}
}
不管有没有if(class_exists(Livewire::class))
,如果不存在这个特定的类,use Livewire\Livewire
的使用都会致命地崩溃.因此,无论如何,判断class_exists(Livewire::class)
的存在很可能是愚蠢的.
因此,这将是我对如何在服务Provider 中注册Livewire组件的最后一次彻底的了解:
namespace SomePackage;
use SomePackage\Livewire\SomeComponent;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\Support\ServiceProvider;
use Livewire\Livewire;
class SomePackageServiceProvider extends ServiceProvider {
public function register() {
// .. merge config, etc.
$this->registerLivewireComponents();
}
/**
* Register Livewire components
*/
protected function registerLivewireComponents() {
$this->callAfterResolving(BladeCompiler::class, function ()
Livewire::component('some-component', SomeComponent::class);
});
}
}
这个管用吗?我不知道,但我想你很快就会告诉我的.
虽然他们看到的是spatie/laravel-dashboard个组件的包装,但他们正在注册boot method of its service provider中的组件.
class DashboardServiceProvider extends ServiceProvider
{
public function boot()
{
// ... code skip
$this
->registerPublishables()
->registerBladeComponents()
->registerLivewireComponents();
}
protected function registerLivewireComponents(): self
{
Livewire::component('dashboard-update-mode', UpdateModeComponent::class);
return $this;
}
}
服务Provider 的register
方法仅用于将服务注册(注入)到容器(Bootstrap),而boot
方法将在所有服务都已被 bootstrap (注册或注入)之后使用,基于此, bootstrap 方法将是注册任何Livewire组件的逻辑位置,因此Jetstream Select 不同路径肯定是有原因的.确实很有趣;)
因此,总而言之,答案should中解释的两种方法都有效.
所以我做了一些测试,没有发现在我的测试包中运行Livewire组件有任何问题.
这个简单的包存在于一个名为test
的路由、一个名为counter
的视图和一个名为Counter
的Livewire组件类中.
服务Provider .
namespace TheCore\Test;
// .. skipping all the includes
class TestServiceProvider extends ServiceProvider {
public function register() {
Livewire::component('counter', Counter::class);
}
}
这条路由
Route::get('/test', function() {
return Test::testView();
})->name('thecore-test')->middleware(['web']);
其中Test::testView()
返回
public function testView() {
// hence the namespace scoping, this package namespace
// scope is set to 'test', else it will land in the
// app `views` directory and not in your package `views`
// directory
return view('test::testing');
}
来自livewire的counter example快速入门页面,其中render()
只与以下内容相关:
public function render() {
// hence the scoping of 'test' again, else it
// will land in your apps `views/livewire` directory
// instead of the package `views/livewire` directory.
return view('test::livewire.counter');
}
并且Livewire组件在Blade 中被调用
<livewire:counter />
如预期的那样工作.我使用了所有类型的注册,在boot()
中,在register()
中,在有和没有callAfterResolving
回调的情况下,都没有太大变化.
这颗卫星在太空中被发现就是这样;)