Livewire 线:单击“在 Alpine.js x-data 指令中不工作”

问题描述 投票:0回答:1

我遇到了 Livewire 的wire:click 方法在 Alpine.js x-data 指令中不起作用的问题。这是我的设置的细分:

里面

routes/web.php

Route::get('/product/{slug}', [ProductController::class, 'show'])->name('product.show');

里面

app/Http/Controllers/ProductController.php

public function show($slug)
{
    // Fetching the product and related products data
    // Pass the product and related products to the view
    return view('pages.products.show', compact('product', 'products'));
}

里面

resources/views/pages/products/show.blade.php

   @extends('layouts.default')
   @section('title', $product->model)
   @section('content')
       @livewire('button', ['product' => $product])
       <div class="max-w-screen-xl mx-auto p-4">
           @livewire('button', ['product' => $product])
           <div x-data="{ mainImage: '{{ $product->images->first() ? asset('img/products/' . $product->slug . '/' . $product->images->first()->filename) : asset('img/common/img-unavailable.jpg') }}' }">
               @livewire('button', ['product' => $product])
               <div class="container mx-auto px-4 py-8">
                   @livewire('button', ['product' => $product])
               </div>
           </div>
           @livewire('button', ['product' => $product])
           <x-products.grid :products="$products" />
       </div>
   @endsection

里面

resources/views/livewire/button.blade.php

<div>
    <button
        class="bg-indigo-600 flex gap-2 items-center text-white px-6 py-2 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" type="button" wire:click="clicked">
        Add to Cart
    </button>
</div>

里面

app/Livewire/Button.php

<?php

namespace App\Livewire;

use Barryvdh\Debugbar\Facades\Debugbar;
use Livewire\Component;

class Button extends Component
{
    public $product;

    public function mount($product)
    {
        $this->product = $product;
        Debugbar::info("Product mounted:", $this->product);
    }

    public function render()
    {
        return view('livewire.button');
    }

    public function clicked()
    {
        Debugbar::info("clicked");
        Debugbar::info("Product in cart:", $this->product);
        // $this->emit('cartUpdated');
    }
}

show.blade.php
视图中的所有 Livewire 按钮都可以正常工作,但 Alpine.js
x-data
指令内的按钮除外。具体来说,该块内的按钮:

<div x-data="{ mainImage: '{{ $product->images->first() ? asset('img/products/' . $product->slug . '/' . $product->images->first()->filename) : asset('img/common/img-unavailable.jpg') }}' }">
    @livewire('button', ['product' => $product])
    <div class="container mx-auto px-4 py-8">
        @livewire('button', ['product' => $product])
    </div>
</div>

这些按钮上的

wire:click
方法不会触发 Livewire 组件中的
clicked
方法。但是,会调用
mount
方法,并将产品详细信息记录在 Debugbar 中。该
x-data
块之外的按钮按预期工作,单击它们会导致 AJAX 调用并记录“已单击”消息。

我尝试过的:

  • 验证是否调用了
    mount
    方法并将产品数据正确传递到Livewire组件。
  • 确认
    wire:click
    方法在
    x-data
    块之外有效。
  • 检查了控制台中是否有任何 JavaScript 错误,但没有发现任何错误。
php laravel laravel-blade laravel-livewire alpine.js
1个回答
0
投票

出现您面临的问题是因为当您尝试在 Alpine.js 上下文中触发 Livewire 操作时,Alpine.js 和 Livewire 并不总是无缝协作,尤其是当 Alpine 在 x-data 中管理 DOM 更新时指示。 Alpine.js 在 Livewire 处理之前拦截诸如wire:click之类的事件。

这里解决问题的方法:

解决方案 1:使用 x-on 进行 Livewire 活动

您可以使用Alpine的x-on指令来发出事件并触发Livewire方法,而不是直接使用wire:click。以下是调整按钮代码的方法:

<div x-data="{ mainImage: '{{ $product->images->first() ? asset('img/products/' . $product->slug . '/' . $product->images->first()->filename) : asset('img/common/img-unavailable.jpg') }}' }">
<button
    class="bg-indigo-600 flex gap-2 items-center text-white px-6 py-2 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
    type="button"
    x-on:click="$wire.clicked"
>
    Add to Cart
</button>
<div class="container mx-auto px-4 py-8">
    <button
        class="bg-indigo-600 flex gap-2 items-center text-white px-6 py-2 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
        type="button"
        x-on:click="$wire.clicked"
    >
        Add to Cart
    </button>
</div>

在此解决方案中,Alpine.js 将在单击按钮时直接调用 $wire.clicked 方法,从而绕过 x-data 范围内的wire:click 的需要。

© www.soinside.com 2019 - 2024. All rights reserved.