<template> <div> <divid="counter">count</div> <buttonid="btn">+1</button> </div> </template> <script> exportdefault { // This is a lifecycle function; we'll ignore it for now because it allows access to DOM elements in mounted mounted() { // Non-reactive data let count = 0; // Render count const counter = document.getElementById("counter"); counter.innerHTML = count; // Method to change count; note if the page updates after the change const btn = document.getElementById("btn"); btn.addEventListener("click", () => { count += 1; console.log(count); }); } } </script>
At this point, when you click the button, the page does not change, but you can see that the count is increasing. To synchronize the page and data changes, we need to use reactive data, which can be defined using data.
Description computed is a feature provided by Vue for declaring computed properties that depend on reactive data. It caches the result based on its dependencies and only recalculates when the dependent data changes.
Deriving new values from multiple reactive data and avoiding redundant calculations.
When complex logic is not suitable to be written directly in templates, computed can be used to return processed values to templates. Example: Concatenate first name and last name to form a full name.
Description watch allows you to listen for changes in reactive data and execute side effects (e.g., asynchronous requests, data cleaning, etc.) when the data changes.
Use Cases
Executing asynchronous or expensive operations when data changes (e.g., calling APIs to fetch data).
Listening for changes in specific fields and making corresponding actions.
Deeply watching changes in object/array internal values (with deep: true).
Listening for route changes to update page content. Example: Trigger an API request when searching in the input box.
<template> <div> <inputv-model="searchQuery"placeholder="Enter keywords to search"> <p>Searching: {{ searchQuery }}</p> </div> </template> <script> exportdefault { data() { return { searchQuery: "" }; }, watch: { searchQuery(newVal) { if (newVal) { console.log("Calling API to search", newVal); // This can be replaced with a real request // fetch(`/api/search?q=${newVal}`) } } } } </script>
methods Methods
Description methods are used to define functions that can be called in templates through event binding or directly. These methods are typically used for handling user interactions, data transformations, etc.
Use Cases
Binding actions triggered by button clicks and other events.
Data processing, formatting output, etc., for non-reactive calculations.
Function calls related to user behavior. Example: Click the button to count and display the number of clicks.
Description The process from the creation to destruction of a Vue instance is called the lifecycle. Vue provides several hook functions that allow you to execute specific logic at different stages.
Common Lifecycle Hooks and Use Cases
Hook Function
Trigger Time
Example Use Case
beforeCreate
After instance initialization, before data observation
Rarely used
created
After instance creation is complete, data is ready
Initialize data, call interfaces to fetch data
beforeMount
Before mounting begins
Almost unused
mounted
After mounting is complete
Manipulate DOM, initialize third-party libraries, get element dimensions
<template> <div> <h2>Component Lifecycle Demo</h2> <p>Component load time: {{ loadedTime }} seconds</p> </div> </template> <script> exportdefault { data() { return { loadedTime: 0, showContent: true, timer: null }; }, beforeCreate() { console.log("🚀 beforeCreate: Instance initialization is complete, but data and methods are not yet initialized"); }, created() { console.log("✅ created: Data is loaded, you can start calling interfaces or initializing data"); // Simulate an asynchronous request setTimeout(() => { console.log("Simulated API request completed"); }, 1000); }, beforeMount() { console.log("🧭 beforeMount: Template compilation is complete, but not yet mounted to the DOM"); }, mounted() { console.log("🎉 mounted: Component has been rendered to the page, you can manipulate DOM or start timers"); this.timer = setInterval(() => { this.loadedTime += 1; }, 1000); }, beforeUpdate() { console.log("🔄 beforeUpdate: Data is about to update, DOM has not yet updated"); }, updated() { console.log("✅ updated: Data and DOM have been synchronized"); }, beforeUnmount() { console.log("🛑 beforeUnmount: Component is about to be destroyed, clean up timers, event listeners, etc."); clearInterval(this.timer); }, unmounted() { console.log("👋 unmounted: Component has been destroyed, all bindings have been removed"); } }; </script>
components Components
Component Data Passing
Parent to Child
Parent components pass data to child components via props, which is a one-way data flow. Parent Component Parent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<template> <div> <h2>Parent Component</h2> <Child:message="parentMsg"/> </div> </template> <script> importChildfrom'./Child.vue'; exportdefault { components: {Child}, data() { return { parentMsg: 'This is a message from the parent component' }; } }; </script>
Child Component Child.vue
1 2 3 4 5 6 7 8 9 10 11
<template> <div> <p>Message received by child component: {{ message }}</p> </div> </template> <script> exportdefault { props: ['message'] }; </script>
Child to Parent
Child components trigger events via $emit and send data to parent components. Parent Component Parent.vue
<template> <div> <button @click="sendToParent">Click to send to parent component</button> </div> </template> <script> exportdefault { methods: { sendToParent() { this.$emit('from-child', 'Hello, I am the child component'); } } }; </script>
Sibling Components
Pass data between non-parent-child components through a common “event bus” or Vuex state management. Create event-bus.js (This syntax is supported in Vue 2; for Vue 3, I implemented a simple solution in the reference code)
Ancestor components provide data via provide, and descendant components receive it via inject, without passing through each level. Ancestor Component GrandParent.vue
Vue 3 introduced the Composition API, which provides a more flexible and reusable way to organize logic code, especially suitable for large projects and logic reuse scenarios.
Basic Concepts
Unlike Vue 2’s Options API, the Composition API is more function-oriented.
Uses the setup() function instead of data, methods, created, etc.
Can use ref, reactive, computed, watch, etc., to manage reactive data.
Vue 3 also provides setup syntax sugar (Syntactic Sugar) for a more concise use of the Composition API. It greatly simplifies the way components are defined, allowing developers to write reactive logic more intuitively and efficiently. In this mode, you do not need to explicitly export the setup() function or return variables used in the template. All variables and functions declared in setup can be used directly in the template.