Logic Reuse and Performance Optimization | Online Tutorial
URL Source: https://example.com/vue3/vue3-taskhub-optimization.html
Logic Reuse: Custom Composables (Hooks)
Composables are the essence of Vue 3, allowing us to extract logic (State + Actions) into independent functions.
useLocalStorage: Extract Data Persistence Logic
No longer manually write localStorage.getItem in every Store or component.
// src/composables/useLocalStorage.js
import{ ref, watch } from 'vue';
export function useLocalStorage(key, defaultValue =null){
// 1. Initialize data
const storedValue = localStorage.getItem(key);
const data = ref(storedValue ? JSON.parse(storedValue): defaultValue);
// 2. Listen for changes and auto-synchronize
watch(data,(newValue)=>{
localStorage.setItem(key, JSON.stringify(newValue));
},{ deep:true});
return data;
}
useNotification: Extract Common UI Logic
Implement a simple notification prompt feature.
// src/composables/useNotification.js
import{ ref } from 'vue';
export function useNotification(){
const message = ref('');
const isVisible = ref(false);
const notify =(msg, duration =2000)=>{
message.value= msg;
isVisible.value=true;
setTimeout(()=>{
isVisible.value=false;
}, duration);
};
return{ message, isVisible, notify };
}
Performance Optimization: Handling Large Data Volumes and Frequent Rendering
When your TaskHub grows from managing 10 tasks to managing 1,000 tasks, Vueβs default βdeep reactivityβ introduces computational pressure.
shallowRef and markRaw
Vueβs default ref is recursively reactive (i.e., every property inside an object is proxied).
shallowRef: Only listens for changes to the .value reference, not changes to internal object properties.
- Scenario: When fetching a large read-only list of task history records from the backend.
markRaw: Marks an object so that it is never converted to reactive.
- Scenario: Certain complex third-party library instances (e.g., ECharts chart instances, map instances) β making them reactive may cause errors or severely degrade performance.
// Performance optimization example
import { shallowRef, markRaw } from 'vue';
// Assume this is ten thousand archived task records
const archiveTasks = shallowRef([]);
const loadArchive = (data) => {
// Triggers reactivity update only on assignment; internal property changes do not trigger
archiveTasks.value = data;
};
v-once and v-memo (Directive-Level Optimization)
v-once: Render Static Content Only Once
If a taskβs content never changes after rendering (e.g., task creation time), use v-once.
<span v-once>Created on: {{ task.createdAt }}</span>
- Principle: Vue skips subsequent update checks for this node after initial rendering.
v-memo: Conditional Updates (Vue 3.2+)
This is the most powerful directive for optimizing long lists. It accepts a dependency array; the node and its children are re-rendered only when values in the array change.
<li v-for="task in tasks" :key="task.id" v-memo="[task.isCompleted, task.title]">
{{ task.title }} - {{ task.isCompleted }}
</li>
When Should You Optimize?
| Approach | Solves | Recommended Scenario |
|---|---|---|
| Composables | Code duplication, scattered logic | Sharing logic across components (e.g., login checks, theme switching) |
| shallowRef | Memory overhead from deep proxying of large objects | List data size > 1000 and only requires whole replacement |
| v-memo | Frequent virtual DOM diffing in long lists | Complex v-for lists where only a few properties per item change |
Integrate into Your Existing Project
You can try applying v-memo in TaskItem.vue:
<template>
<li v-memo="[task.id, task.isCompleted]" class="...">
...
</li>
</template>
Now your project is not only logically clean (with Composables), but also high-performing.
YouTip