JavaScript Prototypes
In JavaScript, prototypes allow objects to inherit properties and methods. When a property is accessed on an object, the engine checks the object itself first; if not found, it checks the prototype chain.
ES6 classes provide syntactic sugar over the prototype-based inheritance model.
class Entity {
constructor(identifier) {
this.identifier = identifier;
}
}
const instance = new Entity('Alpha');
console.log(instance.identifier); // Output: 'Alpha'
// Adding a property to the prototype makes it available to all instances
Entity.prototype.status = 'active';
console.log(instance.status); // Output: 'active'
// This mechanism is often used in Vue to inject global properties
// Vue.prototype.$http = ... makes $http available in all components
Vue Project Environment Setup
The Vue ecosystem relies on Node.js and npm (Node Package Manager), analogous to Python and pip. To scaffold a new project:
- Install CLI:
npm install -g @vue/cli. - Create Project: Run
vue create my-projector use the GUI withvue ui. Ensure Babel is selected to transpile ES6+ code to ES5. - Restore Dependencies: If checking out an existing project, run
npm installinside the project root to generate thenode_modulesfolder based onpackage.json. - Run Server: Execute
npm run serveto start the development hot-reload server.
Project Directory Structure
- node_modules: Contains all installed third-party dependencies. Excluded from version control.
- public/index.html: The single entry HTML file containing the mounting pointt.
- src: The main development folder.
- assets: Static resources like images and CSS.
- components: Reusable child components.
- views: Page-level components mapped to routes.
- router/index.js: Defines URL-to-component mappings.
- App.vue: The root component.
- main.js: The application entry point that initializes the Vue instance.
Application Lifecycle and Initialization
The application boots up via main.js. It creates a new Vue instance, injects global configurations (router, store), and mounts the root component to the DOM.
// main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
new Vue({
router, // Inject router plugin
render: h => h(App) // Render the root component
}).$mount('#app'); // Mount to the #app div in public/index.html
The router configuration maps paths to components. Navigation links (<router-link>) render as anchor tags, while <router-view> acts as a placeholder where the matched route component renders.
Component Architecture
Vue components are typically composed of three sections: <template> (HTML), <script> (Logic), and <style> (CSS). Child components must be imported and registered in the parent's components object.
Parent-Child Communication Example
The following example demonstrates a tabbed interface where a parent controls the active category and passes data to child components. Children emit events back to the parent to update shared state.
<!-- ParentComponent.vue -->
<template>
<div>
<button
v-for="tab in tabs"
:key="tab"
@click="currentTab = tab"
:class="{ active: currentTab === tab }">
{{ tab }}
</button>
<div v-if="currentTab === 'products'">
<product-card
v-for="item in inventory"
:key="item.id"
:product="item"
@selection-update="handleSelection">
</product-card>
</div>
<h2>Status: {{ statusMessage }}</h2>
</div>
</template>
<script>
import ProductCard from './ProductCard.vue';
export default {
components: { ProductCard },
data() {
return {
tabs: ['products', 'services'],
currentTab: 'products',
inventory: [{id: 1, name: 'Laptop'}, {id: 2, name: 'Phone'}],
statusMessage: 'Nothing selected'
};
},
methods: {
handleSelection(itemName) {
this.statusMessage = `${itemName} selected`;
}
}
};
</script>
<!-- ProductCard.vue -->
<template>
<div class="card" @click="selectItem">
<h3>{{ product.name }}</h3>
</div>
</template>
<script>
export default {
props: ['product'],
methods: {
selectItem() {
this.$emit('selection-update', this.product.name);
}
}
};
</script>
Global Styles
To apply CSS globally, define a stylesheet in src/assets/css/global.css and import it in main.js.
// main.js
import './assets/css/global.css'; // Global CSS import
Component-scoped style are achieved by adding the scoped attribute to the <style> tag, ensuring CSS only applies to that specific component.
Routing Logic
Beyond declarative navigation with <router-link>, programmatic navigation uses this.$router.
- Push:
this.$router.push('/path')orthis.$router.push({ name: 'routeName' })navigates to a specific URL. - Go:
this.$router.go(-1)moves backward or forward in history. - Redirect: Configure redirects in the router file.
// router/index.js
const routes = [
{ path: '/', redirect: '/home' },
{ path: '/home', name: 'home', component: HomeView }
];
Component Lifecycle Hooks
Every component instance goes through a lifecycle. Key hooks include:
- created: Instance is created; data is reactive. Ideal for initial API calls.
- mounted: DOM is randered. Good for DOM manipulation or third-party library integration.
- destroyed: Instance is removed. Useful for cleanup (clearing timers, event listeners).
export default {
data() {
return { apiData: null };
},
created() {
console.log('Component instance created');
// Fetch data here
},
mounted() {
console.log('DOM mounted');
},
destroyed() {
console.log('Component destroyed');
}
};
Route Parameters
Data can be passed between routes via URL parameters.
Method 1: Query Parameters
Navigate using a query string: /detail?id=123.
// Navigating
this.$router.push({ path: '/detail', query: { id: '123' } });
// Accessing in the target component
const id = this.$route.query.id;
Method 2: Dynamic Routes (Params)
Define the route with a placeholder: path: '/detail/:id'.
// router/index.js
{ path: '/detail/:id', name: 'detail', component: DetailView }
// Navigating
this.$router.push({ name: 'detail', params: { id: '123' } });
// Accessing in the target component
const id = this.$route.params.id;