Skip to content

Vue 3: Introduction

Vue.js is a progressive JavaScript framework for building user interfaces. Vue 3 introduces the Composition API and a completely rewritten reactivity system.

What is Vue 3?

Vue 3 is the latest version of the Vue.js framework, designed to be:

  • Progressive - Gradually adoptable in your project
  • Versatile - Suitable for small and large projects
  • Performant - Optimized reactivity system
  • Modular - Tree-shaking for smaller bundles

Creating a Vue 3 App

javascript
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

Composition API

The Composition API is the new way to organize logic in components:

vue
<script setup>
import { ref, computed, onMounted } from 'vue'

// Reactive state
const count = ref(0)
const message = ref('Hello Vue 3!')

// Computed properties
const doubleCount = computed(() => count.value * 2)

// Methods
const increment = () => {
  count.value++
}

// Lifecycle hook
onMounted(() => {
  console.log('Component mounted!')
})
</script>

<template>
  <div>
    <p>{{ message }}</p>
    <p>Count: {{ count }}</p>
    <p>Double: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

Reactivity: ref and reactive

javascript
import { ref, reactive } from 'vue'

// ref - for primitive values
const count = ref(0)
console.log(count.value) // access with .value

// reactive - for objects
const state = reactive({
  name: 'Mario',
  age: 30,
  roles: ['admin', 'user']
})
console.log(state.name) // direct access

Props and Emits

vue
<!-- ChildComponent.vue -->
<script setup>
const props = defineProps({
  title: String,
  count: {
    type: Number,
    default: 0
  }
})

const emit = defineEmits(['update', 'delete'])

const updateCount = () => {
  emit('update', props.count + 1)
}
</script>

<!-- ParentComponent.vue -->
<template>
  <ChildComponent 
    title="Example" 
    :count="count" 
    @update="count = $event"
  />
</template>

Watch and WatchEffect

javascript
import { ref, watch, watchEffect } from 'vue'

const query = ref('')

// watch - explicit
watch(query, (newVal, oldVal) => {
  console.log(`Query changed from ${oldVal} to ${newVal}`)
})

// watchEffect - automatic
watchEffect(() => {
  console.log('Current query:', query.value)
})

Slots

vue
<!-- Card.vue -->
<template>
  <div class="card">
    <header>
      <slot name="header">Default header</slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<!-- Usage -->
<Card>
  <template #header>
    <h2>Custom title</h2>
  </template>
  <p>Card content</p>
</Card>

Built-in Directives

vue
<template>
  <!-- Attribute binding -->
  <img :src="imageUrl" :alt="imageAlt" />
  
  <!-- Event listeners -->
  <button @click="handleClick">Click</button>
  
  <!-- Conditional rendering -->
  <p v-if="isVisible">Visible</p>
  <p v-else>Hidden</p>
  
  <!-- List rendering -->
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
  
  <!-- Two-way binding -->
  <input v-model="searchQuery" />
  
  <!-- HTML rendering -->
  <div v-html="rawHtml"></div>
</template>

Conclusion

Vue 3 with the Composition API offers a more flexible and type-safe way to organize component logic. It's a powerful yet accessible framework, perfect for projects of any size.

Made with ❤️ by PeterDev
'Ho mio cuGGGino che lo sa fare' cit.