Learn more about Vue.js

Create Exceptional User Experiences with Vue.js

Vue.js is a progressive JavaScript framework for building user interfaces that focuses on simplicity, flexibility, and performance. With an incrementally adoptable architecture, Vue allows you to start small and progressively integrate more of its features as your application grows in complexity.

Why Vue.js is the Smart Choice for Modern Web Development:

  • Gentle Learning Curve: Vue’s intuitive API and comprehensive documentation make it accessible to developers of all skill levels. The ability to start with simple script tags and gradually adopt more advanced features means teams can be productive quickly without a steep learning curve.

  • Component-Based Architecture: Vue’s single-file components combine HTML, CSS, and JavaScript in one file, creating self-contained, reusable building blocks that promote code organization and maintainability as applications scale.

  • Reactive Data Binding: Vue’s reactivity system automatically tracks dependencies and optimally updates the DOM when data changes, simplifying state management while maintaining excellent performance. This makes creating dynamic, responsive interfaces straightforward.

  • Rich Ecosystem with Official Libraries: Vue provides official libraries for routing (Vue Router), state management (Pinia/Vuex), and build tooling (Vite), ensuring a cohesive development experience while maintaining the flexibility to choose alternatives when needed.

  • Versatile Deployment Options: Whether you’re enhancing existing applications or building new ones, Vue works seamlessly in various scenarios—from progressive enhancement of traditional websites to sophisticated single-page applications and server-side rendered solutions with Nuxt.js.

Vue.js empowers businesses to deliver polished, interactive web experiences without sacrificing developer productivity or application performance. Its balance of simplicity and power makes it an excellent choice for projects of any size, from small interactive components to enterprise-grade applications.

Interactive Demos

TypeWriter Demo

1/4
Vue.js Features

TypeWriterDemo.vue

<template>
  <div class="typewriter-demo w-full">
    <!-- DaisyUI card with mockup code for typewriter effect -->
    <div class="card w-full bg-base-200 shadow-xl">
      <div class="card-body p-4">
        <h3 class="card-title text-sm">TypeWriter Demo</h3>
        
        <!-- DaisyUI mockup code block -->
        <div class="mockup-code bg-primary text-primary-content">
          <pre><code>{{ displayedText }}<span class="animate-pulse">█</span></code></pre>
        </div>
        
        <!-- DaisyUI indicator showing current phrase -->
        <div class="flex justify-between items-center mt-2">
          <div class="badge badge-sm">{{ currentPhraseIndex + 1 }}/{{ phrases.length }}</div>
          <div class="text-xs opacity-70">Vue.js Features</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'

// Vue.js features to display
const phrases = [
  '// Reactive state management',
  '// Single-file components',
  '// Composable functions',
  '// Seamless TypeScript integration'
]

const displayedText = ref('')
const currentPhraseIndex = ref(0)
const currentCharIndex = ref(0)
const isDeleting = ref(false)
let timer: number | null = null

const typeEffect = () => {
  const currentPhrase = phrases[currentPhraseIndex.value]
  
  if (isDeleting.value) {
    displayedText.value = currentPhrase.substring(0, currentCharIndex.value - 1)
    currentCharIndex.value--
    
    if (currentCharIndex.value === 0) {
      isDeleting.value = false
      currentPhraseIndex.value = (currentPhraseIndex.value + 1) % phrases.length
      setTimeout(typeEffect, 500) // Pause before typing next phrase
      return
    }
  } else {
    displayedText.value = currentPhrase.substring(0, currentCharIndex.value + 1)
    currentCharIndex.value++
    
    if (currentCharIndex.value === currentPhrase.length) {
      isDeleting.value = true
      setTimeout(typeEffect, 1500) // Pause before deleting
      return
    }
  }
  
  // Randomize typing speed for natural effect
  const speed = isDeleting.value ? 50 : 100 + Math.random() * 50
  timer = setTimeout(typeEffect, speed) as unknown as number
}

onMounted(() => {
  timer = setTimeout(typeEffect, 500) as unknown as number
})

onUnmounted(() => {
  if (timer) clearTimeout(timer)
})
</script>
Counter Demo
0
Try the buttons below
Zero

CounterDemo.vue

<template>
  <div class="counter-demo w-full">
    <!-- DaisyUI stat component for displaying counter -->
    <div class="stats shadow w-full bg-base-200">
      <div class="stat">
        <div class="stat-title">Counter Demo</div>
        <div class="stat-value text-primary">{{ count }}</div>
        <div class="stat-desc">Try the buttons below</div>
        <div class="stat-actions flex gap-2 mt-2">
          <button class="btn btn-sm btn-primary" @click="increment">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
              <path fill-rule="evenodd" d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clip-rule="evenodd" />
            </svg>
            Increment
          </button>
          <button class="btn btn-sm btn-outline" @click="decrement">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
              <path fill-rule="evenodd" d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd" />
            </svg>
            Decrement
          </button>
        </div>
      </div>
    </div>
    
    <!-- DaisyUI progress bar showing count visually -->
    <progress 
      class="progress progress-primary w-full mt-4" 
      :value="Math.abs(count)" 
      :max="10"
    ></progress>
    
    <!-- DaisyUI badge showing positive/negative status -->
    <div class="flex justify-center mt-2">
      <div 
        class="badge" 
        :class="{
          'badge-success': count > 0,
          'badge-error': count < 0,
          'badge-neutral': count === 0
        }"
      >
        {{ count > 0 ? 'Positive' : count < 0 ? 'Negative' : 'Zero' }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}

function decrement() {
  count.value--
}
</script>