承接 pixelworxio/livewire-workflows 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

pixelworxio/livewire-workflows

最新稳定版本:0.5.3b

Composer 安装命令:

composer require pixelworxio/livewire-workflows

包简介

Build multi-step workflows in Laravel / Livewire with zero boilerplate

README 文档

README

Livewire Workflows Banner

GitHub Tests Action Status GitHub Stars

Livewire Workflows (BETA)

Build powerful multi-step workflows in Laravel with zero boilerplate. Define complex user journeys—onboarding, checkouts, surveys—using an expressive, route-like DSL. Get automatic route registration, guard-based navigation, state persistence, and full Livewire integration out of the box.

// Define a complete workflow in seconds
Workflow::flow('onboarding')
    ->entersAt(name: 'onboarding.start', path: '/onboarding')
    ->finishesAt('dashboard')
    ->step('verify-email')
        ->goTo(VerifyEmail::class)
        ->unlessPasses(EmailVerifiedGuard::class)
        ->order(10)
    ->step('profile')
        ->goTo(EditProfile::class)
        ->unlessPasses(ProfileCompletedGuard::class)
        ->order(20);

That's it. No manual routes. No state management headaches.

View the testbench repo, https://github.com/pixelworxio/livewire-workflows-testbench, for examples of how this package can help you with your project.

✨ Why Livewire Workflows?

Feature Livewire Workflows Manual Implementation
Route Management ✅ Auto-generated ❌ Define every route manually
State Persistence ✅ Built-in (Session/DB) ❌ Roll your own
Navigation Logic ✅ Guard-based pipeline ❌ Complex conditionals everywhere
Back Button ✅ History tracking ❌ Custom session juggling
Progress Tracking ✅ One method call ❌ Calculate yourself
Events & Analytics ✅ Fire automatically ❌ Remember to dispatch

Result: Spend time building features, not workflow infrastructure.

📦 Installation

composer require pixelworxio/livewire-workflows

Quick Setup (Session-Based)

php artisan workflows:install

Production Setup (Database-Backed)

php artisan workflows:install --with-db
php artisan migrate

🚀 Quick Start (3 Minutes)

1. Define Your Workflow

Open routes/workflows.php:

use Pixelworxio\LivewireWorkflows\Facades\Workflow;

Workflow::flow('onboarding')
    ->entersAt(name: 'onboarding.start', path: '/onboarding')
    ->finishesAt('dashboard')
    ->step('verify-email')
        ->goTo(\App\Livewire\Onboarding\VerifyEmail::class)
        ->unlessPasses(\App\Guards\EmailVerifiedGuard::class)
        ->order(10)
    ->step('profile')
        ->goTo(\App\Livewire\Onboarding\EditProfile::class)
        ->unlessPasses(\App\Guards\ProfileCompletedGuard::class)
        ->order(20);

Routes auto-registered:

  • Entry: GET /onboardingonboarding.start
  • Step 1: GET /onboarding/verify-emailonboarding.verify-email
  • Step 2: GET /onboarding/profileonboarding.profile

2. Create a Guard

Quick Generation:

php artisan make:workflow-guard EmailVerified

This generates a guard at App\Guards\EmailVerifiedGuard.php with the proper structure.

namespace App\Guards;

use Illuminate\Http\Request;
use Pixelworxio\LivewireWorkflows\Contracts\GuardContract;

class EmailVerifiedGuard implements GuardContract
{
    public function passes(Request $request): bool
    {
        return true;
    }

    public function onEnter(Request $request): void {}
    public function onExit(Request $request): void {}
    public function onPass(Request $request): void {}
    public function onFail(Request $request): void {}
}

Guard Logic: passes() = true → skip step. passes() = false → show step.

3. Build Your Livewire Component

namespace App\Livewire\Onboarding;

use Livewire\Component;
use Pixelworxio\LivewireWorkflows\Attributes\WorkflowStep;
use Pixelworxio\LivewireWorkflows\Livewire\Concerns\InteractsWithWorkflows;

#[WorkflowStep(flow:'onboarding', key:'verify-email')]
class VerifyEmail extends Component
{
    use InteractsWithWorkflows;

    public function resend()
    {
        auth()->user()->sendEmailVerificationNotification();
        session()->flash('message', 'Verification email sent!');
    }
    
    public function goToNextStep(): void
    {
        // ... handle your logic
        
        $this->continue('onboarding'); // workflow name is optional when using WorkflowStep attribute
    }

    public function render()
    {
        return view('livewire.onboarding.verify-email');
    }
}

And in your Blade view:

<div>
    <h1>Verify Your Email</h1>
    <p>Check your inbox for the verification link.</p>
    
    <button wire:click="resend">Resend Email</button>
    
    <button wire:click="goToNextStep">
        I've Verified — Continue
    </button>
</div>

4. Done!

Visit /onboarding. The package:

  1. Evaluates guards in order
  2. Redirects to first incomplete step
  3. Tracks progress automatically
  4. Completes when all steps pass

📖 Core Concepts

Auto-Generated Routes

Routes are automatically registered from your DSL:

->entersAt(name: 'checkout.start', path: '/checkout')  // Entry route
->step('shipping')                                       // Auto: /checkout/shipping
->step('payment')                                        // Auto: /checkout/payment

Generated:

  • checkout.start/checkout
  • checkout.shipping/checkout/shipping
  • checkout.payment/checkout/payment

Dynamic Routes with Parameters

Workflows support dynamic route parameters and route model binding:

Workflow::flow('user-checkout')
    ->entersAt(name: 'user-checkout.start', path: '/user/{user}/checkout/{product}')
    ->finishesAt('dashboard')
    ->step('shipping')
        ->goTo(\App\Livewire\Checkout\Shipping::class)
        ->unlessPasses(\App\Guards\HasShippingAddress::class)
        ->order(10)
    ->step('payment')
        ->goTo(\App\Livewire\Checkout\Payment::class)
        ->unlessPasses(\App\Guards\HasPaymentMethod::class)
        ->order(20);

Generated Routes:

  • user-checkout.start/user/{user}/checkout/{product}
  • user-checkout.shipping/user/{user}/checkout/{product}/shipping
  • user-checkout.payment/user/{user}/checkout/{product}/payment

Route Model Binding:

// Supports Laravel's route model binding syntax
->entersAt(name: 'checkout.start', path: '/user/{user:id}/product/{product:slug}')

Navigation Preserves Parameters:

Route parameters are automatically passed through all workflow navigation:

class Shipping extends Component
{
    use InteractsWithWorkflows;
    
    protected ?string $workflowName = 'user-checkout';

    // Livewire receives route parameters
    public function mount($user, $product)
    {
        // $user and $product are automatically injected
    }

    public function submit()
    {
        // Parameters are automatically preserved when continuing
        $this->continue($this->workflowName); // Still navigates with {user} and {product}
    }
}

The continue() and back() methods automatically extract and pass route parameters from the current request, ensuring seamless navigation throughout the workflow.

Guard Behavior

Guards use positive semantics:

class ProfileCompleteGuard implements GuardContract
{
    public function passes(Request $request): bool
    {
        return $request->user()->profile_completed;
    }
}
Guard Result Step Behavior
passes() = true Skip this step
passes() = false Show this step

Use unlessPasses(Guard::class): "Show step UNLESS guard passes."

Navigation Flow

  1. User visits entry route (/onboarding)
  2. Package evaluates guards in order
  3. Redirects to first failing guard's step
  4. User completes step, calls $this->continue('onboarding')
  5. Re-evaluates from entry → next unmet step or finish

🧩 Advanced Features

State Management

Setting Workflow Name

Use the #[WorkflowName] attribute to explicitly declare your component's workflow, when not using the WorkflowStep attribute:

use Pixelworxio\LivewireWorkflows\Attributes\WorkflowName;

#[WorkflowName('checkout')]
class CheckoutShipping extends Component
{
    use InteractsWithWorkflows;

    // protected ?string $workflowName = 'checkout'; // No need to set 
}

Benefits:

  • ✅ Eliminates boilerplate
  • ✅ Makes workflow association explicit
  • ✅ Auto-detected during component boot
  • ✅ Falls back to route-based detection if not present

Persisting State

Persist data across workflow steps with the #[WorkflowState] attribute:

use Pixelworxio\LivewireWorkflows\Attributes\WorkflowName;
use Pixelworxio\LivewireWorkflows\Attributes\WorkflowState;

#[WorkflowName('checkout')]
class CheckoutShipping extends Component
{
    use InteractsWithWorkflows;

    #[WorkflowState]
    public ?string $address = null;

    #[WorkflowState(encrypt: true)]
    public ?string $creditCard = null;

    #[WorkflowState(namespace: 'shipping')]
    public ?string $method = null;
}

Features:

  • Auto-hydration on mount
  • Auto-persistence on dehydrate
  • Encryption support
  • Namespace grouping
  • Session or database storage

Full state management guide →

Progress Tracking

$progress = workflow('onboarding')->progressFor($request);

// Returns:
[
    'total' => 3,
    'completed' => 1,
    'remaining' => 2,
    'percentage' => 33.33,
    'current_step' => 'verify-email',
    'next_step' => 'profile',
    'is_complete' => false,
]

Events

Listen to workflow lifecycle:

use Pixelworxio\LivewireWorkflows\Events\{WorkflowAdvanced, WorkflowCompleted};

Event::listen(WorkflowAdvanced::class, function ($event) {
    Log::info("User {$event->userKey} moved from {$event->fromKey} to {$event->toKey}");
});

Event::listen(WorkflowCompleted::class, function ($event) {
    Mail::to($user)->send(new OnboardingComplete());
});

CLI Tools

# Generate a new workflow
php artisan make:workflow checkout

# Generate a guard class
php artisan make:workflow-guard EmailVerified

# Add a step to existing workflow
php artisan make:workflow-step checkout payment \
    --component=App\\Livewire\\Checkout\\Payment \
    --guard=App\\Guards\\CartNotEmptyGuard \
    --order=20

# Validate and document all workflows
php artisan workflows:scan

🎯 Real-World Examples

Multi-Page Checkout

Workflow::flow('checkout')
    ->entersAt(name: 'checkout.start', path: '/checkout')
    ->finishesAt('orders.confirmation')
    ->step('cart')
        ->goTo(ReviewCart::class)
        ->unlessPasses(CartNotEmptyGuard::class)
        ->order(10)
    ->step('shipping')
        ->goTo(ShippingAddress::class)
        ->unlessPasses(ShippingAddressGuard::class)
        ->order(20)
    ->step('payment')
        ->goTo(PaymentMethod::class)
        ->unlessPasses(PaymentMethodGuard::class)
        ->order(30);

Employee Onboarding

Workflow::flow('employee-onboarding')
    ->entersAt(name: 'onboard.start', path: '/onboard')
    ->finishesAt('employee.dashboard')
    ->step('paperwork')
        ->goTo(Paperwork::class)
        ->unlessPasses(PaperworkCompleteGuard::class)
        ->order(10)
    ->step('it-setup')
        ->goTo(ITSetup::class)
        ->unlessPasses(ITAccountGuard::class)
        ->order(20)
    ->step('training')
        ->goTo(TrainingModules::class)
        ->unlessPasses(TrainingCompleteGuard::class)
        ->order(30);

User Registration Flow

Workflow::flow('signup')
    ->entersAt(name: 'signup.start', path: '/signup')
    ->finishesAt('welcome')
    ->step('account')
        ->goTo(CreateAccount::class)
        ->unlessPasses(AccountCreatedGuard::class)
        ->order(10)
    ->step('verify-email')
        ->goTo(VerifyEmail::class)
        ->unlessPasses(EmailVerifiedGuard::class)
        ->order(20)
    ->step('preferences')
        ->goTo(SetPreferences::class)
        ->unlessPasses(PreferencesSetGuard::class)
        ->order(30);

🔧 Configuration

Publish and customize the config:

php artisan vendor:publish --tag=livewire-workflows-config

config/livewire-workflows.php:

return [
    // State persistence: 'null', 'session', or 'eloquent'
    'repository' => env('WORKFLOWS_REPOSITORY', 'session'),
    
    // Middleware applied to all workflow routes
    'middleware' => ['web', 'auth'],
];

State Repository Options

Repository Use Case Persistence
null Stateless workflows None
session Guest users, simple flows Session lifetime
eloquent Authenticated users, production Database

📊 API Reference

Workflow DSL

Workflow::flow(string $name)
    ->entersAt(name: string, path: string)
    ->finishesAt(string $routeName)
    ->step(string $key)
        ->goTo(string $componentClass)
        ->unlessPasses(string $guardClass)
        ->order(int $order);

Livewire Trait Methods

use InteractsWithWorkflows;

$this->continue(string $flow): RedirectResponse
$this->back(string $flow, string $currentKey): ?RedirectResponse
$this->syncState(): void  // Manually persist state

Note: When using the #[WorkflowStep] attribute, the $flow and $currentKey properties are optional

#[WorkflowStep(flow: 'my-flow', key: 'current-step', middleware: ['auth'])]

use InteractsWithWorkflows;

$this->continue(): RedirectResponse
$this->back(): ?RedirectResponse

Helper Functions

workflow(string $flow)->redirect(Request $request, ?string $doneRoute = null)
workflow(string $flow)->nextRouteNameFor(Request $request, ?string $doneRoute = null)
workflow(string $flow)->previousRouteNameFor(string $currentKey, Request $request)
workflow(string $flow)->progressFor(Request $request)

State Management Helpers

// Automatic with attributes
#[WorkflowState] public ?string $email = null;
#[WorkflowState(encrypt: true)] public ?string $password = null;
#[WorkflowState(namespace: 'profile')] public ?string $name = null;

// Manual helpers
$this->putWorkflowState(string $key, mixed $value)
$this->getWorkflowState(string $key, mixed $default = null)
$this->hasWorkflowState(string $key)
$this->forgetWorkflowState(string $key)
$this->clearWorkflowState(?string $namespace = null)
$this->allWorkflowState()

🆚 Comparison with Alternatives

**Or so Claude.ai says...

Feature Livewire Workflows Spatie Laravel Wizard Custom Solution
Route Auto-Registration
Guard-Based Navigation Custom
State Persistence ✅ Built-in Custom
Livewire 3 Native ⚠️ Limited N/A
History/Back Support ⚠️ Basic Custom
Progress Tracking Custom
Events Custom
Learning Curve Low Medium High

💬 FAQ

Can I use this with Livewire v3 and the v4 beta?

The package is tested to work with Livewire v3. Livewire v4 beta compatibility is planned, but not yet tested.

Do I need to define routes manually?

No. Step routes are auto-registered from your DSL. You only need to define the finish route in your regular routes/web.php, if not already present.

Can I protect workflows with authentication?

Yes. Add 'auth' to the middleware array in config/livewire-workflows.php.

How do I skip steps dynamically?

Make the guard's passes() method return true when the step should be skipped.

Can workflows share state?

No. State is scoped per workflow and per user. This is by design for data isolation.

What happens if a user jumps to a step URL directly?

The step page loads, but calling continue() will re-evaluate guards and redirect appropriately.

🛠️ Requirements

  • PHP 8.3+
  • Laravel 11.x or 12.x
  • Livewire 3.x

🤝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

Development Setup

git clone https://github.com/pixelworxio/livewire-workflows.git
cd livewire-workflows
composer install
composer test

📜 License

The MIT License (MIT). Please see License File for more information.

🙏 Credits

Built with ❤️ using Laravel, Livewire, and Spatie's Package Tools.

🌟 Show Your Support

Give a ⭐️ if this project helped you!

GitHub Stars Tweet

统计信息

  • 总下载量: 13
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 65
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 65
  • Watchers: 2
  • Forks: 5
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-11-06