Production Patterns
Production-ready patterns with live, editable code examples
Loading States
FeedbackDifferent loading patterns for async operations
javascript•Loading States
// Loading States Pattern
const { div, h3, p } = van.tags;
// Mock profile data
const profile = {
name: 'Jane Doe',
title: 'Software Engineer',
bio: 'Passionate about building great user experiences with modern web technologies.',
stats: { posts: 42, followers: 1234, following: 567 }
};
const loadingProfile = van.state(true);
// Simulate loading
setTimeout(() => {
loadingProfile.val = false;
}, 2000);
// Skeleton component
const ProfileSkeleton = () => Card({ class: 'p-6 bg-white space-y-4' },
div({ class: 'flex gap-4 items-center' },
Skeleton({ class: 'w-16 h-16 rounded-full' }),
div({ class: 'flex-1 space-y-2' },
Skeleton({ class: 'h-4 w-32' }),
Skeleton({ class: 'h-3 w-48' })
)
),
Skeleton({ class: 'h-20' }),
div({ class: 'flex gap-4' },
Skeleton({ class: 'h-12 flex-1' }),
Skeleton({ class: 'h-12 flex-1' }),
Skeleton({ class: 'h-12 flex-1' })
)
);
// Actual profile
const ProfileCard = () => Card({ class: 'p-6 bg-white space-y-4' },
div({ class: 'flex gap-4 items-center' },
Avatar({ name: profile.name, class: 'avtrsize-lg' }),
div({ class: 'flex-1' },
p({ class: 'font-semibold' }, profile.name),
p({ class: 'text-sm text-secondary' }, profile.title)
)
),
p({ class: 'text-sm' }, profile.bio),
div({ class: 'flex gap-4 text-center' },
div({ class: 'flex-1' },
p({ class: 'text-lg font-semibold' }, profile.stats.posts),
p({ class: 'text-xs text-secondary' }, 'Posts')
),
div({ class: 'flex-1' },
p({ class: 'text-lg font-semibold' }, profile.stats.followers),
p({ class: 'text-xs text-secondary' }, 'Followers')
),
div({ class: 'flex-1' },
p({ class: 'text-lg font-semibold' }, profile.stats.following),
p({ class: 'text-xs text-secondary' }, 'Following')
)
)
);
return div(
{ class: 'space-y-4' },
h3({ class: 'text-lg font-semibold mb-2' }, 'Loading States'),
() => loadingProfile.val ? ProfileSkeleton() : ProfileCard()
);▶️ Live Preview
Loading States
💡 Click "Edit Code" to modify the example
🔄 Click "Apply Changes" to see your modifications
↩️ Click "Reset" to restore original code
📋 Best Practices
State Management
• Use individual van.state() for each value
• Keep state close to where it's used
• Update arrays immutably with spread operator
• Use arrow functions for reactive values
Performance
• Debounce expensive operations
• Use keys for list items
• Avoid complex computations in render
• Clean up timers and listeners
Component Design
• Accept both props and children
• Use parseArgs for flexibility
• Provide sensible defaults
• Keep components focused
User Experience
• Show loading states
• Provide immediate feedback
• Handle errors gracefully
• Add smooth transitions