Qwik Beispiele

Qwik Framework-Beispiele einschließlich Komponenten, Signalen, State Management und Zero-Hydration-Patterns

💻 Hallo Welt Qwik typescript

🟢 simple

Grundlegende Qwik Komponenten-Beispiele und Hallo Welt-Anwendungen mit JSX

// Qwik Hello World Examples

import { component$, useSignal, useStore, $, useTask$ } from '@builder.io/qwik';

// 1. Basic functional component
export const HelloWorld = component$(() => {
    return <h1>Hello, World!</h1>;
});

// 2. Component with props
export interface GreetingProps {
    name: string;
}

export const Greeting = component$<GreetingProps>((props) => {
    return <h1>Hello, {props.name}!</h1>;
});

// 3. Component with signal (reactive state)
export const Counter = component$(() => {
    const count = useSignal(0);

    const increment = $(() => {
        count.value++;
    });

    const decrement = $(() => {
        count.value--;
    });

    return (
        <div>
            <h1>Count: {count.value}</h1>
            <button onClick$={increment}>Increment</button>
            <button onClick$={decrement}>Decrement</button>
        </div>
    );
});

// 4. Component with store (for complex objects)
export const UserProfile = component$(() => {
    const user = useStore({
        name: 'Guest',
        age: 25,
        isLoggedIn: false
    });

    const login = $(() => {
        user.name = 'John Doe';
        user.age = 30;
        user.isLoggedIn = true;
    });

    const logout = $(() => {
        user.name = 'Guest';
        user.age = 25;
        user.isLoggedIn = false;
    });

    const updateName = $((event: Event) => {
        const target = event.target as HTMLInputElement;
        user.name = target.value;
    });

    const updateAge = $((event: Event) => {
        const target = event.target as HTMLInputElement;
        user.age = parseInt(target.value);
    });

    return (
        <div>
            <h2>User Profile</h2>
            {user.isLoggedIn ? (
                <div>
                    <p>Name: {user.name}</p>
                    <p>Age: {user.age}</p>
                    <input
                        type="text"
                        value={user.name}
                        onInput$={updateName}
                        placeholder="Enter name"
                    />
                    <input
                        type="number"
                        value={user.age}
                        onInput$={updateAge}
                        placeholder="Enter age"
                    />
                    <button onClick$={logout}>Logout</button>
                </div>
            ) : (
                <button onClick$={login}>Login</button>
            )}
        </div>
    );
});

// 5. Component with computed values
export const ShoppingCart = component$(() => {
    const items = useStore([
        { name: 'Apple', price: 1.5, quantity: 2 },
        { name: 'Banana', price: 0.8, quantity: 5 }
    ]);

    const total = useSignal(0);
    const itemCount = useSignal(0);

    // UseTask$ for reactive computations
    useTask$(({ track }) => {
        track(() => items);
        total.value = items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
        itemCount.value = items.reduce((sum, item) => sum + item.quantity, 0);
    });

    const removeItem = $((index: number) => {
        items.splice(index, 1);
    });

    return (
        <div>
            <h2>Shopping Cart</h2>
            <p>Items: {itemCount.value}</p>
            <p>Total: ${total.value.toFixed(2)}</p>
            <ul>
                {items.map((item, index) => (
                    <li key={index}>
                        {item.name} - ${item.price} x {item.quantity}
                        <button onClick$={() => removeItem(index)}>Remove</button>
                    </li>
                ))}
            </ul>
        </div>
    );
});

// 6. Async component with resource
import { Resource, useResource$ } from '@builder.io/qwik';

export interface Product {
    id: number;
    name: string;
    price: number;
}

export const ProductList = component$(() => {
    const productsResource = useResource$<Product[]>(async ({ track, cleanup }) => {
        // Track any reactive dependencies
        track(() => {/* track signals if needed */});

        // Cleanup function
        cleanup(() => {
            console.log('Cleaning up product fetch');
        });

        // Simulate API call
        await new Promise(resolve => setTimeout(resolve, 2000));

        return [
            { id: 1, name: 'Laptop', price: 999 },
            { id: 2, name: 'Phone', price: 699 },
            { id: 3, name: 'Tablet', price: 399 }
        ];
    });

    return (
        <div>
            <h2>Products</h2>
            <Resource
                value={productsResource}
                onPending={() => <div>Loading products...</div>}
                onRejected={(error) => <div>Error: {error.message}</div>}
                onResolved={(products) => (
                    <ul>
                        {products.map((product) => (
                            <li key={product.id}>
                                {product.name} - ${product.price}
                            </li>
                        ))}
                    </ul>
                )}
            />
        </div>
    );
});

// 7. Parent component demonstrating usage
export const App = component$(() => {
    return (
        <div>
            <HelloWorld />
            <Greeting name="Qwik" />
            <Counter />
            <UserProfile />
            <ShoppingCart />
            <ProductList />
        </div>
    );
});

// 8. Component with lifecycle hooks
import { useClientEffect$, useVisibleTask$ } from '@builder.io/qwik';

export const LifecycleDemo = component$(() => {
    const message = useSignal('Component mounted');

    // Runs on the client only (equivalent to componentDidMount)
    useClientEffect$(() => {
        console.log('Component mounted on client');
        message.value = 'Client effect executed';

        // Cleanup function
        return () => {
            console.log('Component will unmount');
        };
    });

    // Runs when component becomes visible
    useVisibleTask$(({ cleanup }) => {
        console.log('Component is visible');
        message.value = 'Visible task executed';

        cleanup(() => {
            console.log('Component hidden/cleaned up');
        });
    });

    return (
        <div>
            <h3>Lifecycle Demo</h3>
            <p>{message.value}</p>
        </div>
    );
});

// 9. Form handling
export const ContactForm = component$(() => {
    const form = useStore({
        name: '',
        email: '',
        message: '',
        submitted: false
    });

    const handleSubmit = $(async (event: Event) => {
        event.preventDefault();
        console.log('Form submitted:', form);

        // Simulate form submission
        await new Promise(resolve => setTimeout(resolve, 1000));

        form.submitted = true;

        // Reset form after 2 seconds
        setTimeout(() => {
            form.name = '';
            form.email = '';
            form.message = '';
            form.submitted = false;
        }, 2000);
    });

    return (
        <div>
            <h3>Contact Form</h3>
            {form.submitted ? (
                <p>Thank you for your submission!</p>
            ) : (
                <form onSubmit$={handleSubmit}>
                    <div>
                        <label>
                            Name:
                            <input
                                type="text"
                                value={form.name}
                                onInput$={(e) => form.name = (e.target as HTMLInputElement).value}
                                required
                            />
                        </label>
                    </div>
                    <div>
                        <label>
                            Email:
                            <input
                                type="email"
                                value={form.email}
                                onInput$={(e) => form.email = (e.target as HTMLInputElement).value}
                                required
                            />
                        </label>
                    </div>
                    <div>
                        <label>
                            Message:
                            <textarea
                                value={form.message}
                                onInput$={(e) => form.message = (e.target as HTMLTextAreaElement).value}
                                required
                            />
                        </label>
                    </div>
                    <button type="submit">Submit</button>
                </form>
            )}
        </div>
    );
});

export { App as HelloWorldExample };

💻 Qwik Signale und Stores typescript

🟡 intermediate

Arbeiten mit reaktiven Signalen, Stores und State Management in Qwik

// Qwik Signals and Stores

import {
    component$,
    useSignal,
    useStore,
    useTask$,
    $,
    useResource$,
    Resource
} from '@builder.io/qwik';

// 1. Basic signals
export const SignalDemo = component$(() => {
    const count = useSignal(0);
    const text = useSignal('Hello');
    const isVisible = useSignal(true);

    const increment = $(() => {
        count.value++;
    });

    const decrement = $(() => {
        count.value--;
    });

    const reset = $(() => {
        count.value = 0;
        text.value = 'Hello';
    });

    const toggle = $(() => {
        isVisible.value = !isVisible.value;
    });

    // Reactive computation with useTask$
    const doubled = useSignal(0);
    useTask$(({ track }) => {
        track(() => count.value);
        doubled.value = count.value * 2;
    });

    return (
        <div>
            <h3>Signal Demo</h3>
            <p>Count: {count.value}</p>
            <p>Doubled: {doubled.value}</p>
            <p>Text: {text.value}</p>

            <div>
                <button onClick$={increment}>+</button>
                <button onClick$={decrement}>-</button>
                <button onClick$={reset}>Reset</button>
            </div>

            <input
                type="text"
                value={text.value}
                onInput$={(e) => text.value = (e.target as HTMLInputElement).value}
            />

            <button onClick$={toggle}>
                {isVisible.value ? 'Hide' : 'Show'} Content
            </button>

            {isVisible.value && (
                <div>Toggle content is visible!</div>
            )}
        </div>
    );
});

// 2. Complex store
interface Todo {
    id: number;
    text: string;
    completed: boolean;
    createdAt: Date;
}

interface TodoStore {
    todos: Todo[];
    filter: 'all' | 'active' | 'completed';
    newTodoText: string;
}

export const TodoApp = component$(() => {
    const store = useStore<TodoStore>({
        todos: [],
        filter: 'all',
        newTodoText: ''
    });

    const filteredTodos = useSignal<Todo[]>([]);
    const stats = useSignal({ total: 0, completed: 0, active: 0 });

    // Reactive computations
    useTask$(({ track }) => {
        track(() => store.todos);
        track(() => store.filter);

        // Filter todos
        filteredTodos.value = store.todos.filter(todo => {
            switch (store.filter) {
                case 'active':
                    return !todo.completed;
                case 'completed':
                    return todo.completed;
                default:
                    return true;
            }
        });

        // Update stats
        stats.value = {
            total: store.todos.length,
            completed: store.todos.filter(todo => todo.completed).length,
            active: store.todos.filter(todo => !todo.completed).length
        };
    });

    const addTodo = $((event: Event) => {
        event.preventDefault();
        if (store.newTodoText.trim()) {
            store.todos.push({
                id: Date.now(),
                text: store.newTodoText.trim(),
                completed: false,
                createdAt: new Date()
            });
            store.newTodoText = '';
        }
    });

    const toggleTodo = $((id: number) => {
        const todo = store.todos.find(t => t.id === id);
        if (todo) {
            todo.completed = !todo.completed;
        }
    });

    const deleteTodo = $((id: number) => {
        const index = store.todos.findIndex(t => t.id === id);
        if (index !== -1) {
            store.todos.splice(index, 1);
        }
    });

    const clearCompleted = $(() => {
        store.todos = store.todos.filter(todo => !todo.completed);
    });

    const setFilter = $((filter: 'all' | 'active' | 'completed') => {
        store.filter = filter;
    });

    return (
        <div>
            <h3>Todo App</h3>

            <form onSubmit$={addTodo}>
                <input
                    type="text"
                    value={store.newTodoText}
                    onInput$={(e) => store.newTodoText = (e.target as HTMLInputElement).value}
                    placeholder="What needs to be done?"
                />
                <button type="submit">Add</button>
            </form>

            <div class="filters">
                <button
                    class={store.filter === 'all' ? 'active' : ''}
                    onClick$={() => setFilter('all')}
                >
                    All ({stats.value.total})
                </button>
                <button
                    class={store.filter === 'active' ? 'active' : ''}
                    onClick$={() => setFilter('active')}
                >
                    Active ({stats.value.active})
                </button>
                <button
                    class={store.filter === 'completed' ? 'active' : ''}
                    onClick$={() => setFilter('completed')}
                >
                    Completed ({stats.value.completed})
                </button>
            </div>

            <ul>
                {filteredTodos.value.map((todo) => (
                    <li key={todo.id} class={todo.completed ? 'completed' : ''}>
                        <input
                            type="checkbox"
                            checked={todo.completed}
                            onClick$={() => toggleTodo(todo.id)}
                        />
                        <span>{todo.text}</span>
                        <button onClick$={() => deleteTodo(todo.id)}>Delete</button>
                    </li>
                ))}
            </ul>

            {stats.value.completed > 0 && (
                <button onClick$={clearCompleted}>
                    Clear Completed ({stats.value.completed})
                </button>
            )}
        </div>
    );
});

// 3. Shopping cart with nested stores
interface CartItem {
    id: number;
    name: string;
    price: number;
    quantity: number;
}

interface CartStore {
    items: CartItem[];
    isOpen: boolean;
    couponCode: string;
    discount: number;
}

export const ShoppingCart = component$(() => {
    const cart = useStore<CartStore>({
        items: [],
        isOpen: false,
        couponCode: '',
        discount: 0
    });

    const total = useSignal(0);
    const subtotal = useSignal(0);
    const itemCount = useSignal(0);

    // Reactive calculations
    useTask$(({ track }) => {
        track(() => cart.items);
        track(() => cart.discount);

        subtotal.value = cart.items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
        total.value = subtotal.value - (subtotal.value * cart.discount);
        itemCount.value = cart.items.reduce((sum, item) => sum + item.quantity, 0);
    });

    const addItem = $((item: Omit<CartItem, 'quantity'>) => {
        const existingItem = cart.items.find(i => i.id === item.id);
        if (existingItem) {
            existingItem.quantity++;
        } else {
            cart.items.push({ ...item, quantity: 1 });
        }
    });

    const removeItem = $((id: number) => {
        const index = cart.items.findIndex(item => item.id === id);
        if (index !== -1) {
            cart.items.splice(index, 1);
        }
    });

    const updateQuantity = $((id: number, quantity: number) => {
        const item = cart.items.find(item => item.id === id);
        if (item) {
            if (quantity <= 0) {
                removeItem(id);
            } else {
                item.quantity = quantity;
            }
        }
    });

    const toggleCart = $(() => {
        cart.isOpen = !cart.isOpen;
    });

    const applyCoupon = $(() => {
        // Simple coupon logic
        if (cart.couponCode === 'SAVE10') {
            cart.discount = 0.1;
        } else if (cart.couponCode === 'SAVE20') {
            cart.discount = 0.2;
        }
    });

    return (
        <div>
            <button onClick$={toggleCart}>
                Cart ({itemCount.value}) - ${total.value.toFixed(2)}
            </button>

            {cart.isOpen && (
                <div class="cart-modal">
                    <h3>Shopping Cart</h3>

                    {cart.items.length === 0 ? (
                        <p>Your cart is empty</p>
                    ) : (
                        <>
                            <ul>
                                {cart.items.map((item) => (
                                    <li key={item.id}>
                                        <div>
                                            <h4>{item.name}</h4>
                                            <p>${item.price} x {item.quantity} = ${(item.price * item.quantity).toFixed(2)}</p>
                                        </div>
                                        <div>
                                            <input
                                                type="number"
                                                value={item.quantity}
                                                min="1"
                                                onInput$={(e) => updateQuantity(item.id, parseInt((e.target as HTMLInputElement).value))}
                                            />
                                            <button onClick$={() => removeItem(item.id)}>Remove</button>
                                        </div>
                                    </li>
                                ))}
                            </ul>

                            <div class="cart-summary">
                                <p>Subtotal: ${subtotal.value.toFixed(2)}</p>
                                <p>Discount: {(cart.discount * 100).toFixed(0)}%</p>
                                <p><strong>Total: ${total.value.toFixed(2)}</strong></p>
                            </div>

                            <div class="coupon">
                                <input
                                    type="text"
                                    value={cart.couponCode}
                                    onInput$={(e) => cart.couponCode = (e.target as HTMLInputElement).value}
                                    placeholder="Coupon code"
                                />
                                <button onClick$={applyCoupon}>Apply</button>
                            </div>

                            <button onClick$={() => cart.items = []}>Clear Cart</button>
                        </>
                    )}

                    <button onClick$={toggleCart}>Close</button>
                </div>
            )}
        </div>
    );
});

// 4. Data fetching with stores
interface User {
    id: number;
    name: string;
    email: string;
    posts: Post[];
}

interface Post {
    id: number;
    title: string;
    body: string;
}

export const UserDashboard = component$(() => {
    const user = useStore<User | null>(null);
    const loading = useSignal(true);
    const error = useSignal<string | null>(null);

    // Resource for fetching user data
    const userResource = useResource$<User>(async ({ track }) => {
        track(() => {/* Track any signals if needed */});

        try {
            // Simulate API call
            await new Promise(resolve => setTimeout(resolve, 2000));

            return {
                id: 1,
                name: 'John Doe',
                email: '[email protected]',
                posts: [
                    { id: 1, title: 'First Post', body: 'This is my first post' },
                    { id: 2, title: 'Second Post', body: 'This is my second post' }
                ]
            };
        } catch (err) {
            error.value = err instanceof Error ? err.message : 'Unknown error';
            throw err;
        }
    });

    const refreshData = $(async () => {
        loading.value = true;
        error.value = null;
        // Resource will automatically refetch
    });

    return (
        <div>
            <h2>User Dashboard</h2>
            <button onClick$={refreshData}>Refresh Data</button>

            <Resource
                value={userResource}
                onPending={() => <div>Loading user data...</div>}
                onRejected={(error) => <div>Error: {error.message}</div>}
                onResolved={(userData) => {
                    // Store the resolved data
                    user.value = userData;
                    loading.value = false;
                    return null; // We'll render from the store
                }}
            />

            {user.value && !loading.value && (
                <div>
                    <div class="user-info">
                        <h3>{user.value.name}</h3>
                        <p>{user.value.email}</p>
                    </div>

                    <div class="user-posts">
                        <h4>Posts ({user.value.posts.length})</h4>
                        <ul>
                            {user.value.posts.map((post) => (
                                <li key={post.id}>
                                    <h5>{post.title}</h5>
                                    <p>{post.body}</p>
                                </li>
                            ))}
                        </ul>
                    </div>
                </div>
            )}
        </div>
    );
});

// 5. Global state management
interface AppState {
    theme: 'light' | 'dark';
    user: User | null;
    notifications: string[];
}

// This would typically be in a separate file and used with context
export const createAppStore = (): AppState => ({
    theme: 'light',
    user: null,
    notifications: []
});

export const ThemeToggle = component$(() => {
    const appState = useStore(createAppStore());

    const toggleTheme = $(() => {
        appState.theme = appState.theme === 'light' ? 'dark' : 'light';
    });

    return (
        <div class={`theme-${appState.theme}`}>
            <button onClick$={toggleTheme}>
                Current theme: {appState.theme}
            </button>
        </div>
    );
});

export { SignalDemo, TodoApp, ShoppingCart, UserDashboard, ThemeToggle };

💻 Asynchron und Lazy Loading in Qwik typescript

🔴 complex

Asynchrone Operationen, Lazy Loading und resumable Rendering in Qwik

// Qwik Async and Lazy Loading

import {
    component$,
    useSignal,
    useStore,
    useTask$,
    $,
    useResource$,
    Resource,
    useVisibleTask$,
    lazy$,
    useStylesScoped$
} from '@builder.io/qwik';

// 1. Lazy loaded component
export const LazyComponent = component$(() => {
    const isVisible = useSignal(false);
    const data = useSignal<string>('');

    useVisibleTask$(() => {
        isVisible.value = true;
        // Load data only when component is visible
        setTimeout(() => {
            data.value = 'Lazy loaded data!';
        }, 1000);
    });

    return (
        <div>
            <h3>Lazy Component</h3>
            {isVisible.value ? (
                <div>
                    <p>Component is now visible!</p>
                    <p>{data.value || 'Loading...'}</p>
                </div>
            ) : (
                <p>Component will load when visible...</p>
            )}
        </div>
    );
});

// 2. Using lazy$ for code splitting
const HeavyComponent = lazy$(() => import('./heavy-component'));

export const LazyLoadDemo = component$(() => {
    const showHeavyComponent = useSignal(false);

    return (
        <div>
            <h3>Lazy Load Demo</h3>
            <button
                onClick$={() => showHeavyComponent.value = true}
            >
                Load Heavy Component
            </button>

            {showHeavyComponent.value && (
                <HeavyComponent />
            )}
        </div>
    );
});

// 3. Resource management with cleanup
export const ResourceManagement = component$(() => {
    const data = useSignal<string[]>([]);
    const loading = useSignal(false);
    const error = useSignal<string | null>(null);
    const intervalId = useSignal<number | null>(null);

    const startPolling = $(() => {
        loading.value = true;
        error.value = null;

        // Simulate polling API
        intervalId.value = window.setInterval(async () => {
            try {
                // Simulate API call
                await new Promise(resolve => setTimeout(resolve, 1000));
                const newData = `Data ${Date.now()}`;
                data.value = [...data.value, newData];
                loading.value = false;
            } catch (err) {
                error.value = err instanceof Error ? err.message : 'Unknown error';
                loading.value = false;
            }
        }, 2000);
    });

    const stopPolling = $(() => {
        if (intervalId.value) {
            clearInterval(intervalId.value);
            intervalId.value = null;
        }
    });

    const clearData = $(() => {
        data.value = [];
    });

    // Cleanup on unmount
    useVisibleTask$(({ cleanup }) => {
        cleanup(() => {
            stopPolling();
        });
    });

    return (
        <div>
            <h3>Resource Management</h3>

            <div>
                <button onClick$={startPolling}>Start Polling</button>
                <button onClick$={stopPolling}>Stop Polling</button>
                <button onClick$={clearData}>Clear Data</button>
            </div>

            {loading.value && <p>Loading...</p>}
            {error.value && <p style="color: red">Error: {error.value}</p>}

            <ul>
                {data.value.map((item, index) => (
                    <li key={index}>{item}</li>
                ))}
            </ul>

            <p>Status: {intervalId.value ? 'Polling' : 'Stopped'}</p>
        </div>
    );
});

// 4. Advanced async patterns
interface AsyncData {
    id: number;
    title: string;
    description: string;
    metadata: {
        created: Date;
        updated: Date;
        tags: string[];
    };
}

export const AsyncPatterns = component$(() => {
    const items = useSignal<AsyncData[]>([]);
    const loading = useSignal(false);
    const currentFilter = useSignal('all');

    // Complex resource with filtering and caching
    const itemsResource = useResource$<AsyncData[]>(async ({ track }) => {
        track(() => currentFilter.value);

        loading.value = true;

        try {
            // Simulate API call with different endpoints based on filter
            let endpoint = '/api/items';
            if (currentFilter.value !== 'all') {
                endpoint += `?filter=${currentFilter.value}`;
            }

            console.log('Fetching from:', endpoint);

            // Simulate network delay and different responses
            await new Promise(resolve => setTimeout(resolve, 1500));

            const allItems: AsyncData[] = [
                {
                    id: 1,
                    title: 'Item 1',
                    description: 'Description for item 1',
                    metadata: {
                        created: new Date('2023-01-01'),
                        updated: new Date('2023-12-01'),
                        tags: ['tag1', 'tag2']
                    }
                },
                {
                    id: 2,
                    title: 'Item 2',
                    description: 'Description for item 2',
                    metadata: {
                        created: new Date('2023-02-01'),
                        updated: new Date('2023-11-01'),
                        tags: ['tag2', 'tag3']
                    }
                },
                {
                    id: 3,
                    title: 'Item 3',
                    description: 'Description for item 3',
                    metadata: {
                        created: new Date('2023-03-01'),
                        updated: new Date('2023-10-01'),
                        tags: ['tag1', 'tag3']
                    }
                }
            ];

            // Apply filtering logic
            let filteredItems = allItems;
            if (currentFilter.value !== 'all') {
                filteredItems = allItems.filter(item =>
                    item.metadata.tags.includes(currentFilter.value)
                );
            }

            return filteredItems;
        } catch (err) {
            console.error('Failed to fetch items:', err);
            throw err;
        } finally {
            loading.value = false;
        }
    });

    const setFilter = $((filter: string) => {
        currentFilter.value = filter;
    });

    const refreshItems = $(() => {
        // Force resource refetch by changing a dependency
        const temp = currentFilter.value;
        currentFilter.value = '';
        setTimeout(() => {
            currentFilter.value = temp;
        }, 10);
    });

    return (
        <div>
            <h3>Advanced Async Patterns</h3>

            <div class="filters">
                <button
                    class={currentFilter.value === 'all' ? 'active' : ''}
                    onClick$={() => setFilter('all')}
                >
                    All
                </button>
                <button
                    class={currentFilter.value === 'tag1' ? 'active' : ''}
                    onClick$={() => setFilter('tag1')}
                >
                    Tag 1
                </button>
                <button
                    class={currentFilter.value === 'tag2' ? 'active' : ''}
                    onClick$={() => setFilter('tag2')}
                >
                    Tag 2
                </button>
                <button
                    class={currentFilter.value === 'tag3' ? 'active' : ''}
                    onClick$={() => setFilter('tag3')}
                >
                    Tag 3
                </button>
                <button onClick$={refreshItems}>Refresh</button>
            </div>

            <Resource
                value={itemsResource}
                onPending={() => <div>Loading items...</div>}
                onRejected={(error) => (
                    <div style="color: red">
                        Error loading items: {error.message}
                    </div>
                )}
                onResolved={(items) => {
                    return (
                        <div>
                            <p>Found {items.length} items</p>
                            <ul>
                                {items.map((item) => (
                                    <li key={item.id} class="item-card">
                                        <h4>{item.title}</h4>
                                        <p>{item.description}</p>
                                        <div class="metadata">
                                            <small>
                                                Created: {item.metadata.created.toLocaleDateString()} |
                                                Updated: {item.metadata.updated.toLocaleDateString()}
                                            </small>
                                            <div class="tags">
                                                {item.metadata.tags.map((tag) => (
                                                    <span key={tag} class="tag">
                                                        {tag}
                                                    </span>
                                                ))}
                                            </div>
                                        </div>
                                    </li>
                                ))}
                            </ul>
                        </div>
                    );
                }}
            />

            {loading.value && <div class="loading-indicator">Processing...</div>}
        </div>
    );
});

// 5. Progressive enhancement with async
export const ProgressiveEnhancement = component$(() => {
    const isClient = useSignal(false);
    const features = useSignal<string[]>([]);

    // Check if we're on the client
    useVisibleTask$(() => {
        isClient.value = true;

        // Detect available features
        const detectedFeatures: string[] = [];
        if ('serviceWorker' in navigator) {
            detectedFeatures.push('Service Worker');
        }
        if ('IntersectionObserver' in window) {
            detectedFeatures.push('Intersection Observer');
        }
        if ('WebAssembly' in window) {
            detectedFeatures.push('WebAssembly');
        }
        if ('localStorage' in window) {
            detectedFeatures.push('Local Storage');
        }

        features.value = detectedFeatures;
    });

    const loadAdvancedFeature = $(async () => {
        if (!isClient.value) return;

        try {
            // Simulate loading an advanced feature
            const module = await import('./advanced-feature');
            console.log('Advanced feature loaded:', module);
            features.value = [...features.value, 'Advanced Feature'];
        } catch (err) {
            console.error('Failed to load advanced feature:', err);
        }
    });

    const testAsyncOperation = $(async () => {
        const result = await new Promise<string>((resolve) => {
            setTimeout(() => {
                resolve('Async operation completed!');
            }, 2000);
        });

        alert(result);
    });

    return (
        <div>
            <h3>Progressive Enhancement</h3>

            <div class="client-info">
                <p>Environment: {isClient.value ? 'Client' : 'Server'}</p>
                {isClient.value && (
                    <div>
                        <p>Available Features:</p>
                        <ul>
                            {features.value.map((feature, index) => (
                                <li key={index}>{feature}</li>
                            ))}
                        </ul>
                    </div>
                )}
            </div>

            {isClient.value && (
                <div class="client-only-features">
                    <button onClick$={loadAdvancedFeature}>
                        Load Advanced Feature
                    </button>
                    <button onClick$={testAsyncOperation}>
                        Test Async Operation
                    </button>
                </div>
            )}

            {!isClient.value && (
                <div class="server-fallback">
                    <p>This content works even without JavaScript!</p>
                </div>
            )}
        </div>
    );
});

// 6. Optimistic updates
export const OptimisticUpdates = component$(() => {
    const posts = useSignal<{ id: number; title: string; likes: number }[]>([
        { id: 1, title: 'Post 1', likes: 5 },
        { id: 2, title: 'Post 2', likes: 3 }
    ]);
    const pendingLikes = useSignal<number[]>([]);

    const likePost = $(async (postId: number) => {
        // Optimistic update
        const post = posts.value.find(p => p.id === postId);
        if (post) {
            post.likes++;
            pendingLikes.value = [...pendingLikes.value, postId];
        }

        try {
            // Simulate API call
            await new Promise(resolve => setTimeout(resolve, 1000));

            // Server succeeded - remove from pending
            pendingLikes.value = pendingLikes.value.filter(id => id !== postId);
        } catch (err) {
            // Revert optimistic update
            if (post) {
                post.likes--;
            }
            pendingLikes.value = pendingLikes.value.filter(id => id !== postId);
            alert('Failed to like post. Please try again.');
        }
    });

    const addComment = $(async (postId: number, comment: string) => {
        if (!comment.trim()) return;

        // Optimistic update would go here
        try {
            // Simulate API call
            await new Promise(resolve => setTimeout(resolve, 1500));
            alert('Comment added successfully!');
        } catch (err) {
            alert('Failed to add comment. Please try again.');
        }
    });

    return (
        <div>
            <h3>Optimistic Updates</h3>

            {posts.value.map((post) => (
                <div key={post.id} class="post">
                    <h4>{post.title}</h4>
                    <div class="post-actions">
                        <button
                            onClick$={() => likePost(post.id)}
                            disabled={pendingLikes.value.includes(post.id)}
                        >
                            {pendingLikes.value.includes(post.id) ? 'Liking...' : `Like (${post.likes})`}
                        </button>
                    </div>
                </div>
            ))}
        </div>
    );
});

// Add some scoped styles
useStylesScoped$(`
    .filters {
        margin-bottom: 1rem;
    }

    .filters button {
        margin-right: 0.5rem;
        padding: 0.5rem 1rem;
        border: 1px solid #ccc;
        background: white;
        cursor: pointer;
    }

    .filters button.active {
        background: #007bff;
        color: white;
        border-color: #007bff;
    }

    .item-card {
        border: 1px solid #ddd;
        padding: 1rem;
        margin-bottom: 1rem;
        border-radius: 4px;
    }

    .metadata {
        margin-top: 0.5rem;
    }

    .tags {
        margin-top: 0.25rem;
    }

    .tag {
        display: inline-block;
        background: #f0f0f0;
        padding: 0.25rem 0.5rem;
        margin-right: 0.25rem;
        border-radius: 3px;
        font-size: 0.8rem;
    }

    .loading-indicator {
        margin-top: 1rem;
        padding: 0.5rem;
        background: #f8f9fa;
        border-left: 4px solid #007bff;
    }

    .post {
        border: 1px solid #ddd;
        padding: 1rem;
        margin-bottom: 1rem;
        border-radius: 4px;
    }

    .post-actions button {
        margin-right: 0.5rem;
    }

    .post-actions button:disabled {
        opacity: 0.6;
        cursor: not-allowed;
    }
`);

export {
    LazyComponent,
    LazyLoadDemo,
    ResourceManagement,
    AsyncPatterns,
    ProgressiveEnhancement,
    OptimisticUpdates
};

💻 Qwik Best Practices und Patterns typescript

🔴 complex

Best Practices, Performance-Patterns und Optimierungstechniken für Qwik-Anwendungen

// Qwik Best Practices and Patterns

import {
    component$,
    useSignal,
    useStore,
    useTask$,
    $,
    useResource$,
    Resource,
    useVisibleTask$,
    useClientEffect$,
    useStylesScoped$,
    useBrowserVisibleTask$
} from '@builder.io/qwik';

// 1. Component decomposition and reusability
interface ButtonProps {
    onClick$: () => void;
    variant?: 'primary' | 'secondary' | 'danger';
    size?: 'small' | 'medium' | 'large';
    disabled?: boolean;
    loading?: boolean;
}

export const Button = component$<ButtonProps>((props) => {
    return (
        <button
            class={`btn btn-${props.variant || 'primary'} btn-${props.size || 'medium'}`}
            onClick$={props.onClick$}
            disabled={props.disabled || props.loading}
        >
            {props.loading ? 'Loading...' : props.children}
        </button>
    );
});

// 2. Custom hooks pattern
export const useDebounce = <T>(value: T, delay: number) => {
    const debouncedValue = useSignal(value);

    useTask$(({ track }) => {
        track(() => value);

        const timer = setTimeout(() => {
            debouncedValue.value = value;
        }, delay);

        return () => clearTimeout(timer);
    });

    return debouncedValue;
};

export const useLocalStorage = <T>(key: string, initialValue: T) => {
    const value = useSignal<T>(initialValue);

    useClientEffect$(() => {
        // Load from localStorage on mount
        const stored = localStorage.getItem(key);
        if (stored !== null) {
            value.value = JSON.parse(stored);
        }

        // Save to localStorage when value changes
        return () => {
            localStorage.setItem(key, JSON.stringify(value.value));
        };
    });

    return value;
};

// 3. Performance optimization patterns
export const VirtualizedList = component$<{
    items: any[];
    itemHeight: number;
    containerHeight: number;
    renderItem: (item: any, index: number) => any;
}>((props) => {
    const scrollTop = useSignal(0);
    const startIndex = useSignal(0);
    const endIndex = useSignal(0);

    useTask$(({ track }) => {
        track(() => scrollTop.value);
        track(() => props.items);

        start = Math.floor(scrollTop.value / props.itemHeight);
        end = Math.min(
            start + Math.ceil(props.containerHeight / props.itemHeight) + 1,
            props.items.length
        );

        startIndex.value = start;
        endIndex.value = end;
    });

    const handleScroll = $((event: Event) => {
        const target = event.target as HTMLElement;
        scrollTop.value = target.scrollTop;
    });

    let start = 0;
    let end = 10;

    return (
        <div
            style={{
                height: `${props.containerHeight}px`,
                overflow: 'auto'
            }}
            onScroll$={handleScroll}
        >
            <div
                style={{
                    height: `${props.items.length * props.itemHeight}px`,
                    position: 'relative'
                }}
            >
                {props.items.slice(startIndex.value, endIndex.value).map((item, index) => (
                    <div
                        key={index}
                        style={{
                            position: 'absolute',
                            top: `${(startIndex.value + index) * props.itemHeight}px`,
                            height: `${props.itemHeight}px`,
                            width: '100%'
                        }}
                    >
                        {props.renderItem(item, startIndex.value + index)}
                    </div>
                ))}
            </div>
        </div>
    );
});

// 4. Error boundaries and error handling
interface ErrorBoundaryProps {
    fallback: (error: Error, reset: () => void) => any;
}

export const ErrorBoundary = component$<ErrorBoundaryProps>((props) => {
    const error = useSignal<Error | null>(null);
    const hasError = useSignal(false);

    useTask$(({ track }) => {
        track(() => props.children);

        // In a real implementation, you would catch errors from children
        // This is a simplified example
    });

    const reset = $(() => {
        error.value = null;
        hasError.value = false;
    });

    return (
        <>
            {hasError.value && error.value ? (
                props.fallback(error.value, reset)
            ) : (
                props.children
            )}
        </>
    );
});

// 5. Optimized form handling
export const OptimizedForm = component$(() => {
    const form = useStore({
        email: '',
        password: '',
        errors: {} as Record<string, string>,
        touched: {} as Record<string, boolean>
    });

    const isSubmitting = useSignal(false);
    const debouncedEmail = useDebounce(form.email, 500);
    const emailValid = useSignal(true);

    // Validate email on debounce
    useTask$(({ track }) => {
        track(() => debouncedEmail.value);

        if (form.touched.email) {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            emailValid.value = emailRegex.test(debouncedEmail.value);

            if (!emailValid.value) {
                form.errors.email = 'Please enter a valid email address';
            } else {
                delete form.errors.email;
            }
        }
    });

    const handleFieldBlur = $((fieldName: string) => {
        form.touched[fieldName] = true;
    });

    const handleSubmit = $(async (event: Event) => {
        event.preventDefault();
        isSubmitting.value = true;

        // Mark all fields as touched
        form.touched.email = true;
        form.touched.password = true;

        // Validate all fields
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailRegex.test(form.email)) {
            form.errors.email = 'Please enter a valid email address';
        }

        if (form.password.length < 8) {
            form.errors.password = 'Password must be at least 8 characters';
        }

        // Submit if no errors
        if (Object.keys(form.errors).length === 0) {
            try {
                // Simulate API call
                await new Promise(resolve => setTimeout(resolve, 2000));
                alert('Form submitted successfully!');
            } catch (err) {
                alert('Submission failed. Please try again.');
            }
        }

        isSubmitting.value = false;
    });

    return (
        <form onSubmit$={handleSubmit}>
            <div class="form-group">
                <label>Email:</label>
                <input
                    type="email"
                    value={form.email}
                    onInput$={(e) => form.email = (e.target as HTMLInputElement).value}
                    onBlur$={() => handleFieldBlur('email')}
                    class={form.touched.email && form.errors.email ? 'error' : ''}
                />
                {form.touched.email && form.errors.email && (
                    <span class="error-message">{form.errors.email}</span>
                )}
            </div>

            <div class="form-group">
                <label>Password:</label>
                <input
                    type="password"
                    value={form.password}
                    onInput$={(e) => form.password = (e.target as HTMLInputElement).value}
                    onBlur$={() => handleFieldBlur('password')}
                    class={form.touched.password && form.errors.password ? 'error' : ''}
                />
                {form.touched.password && form.errors.password && (
                    <span class="error-message">{form.errors.password}</span>
                )}
            </div>

            <Button
                type="submit"
                variant="primary"
                loading={isSubmitting.value}
                disabled={isSubmitting.value}
            >
                Submit
            </Button>
        </form>
    );
});

// 6. Memory optimization patterns
export const MemoryOptimizedComponent = component$(() => {
    const data = useSignal<any[]>([]);
    const activeItem = useSignal<any | null>(null);
    const subscriptions = useSignal<(() => void)[]>([]);

    // Proper cleanup pattern
    useVisibleTask$(({ cleanup }) => {
        // Setup subscriptions or timers
        const timer = setInterval(() => {
            console.log('Timer running');
        }, 1000);

        // Add cleanup function
        cleanup(() => {
            clearInterval(timer);

            // Cleanup all subscriptions
            subscriptions.value.forEach(unsubscribe => unsubscribe());
            subscriptions.value = [];
        });
    });

    const loadMoreData = $(async () => {
        // Load data efficiently
        try {
            const response = await fetch('/api/data');
            const newData = await response.json();

            // Process data in chunks to avoid blocking
            const chunkSize = 100;
            for (let i = 0; i < newData.length; i += chunkSize) {
                const chunk = newData.slice(i, i + chunkSize);
                data.value = [...data.value, ...chunk];

                // Allow UI to update
                await new Promise(resolve => setTimeout(resolve, 10));
            }
        } catch (err) {
            console.error('Failed to load data:', err);
        }
    });

    return (
        <div>
            <h3>Memory Optimized Component</h3>
            <button onClick$={loadMoreData}>Load More Data</button>
            <p>Data items: {data.value.length}</p>
        </div>
    );
});

// 7. Responsive design patterns
export const ResponsiveLayout = component$(() => {
    const screenSize = useSignal<'mobile' | 'tablet' | 'desktop'>('desktop');
    const menuOpen = useSignal(false);

    useBrowserVisibleTask$(() => {
        const updateScreenSize = () => {
            const width = window.innerWidth;
            if (width < 768) {
                screenSize.value = 'mobile';
            } else if (width < 1024) {
                screenSize.value = 'tablet';
            } else {
                screenSize.value = 'desktop';
            }
        };

        updateScreenSize();
        window.addEventListener('resize', updateScreenSize);

        return () => {
            window.removeEventListener('resize', updateScreenSize);
        };
    });

    const toggleMenu = $(() => {
        menuOpen.value = !menuOpen.value;
    });

    return (
        <div class={`layout layout-${screenSize.value}`}>
            <header class="header">
                <h1>My App</h1>
                {screenSize.value === 'mobile' && (
                    <button onClick$={toggleMenu}>Menu</button>
                )}
            </header>

            <div class="container">
                <aside class={`sidebar ${menuOpen.value ? 'open' : ''}`}>
                    <nav>
                        <a href="/">Home</a>
                        <a href="/about">About</a>
                        <a href="/contact">Contact</a>
                    </nav>
                </aside>

                <main class="main">
                    <p>Screen size: {screenSize.value}</p>
                    {screenSize.value === 'mobile' && (
                        <p>Mobile menu is {menuOpen.value ? 'open' : 'closed'}</p>
                    )}
                </main>
            </div>
        </div>
    );
});

// 8. Performance monitoring
export const PerformanceMonitor = component$(() => {
    const metrics = useStore({
        renderTime: 0,
        componentCount: 0,
        memoryUsage: 0
    });

    const startTime = useSignal(Date.now());

    useVisibleTask$(() => {
        const endTime = Date.now();
        metrics.renderTime = endTime - startTime.value;

        // Monitor memory usage if available
        if ('memory' in performance) {
            const memory = (performance as any).memory;
            metrics.memoryUsage = Math.round(memory.usedJSHeapSize / 1024 / 1024);
        }

        // Monitor performance metrics
        if ('PerformanceObserver' in window) {
            const observer = new PerformanceObserver((list) => {
                for (const entry of list.getEntries()) {
                    if (entry.entryType === 'measure') {
                        console.log(`Performance measure: ${entry.name} - ${entry.duration}ms`);
                    }
                }
            });
            observer.observe({ entryTypes: ['measure'] });
        }
    });

    return (
        <div class="performance-monitor">
            <h3>Performance Metrics</h3>
            <ul>
                <li>Render time: {metrics.renderTime}ms</li>
                <li>Memory usage: {metrics.memoryUsage}MB</li>
                <li>Components: {metrics.componentCount}</li>
            </ul>
        </div>
    );
});

// Add scoped styles for all components
useStylesScoped$(`
    .btn {
        padding: 0.5rem 1rem;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 0.875rem;
        transition: all 0.2s;
    }

    .btn-primary {
        background: #007bff;
        color: white;
    }

    .btn-secondary {
        background: #6c757d;
        color: white;
    }

    .btn-danger {
        background: #dc3545;
        color: white;
    }

    .btn-small {
        padding: 0.25rem 0.5rem;
        font-size: 0.75rem;
    }

    .btn-medium {
        padding: 0.5rem 1rem;
        font-size: 0.875rem;
    }

    .btn-large {
        padding: 1rem 2rem;
        font-size: 1rem;
    }

    .btn:disabled {
        opacity: 0.6;
        cursor: not-allowed;
    }

    .form-group {
        margin-bottom: 1rem;
    }

    .form-group label {
        display: block;
        margin-bottom: 0.5rem;
        font-weight: 500;
    }

    .form-group input {
        width: 100%;
        padding: 0.5rem;
        border: 1px solid #ddd;
        border-radius: 4px;
    }

    .form-group input.error {
        border-color: #dc3545;
    }

    .error-message {
        color: #dc3545;
        font-size: 0.875rem;
        margin-top: 0.25rem;
        display: block;
    }

    .layout {
        display: flex;
        flex-direction: column;
        min-height: 100vh;
    }

    .header {
        padding: 1rem;
        background: #f8f9fa;
        border-bottom: 1px solid #ddd;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .container {
        display: flex;
        flex: 1;
    }

    .sidebar {
        width: 250px;
        background: #f8f9fa;
        border-right: 1px solid #ddd;
        transition: transform 0.3s;
    }

    .layout-mobile .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        z-index: 1000;
        transform: translateX(-100%);
    }

    .layout-mobile .sidebar.open {
        transform: translateX(0);
    }

    .main {
        flex: 1;
        padding: 1rem;
    }

    .performance-monitor {
        position: fixed;
        bottom: 20px;
        right: 20px;
        background: rgba(0, 0, 0, 0.8);
        color: white;
        padding: 1rem;
        border-radius: 4px;
        font-size: 0.875rem;
    }

    .performance-monitor h3 {
        margin: 0 0 0.5rem 0;
        font-size: 1rem;
    }

    .performance-monitor ul {
        margin: 0;
        padding-left: 1rem;
    }

    .performance-monitor li {
        margin-bottom: 0.25rem;
    }
`);

export {
    Button,
    useDebounce,
    useLocalStorage,
    VirtualizedList,
    ErrorBoundary,
    OptimizedForm,
    MemoryOptimizedComponent,
    ResponsiveLayout,
    PerformanceMonitor
};