在Livewire v2中,有一个using Livewire within a package美元的doctor .我找不到任何与v3相关的文档.我try 了v2文档中提到的方法,但它不适用于v3.

我需要注册来自多个自定义路径/命名空间的Livewire组件.我想要手动注册那些.

推荐答案

以下为TLDR.

是的,我的 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)的存在很可能是愚蠢的.

TLDR;

因此,这将是我对如何在服务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);
         });

    }

}

这个管用吗?我不知道,但我想你很快就会告诉我的.

更新v1 SPACE/LARAVEL-仪表板

虽然他们看到的是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中解释的两种方法都有效.

更新v2测试

所以我做了一些测试,没有发现在我的测试包中运行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回调的情况下,都没有太大变化.

这颗卫星在太空中被发现就是这样;)


Laravel相关问答推荐

自定义验证在表单请求上始终返回 true laravel

找不到 Laravel 5 类日志(log)

如何在 Laravel 的外部 js 文件中包含 csrf_token()?

如何在 Laravel 5.5 中扩展 vendor 包服务提供者

在 laravel 中更改时区

在 Laravel 5 中扩展请求类

Laravel 中未加密的 cookie

这个上下文的流程应该是怎样的? (根据 Select 的付款方式,将处理付款的代码放在哪里?)

Laravel 5 - 多对多 - Attach versus Save

在 Laravel 5.4 中将中间件应用于除 `setup/*` 之外的所有路由

干预图像:直接从带有原始文件名和分机的网址保存图像?

Laravel 5 Mime 验证

如何在laravel 5.1中使用url(路由)传递多个参数

在 Laravel 5.4 中向多个抄送收件人发送Electron邮件

Laravel 错误声明 App\Exceptions\Handler::report(Throwable $exception)

Laravel 5.3 通知 - 仅使用Electron邮件地址通知

Laravel 5.4 Vue.JS 无法挂载组件:未定义模板或渲染函数

在 laravel Passport 客户端应用程序中使用访问令牌获取用户数据

如何在没有日志(log)、没有信息的情况下调试 Laravel 错误 500

如何使用 Postman 处理 Laravel $_POST 请求