Data Proxy in Vue2
Data proxy refers to the process of performing operations (read/write) on one object's properties through another object.
Vue2 Data Proxy Implementation
Vue2 implements data proxy through the Vue instance (vm), allowing operations on properties within the data object. This approach provides several advantages:
- Simplified data access and manipulation
- More intuitive data binding mechanisms
- Better integration with Vue's reactivity system
The fundamental principle involves using Object.defineProperty() to add all properties from the data object to the Vue instance. Each property added to the Vue instance is assigned a getter/setter that internally handles read/write operations on the corresponding property in the data object.
Element and Data Binding Approaches
Vue2 offers multiple methods for binding elements to data:
- Direct element binding
- Template-based binding
- Component-based binding
Event Handling in Vue2
Binding Directives
- v-bind: Establishes one-way data binding, updating the view when data changes
- v-model: Creates two-way data binding, synchronizing data between the model and view
Keyboard Events
Vue2 provides special handling for keyboard events through directives like @keyup, @keydown, and @keypress. These can capture specific key actions and trigger appropriate responses.
Event Modifiers
Vue2 includes several useful event modifiers:
- .prevent: Stops the default browser behavior
- .stop: Halts event propagation
- .once: Ensures the event handler executes only once
- .capture: Enables event capturing mode
- .self: Triggers only when the event target is the element itself
- .passive: Executes the default behavior immediately without waiting for the handler
Computed Properties
Computed properties in Vue2 allow you to declare values that depend on other reactive data. They are cached based on their reactive dependencies and only re-evaluated when those dependencies change.
Watched Properties
The watch option allows you to perform asynchronous operations or expensive operations in response to changing data. Key characteristics include:
- Automatic callback execution when watched properties change
- Requirement that the watched property must exist
- Two implementation approaches: configuration during Vue instantiation or using vm.$watch
Deep Watching
By default, Vue2 watch doesn't detect changes to object internal values. Setting deep: true enables monitoring of nested object changes.
Style Binding
Vue2 offers flexible style binding through:
- Object syntax for conditional styling
- Array syntax for applying multiple styles
- Inline style objects for dynamic styling
Conditional Rendering
Vue2 provides directives for conditional rendering:
- v-if: Renders elements conditionally with full toggling
- v-show: Toggles display property while keeping elements in DOM
- v-else: Specifies else blocks for v-if or v-show
Key Attribute
The key attribute helps Vue identify elements for efficient DOM updates. It should be unique among sibling elements and stable across re-renders.
Vue Data Monitoring Principles
Vue2 implements its reactivity system through Object.defineProperty(), which intercepts property access and modifications to trigger view updates. This approach has limitations with certain data types like arrays and nested objects.
Form Data Collection
Vue2 simplifies form data handling through:
- Two-way binding with v-model
- Form validation directives
- Custom form components
Built-in Directives
Vue2 includes numerous built-in directives for common tasks:
- v-text: Updates text content
- v-html: Updates HTML content
- v-show: Toggles element visibility
- v-if/v-else-if/v-else: Conditional rendering
- v-for: List rendering
- v-on: Event handling
- v-bind: Attribute binding
- v-model: Two-way data binding
- v-slot: Slot content distribution
Custom Directives
Vue2 allows creation of custom directives to extend its functionality. Custom directives can be defined at global or component level and can handle different phases of directive lifecycle.
Vue Lifecycle
Vue2 components follow a specific lifecycle with hooks for different stages:
- beforeCreate: Before instance initialization
- created: After instance creation
- beforeMount: Before DOM mounting
- mounted: After DOM mounting
- beforeUpdate: Before data update
- updated: After data update
- beforeDestroy: Before instance destruction
- destroyed: After instance destruction
Vue Components
Non-Single File Components
Vue2 components can be defined using plain JavaScript objects with options like template, data, methods, etc.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue2 Components Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<university></university>
<person></person>
<hr>
<learner></learner>
</div>
<div id="app2">
<greeting></greeting>
</div>
<script>
// Create University component
const University = Vue.extend({
template: `
<div>
<h2>University Name: {{name}}</h2>
<h2>Location: {{location}}</h2>
</div>
`,
data() {
return {
name: 'Tech Institute',
location: 'San Francisco'
}
}
})
// Create Person component
const Person = Vue.extend({
template: `
<div>
<h2>Person Name: {{personName}}</h2>
<h2>Age: {{age}}</h2>
</div>
`,
data() {
return {
personName: 'Alex Johnson',
age: '28'
}
}
})
// Create Learner component
const Learner = Vue.extend({
template: `
<div>
<h2>Learner: {{learnerName}}</h2>
<h2>Course: {{course}}</h2>
</div>
`,
data() {
return {
learnerName: 'Sarah Miller',
course: 'Advanced Vue2'
}
}
})
// Create Greeting component
const Greeting = Vue.extend({
template: `
<div>
<h1>{{message}} {{role}}</h1>
</div>
`,
data() {
return {
message: 'Welcome to',
role: 'Vue2 Development'
}
}
})
// Global registration
Vue.component('greeting', Greeting)
// First Vue instance
new Vue({
el: '#app',
// Local registration
components: {
university: University,
person: Person,
learner: Learner
}
})
// Second Vue instance
new Vue({
el: '#app2'
})
</script>
</body>
</html>
Single File Components
Vue2 supports single file components (.vue files) that combine template, script, and style in one file:
- University.vue: Contains university-related component code
- Learner.vue: Contains learner-related component code
- App.vue: Root component that combines other components
- main.js: Entry point for the Vue application
- index.html: HTML file that mounts the Vue app
Vue CLI
The Vue CLI provides tools for scaffolding, developing, and maintaining Vue2 applications with features like hot module replacement, linting, and testing integration.
Ref Property
The ref attribute allows direct access to DOM elements or child components from the parent component, enabling direct manipulation or programmatic access.
Props
Props allow parent components to pass data to child components. They enable one-way data flow from parent to child, ensuring predictable data changes.
Mixins
Mixins provide a flexible way to distribute reusable functionality across Vue2 components. They can contain any component option.
Local Mixins
Local mixins are applied to specific components rather than globally.
Plugins
Vue2 plugins add global functionality to Vue applications. They can be installed using Vue.use() and may add methods, properties, or directives.
Scoped Styles
The scoped attribute in style tags ensures CSS rules only apply to the current component, preventing style leakage to other components.
To-Do List Case Study
A practical implementation of a to-do list application demonstrates Vue2 capabilities including:
- Dynamic list rendering
- User input handling
- State management
- Conditional rendering
Browser Local Storage
Vue2 applications can interact with browser local storage through:
- Direct localStorage API usage
- Computed properties that sync with storage
- Custom directives for storage operations
Custom Events
Custom events enable child components to communicate with parent components:
<template>
<div id="app">
<h1>{{ greeting }}</h1>
<Institution :getInstitutionName="getInstitutionName" />
<br />
<Individual v-on:institution-event="handleEvent"></Individual>
<Individual ref="individual" />
</div>
</template>
<script>
import Institution from "./components/Institution.vue";
import Individual from "./components/Individual.vue";
export default {
name: "App",
components: {
Institution,
Individual,
},
data() {
return {
greeting: "Welcome to Vue2",
};
},
methods: {
getInstitutionName(name) {
console.log("Received institution name:", name);
},
handleEvent(data) {
console.log("Custom event triggered with:", data);
},
},
mounted() {
setTimeout(() => {
this.$refs.individual.$on("institution-event", this.handleEvent);
}, 3000);
},
};
</script>
<style scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
margin-top: 60px;
background-color: #f5f5f5;
padding: 20px;
}
</style>
Component Custom Events
Components can emit custom events to communicate with parent components, enabling flexible component interactions.
Global Event Bus
A global event bus allows any components in the application to communicate regardless of their position in the component tree. It's implemented as a Vue instance passed to all components.
Message Subscription and Publishing
Message subscription and publishing patterns enable decoupled communication between components, similar to event buses but with more structured messaging.
NextTick
The Vue.nextTick() method allows delayed execution of code after the next DOM update cycle, ensuring all pending view updates are completed.
Transitions
Vue2 provides transition components for animating element entering and leaving, as well as transition effects for list updates.
Proxy Configuration
Vue CLI allows configuring proxies to handle CORS issues by forwarding API requests to a development server:
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
Cross-origin issues occur when requests violate the same-origin policy (different protocol, domain, or port). Solutions include CORS, JSONP (limited to GET requests), and proxy servers.
Vue Slots
Slots enable component composition by allowing parent components to inject content into child components:
- Default Slots: Basic content distribution
- Named Slots: Multiple slot targets with v-slot directive
- Scoped Slots: Passing data from child to parent slot content
Vuex State Management
Vuex is Vue2's official state management library that provides centralized storage for all components. Key concepts include:
- State: Centralized application data
- Getters: Computed properties for state
- Mutations: Synchronous state changes
- Actions: Asynchronous operations that commit mutations
- Modules: Namespaced state management
Vue2 Routing
Multi-level Routing
Vue Router supports nested routing, allowing complex application structures with parent-child route relationships.
Route Query Parameters
Query parameters are appended to URLs and can be accessed through the $route.query object. They're useful for filtering, pagination, and optional data.
When using route parameters with params, you must use the name property in route configuration rather than path.
Route Guards
Route guards control navigation behavior:
- Global Guards: Applied to all routes
- Per-Route Guards: Applied to specific routes
- In-Component Guards: Defined within components
Vue UI Component Libraries
Popular Vue2 UI libraries include:
- Element UI
- Vuetify
- Quasar Framework
- Ant Design Vue
- Buefy