vwf .

Production Patterns

Production-ready patterns with live, editable code examples

Loading States

Feedback

Different loading patterns for async operations

// 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