Vue 3 Framework Overview
Vue 3 is a progressive JavaScript framework designed for building user interfaces. It relies on a reactivity system that automatically updates the DOM when data changes, eliminating the need for manual DOM manipulation.
Project Initialization and Directory Structure
Prerequisites
Ensure Node.js (v18.0 LTS or higher) is installed on your system.
Scaffolding the Project
Execute the following commands in your terminal to create and launch a new project named my-vue-app:
npm create vue@latest
cd my-vue-app
npm install
npm run devNavigate to http://localhost:5173/ in your browser to view the default application.
Directory Architecture
my-vue-app/
├── node_modules/ # Dependencies
├── public/ # Static assets
├── src/ # Source code
│ ├── assets/ # Images and global styles
│ ├── components/ # Reusable UI components
│ ├── views/ # Route-level components
│ ├── router/ # Routing configuration
│ ├── stores/ # Global state management
│ ├── App.vue # Root component
│ └── main.js # Application entry point
├── index.html # HTML entry point
└── package. # Project metadata and dependenciesSingle File Component Syntax
Vue applications are built using .vue files, which encapsulate template, logic, and styles:
<template>
<div class="container">Application Content</div>
</template>
<script setup>
// Component logic and reactivity
</script>
<style scoped>
/* Component-scoped styles */
</style>Reactive State Management
Primitive Values with ref
Use ref for primitive data types (strings, numbers, booleans). Access or modify the value using the .value property in the script block.
<template>
<div>
<p>User: {{ userName }}</p>
<p>Age: {{ userAge }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const userName = ref('John Doe')
const userAge = ref(25)
userAge.value = 26
</script>Complex Objects with reactive
Use reactive for objects and arrays. Direct property mutation is allowed without .value.
<template>
<div>
<p>Account: {{ accountDetails.alias }}</p>
<p>Completion: {{ accountDetails.completionRate }}%</p>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const accountDetails = reactive({
alias: 'Developer',
completionRate: 45
})
accountDetails.completionRate = 60
</script>Event Handling and Data Binding
Click Events
Attach event listeners using the @ directive.
<template>
<p>Counter: {{ counter }}</p>
<button @click="increment">Increment</button>
</template>
<script setup>
import { ref } from 'vue'
const counter = ref(0)
const increment = () => {
counter.value++
}
</script>Two-Way Binding
Sync form input values with reactive state using v-model.
<template>
<input type="text" v-model="textInput" placeholder="Enter text" />
<p>Live output: {{ textInput }}</p>
</template>
<script setup>
import { ref } from 'vue'
const textInput = ref('')
</script>Component Communication
Child Component Definition
Create a file at src/components/SubComponent.vue.
Parent-to-Child (Props)
Child component consuming the prop:
<!-- SubComponent.vue -->
<template>
<div>
<p>Received message: {{ titleMessage }}</p>
</div>
</template>
<script setup>
defineProps({
titleMessage: String
})
</script>Parent component passing the prop:
<!-- App.vue -->
<template>
<SubComponent titleMessage="Data from parent" />
</template>
<script setup>
import SubComponent from './components/SubComponent.vue'
</script>Child-to-Parent (Emits)
Child component emitting an event:
<!-- SubComponent.vue -->
<template>
<button @click="dispatchToParent">Send to Parent</button>
</template>
<script setup>
const emit = defineEmits(['notifyParent'])
const dispatchToParent = () => {
emit('notifyParent', 'Operation successful')
}
</script>Parent component listening for the event:
<!-- App.vue -->
<template>
<SubComponent @notify-parent="processChildData" />
<p v-if="receivedPayload">Child says: {{ receivedPayload }}</p>
</template>
<script setup>
import { ref } from 'vue'
import SubComponent from './components/SubComponent.vue'
const receivedPayload = ref('')
const processChildData = (payload) => {
receivedPayload.value = payload
}
</script>Component Lifecycle
Execute logic after the component is mounted using onMounted. This is commonly used for initial data fetching.
<script setup>
import { ref, onMounted } from 'vue'
const initialPayload = ref('')
onMounted(() => {
initialPayload.value = 'Initialization complete'
console.log('Component mounted')
})
</script>Client-Side Routing
Installation
npm install vue-router@4Router Configuration
Create src/router/index.js:
import { createRouter, createWebHistory } from 'vue-router'
import Dashboard from '../views/Dashboard.vue'
import Settings from '../views/Settings.vue'
const pathMappings = [
{ path: '/', redirect: '/dashboard' },
{ path: '/dashboard', component: Dashboard },
{ path: '/settings', component: Settings }
]
const routerInstance = createRouter({
history: createWebHistory(),
routes: pathMappings
})
export default routerInstanceApplication Mounting
Update src/main.js:
import { createApp } from 'vue'
import App from './App.vue'
import routerInstance from './router'
const application = createApp(App)
application.use(routerInstance)
application.mount('#app')Navigation Implementation
Modify src/App.vue:
<template>
<nav>
<router-link to="/dashboard">Dashboard</router-link>
<router-link to="/settings">Settings</router-link>
</nav>
<router-view />
</template>Global State with Pinia
Installation
npm install piniaStore Definition
Create src/stores/auth.js:
import { defineStore } from 'pinia'
export const useAuthStore = defineStore('auth', {
state: () => ({
authKey: 'default-key-xyz'
}),
actions: {
updateAuthKey(newKey) {
this.authKey = newKey
}
}
})Store Consumption
<script setup>
import { useAuthStore } from './stores/auth'
const authStore = useAuthStore()
// Read state
console.log(authStore.authKey)
// Update state
authStore.updateAuthKey('updated-key-abc')
</script>UI Integration with Element Plus
Installation
npm install element-plusGlobal Registration
Update src/main.js:
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const application = createApp(App)
application.use(ElementPlus)
application.mount('#app')Component Usage
<template>
<el-button type="success">Submit</el-button>
<el-input placeholder="Enter credentials"></el-input>
</template>