Browse Source
Remove LazyLoadingExample.vue component that was only used for documentation and not referenced in the actual application code. **Changes:** - Delete src/components/LazyLoadingExample.vue (306 lines) - Add description to @ts-expect-error directive in ShareMyContactInfoView **Benefits:** - Reduces codebase size and complexity - Eliminates 13 lint warnings from unused component - Improves code maintainability - Keeps documentation examples separate from runtime code **Impact:** - No functional changes to application - Cleaner component directory - Reduced bundle size (component was not tree-shakeable)pull/142/head
2 changed files with 2 additions and 307 deletions
@ -1,305 +0,0 @@ |
|||
<template> |
|||
<div class="lazy-loading-example"> |
|||
<!-- Loading state with Suspense --> |
|||
<Suspense> |
|||
<template #default> |
|||
<!-- Main content with lazy-loaded components --> |
|||
<div class="content"> |
|||
<h1>Lazy Loading Example</h1> |
|||
|
|||
<!-- Lazy-loaded heavy component --> |
|||
<LazyHeavyComponent |
|||
v-if="showHeavyComponent" |
|||
:data="heavyComponentData" |
|||
@data-processed="handleDataProcessed" |
|||
/> |
|||
|
|||
<!-- Conditionally loaded components --> |
|||
<LazyQRScanner v-if="showQRScanner" @qr-detected="handleQRDetected" /> |
|||
|
|||
<LazyThreeJSViewer |
|||
v-if="showThreeJS" |
|||
:model-url="threeJSModelUrl" |
|||
@model-loaded="handleModelLoaded" |
|||
/> |
|||
|
|||
<!-- Route-based lazy loading --> |
|||
<router-view v-slot="{ Component }"> |
|||
<component :is="Component" /> |
|||
</router-view> |
|||
</div> |
|||
</template> |
|||
|
|||
<!-- Loading fallback --> |
|||
<template #fallback> |
|||
<div class="loading-fallback"> |
|||
<div class="spinner"></div> |
|||
<p>Loading components...</p> |
|||
</div> |
|||
</template> |
|||
</Suspense> |
|||
|
|||
<!-- Control buttons --> |
|||
<div class="controls"> |
|||
<button @click="toggleHeavyComponent"> |
|||
{{ showHeavyComponent ? "Hide" : "Show" }} Heavy Component |
|||
</button> |
|||
<button @click="toggleQRScanner"> |
|||
{{ showQRScanner ? "Hide" : "Show" }} QR Scanner |
|||
</button> |
|||
<button @click="toggleThreeJS"> |
|||
{{ showThreeJS ? "Hide" : "Show" }} 3D Viewer |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { Component, Vue, Prop, Watch } from "vue-facing-decorator"; |
|||
import { defineAsyncComponent } from "vue"; |
|||
|
|||
/** |
|||
* Lazy Loading Example Component |
|||
* |
|||
* Demonstrates various lazy loading patterns with vue-facing-decorator: |
|||
* - defineAsyncComponent for heavy components |
|||
* - Conditional loading based on user interaction |
|||
* - Suspense for loading states |
|||
* - Route-based lazy loading |
|||
* |
|||
* @author Matthew Raymer |
|||
* @version 1.0.0 |
|||
*/ |
|||
@Component({ |
|||
name: "LazyLoadingExample", |
|||
components: { |
|||
// Lazy-loaded components with loading and error states |
|||
LazyHeavyComponent: defineAsyncComponent({ |
|||
loader: () => import("./sub-components/HeavyComponent.vue"), |
|||
loadingComponent: { |
|||
template: '<div class="loading">Loading heavy component...</div>', |
|||
}, |
|||
errorComponent: { |
|||
template: '<div class="error">Failed to load heavy component</div>', |
|||
}, |
|||
delay: 200, // Show loading component after 200ms |
|||
timeout: 10000, // Timeout after 10 seconds |
|||
}), |
|||
|
|||
LazyQRScanner: defineAsyncComponent({ |
|||
loader: () => import("./sub-components/QRScannerComponent.vue"), |
|||
loadingComponent: { |
|||
template: '<div class="loading">Initializing QR scanner...</div>', |
|||
}, |
|||
errorComponent: { |
|||
template: '<div class="error">QR scanner not available</div>', |
|||
}, |
|||
}), |
|||
|
|||
LazyThreeJSViewer: defineAsyncComponent({ |
|||
loader: () => import("./sub-components/ThreeJSViewer.vue"), |
|||
loadingComponent: { |
|||
template: '<div class="loading">Loading 3D viewer...</div>', |
|||
}, |
|||
errorComponent: { |
|||
template: '<div class="error">3D viewer failed to load</div>', |
|||
}, |
|||
}), |
|||
}, |
|||
}) |
|||
export default class LazyLoadingExample extends Vue { |
|||
// Component state |
|||
@Prop({ default: false }) readonly initialLoadHeavy!: boolean; |
|||
|
|||
// Reactive properties |
|||
showHeavyComponent = false; |
|||
showQRScanner = false; |
|||
showThreeJS = false; |
|||
|
|||
// Component data |
|||
heavyComponentData = { |
|||
items: Array.from({ length: 1000 }, (_, i) => ({ |
|||
id: i, |
|||
name: `Item ${i}`, |
|||
})), |
|||
filters: { category: "all", status: "active" }, |
|||
sortBy: "name", |
|||
}; |
|||
|
|||
threeJSModelUrl = "/models/lupine_plant/scene.gltf"; |
|||
|
|||
// Computed properties |
|||
get isLoadingAnyComponent(): boolean { |
|||
return this.showHeavyComponent || this.showQRScanner || this.showThreeJS; |
|||
} |
|||
|
|||
get componentCount(): number { |
|||
let count = 0; |
|||
if (this.showHeavyComponent) count++; |
|||
if (this.showQRScanner) count++; |
|||
if (this.showThreeJS) count++; |
|||
return count; |
|||
} |
|||
|
|||
// Lifecycle hooks |
|||
mounted(): void { |
|||
console.log("[LazyLoadingExample] Component mounted"); |
|||
|
|||
// Initialize based on props |
|||
if (this.initialLoadHeavy) { |
|||
this.showHeavyComponent = true; |
|||
} |
|||
|
|||
// Preload critical components |
|||
this.preloadCriticalComponents(); |
|||
} |
|||
|
|||
// Methods |
|||
toggleHeavyComponent(): void { |
|||
this.showHeavyComponent = !this.showHeavyComponent; |
|||
console.log( |
|||
"[LazyLoadingExample] Heavy component toggled:", |
|||
this.showHeavyComponent, |
|||
); |
|||
} |
|||
|
|||
toggleQRScanner(): void { |
|||
this.showQRScanner = !this.showQRScanner; |
|||
console.log("[LazyLoadingExample] QR scanner toggled:", this.showQRScanner); |
|||
} |
|||
|
|||
toggleThreeJS(): void { |
|||
this.showThreeJS = !this.showThreeJS; |
|||
console.log( |
|||
"[LazyLoadingExample] ThreeJS viewer toggled:", |
|||
this.showThreeJS, |
|||
); |
|||
} |
|||
|
|||
handleDataProcessed(data: any): void { |
|||
console.log("[LazyLoadingExample] Data processed:", data); |
|||
// Handle processed data from heavy component |
|||
} |
|||
|
|||
handleQRDetected(qrData: string): void { |
|||
console.log("[LazyLoadingExample] QR code detected:", qrData); |
|||
// Handle QR code data |
|||
} |
|||
|
|||
handleModelLoaded(modelInfo: any): void { |
|||
console.log("[LazyLoadingExample] 3D model loaded:", modelInfo); |
|||
// Handle 3D model loaded event |
|||
} |
|||
|
|||
/** |
|||
* Preload critical components for better UX |
|||
*/ |
|||
private preloadCriticalComponents(): void { |
|||
// Preload components that are likely to be used |
|||
if (process.env.NODE_ENV === "production") { |
|||
// In production, preload based on user behavior patterns |
|||
this.preloadComponent( |
|||
() => import("./sub-components/HeavyComponent.vue"), |
|||
); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Preload a component without rendering it |
|||
*/ |
|||
private preloadComponent(componentLoader: () => Promise<any>): void { |
|||
componentLoader().catch((error) => { |
|||
console.warn("[LazyLoadingExample] Preload failed:", error); |
|||
}); |
|||
} |
|||
|
|||
// Watchers |
|||
@Watch("showHeavyComponent") |
|||
onHeavyComponentToggle(newValue: boolean): void { |
|||
if (newValue) { |
|||
// Component is being shown - could trigger analytics |
|||
console.log("[LazyLoadingExample] Heavy component shown"); |
|||
} |
|||
} |
|||
|
|||
@Watch("componentCount") |
|||
onComponentCountChange(newCount: number): void { |
|||
console.log("[LazyLoadingExample] Active component count:", newCount); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.lazy-loading-example { |
|||
padding: 20px; |
|||
max-width: 1200px; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.content { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.controls { |
|||
display: flex; |
|||
gap: 10px; |
|||
flex-wrap: wrap; |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
.controls button { |
|||
padding: 10px 20px; |
|||
border: 1px solid #ccc; |
|||
border-radius: 4px; |
|||
background: #f8f9fa; |
|||
cursor: pointer; |
|||
transition: background-color 0.2s; |
|||
} |
|||
|
|||
.controls button:hover { |
|||
background: #e9ecef; |
|||
} |
|||
|
|||
.loading-fallback { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 40px; |
|||
text-align: center; |
|||
} |
|||
|
|||
.spinner { |
|||
width: 40px; |
|||
height: 40px; |
|||
border: 4px solid #f3f3f3; |
|||
border-top: 4px solid #3498db; |
|||
border-radius: 50%; |
|||
animation: spin 1s linear infinite; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
@keyframes spin { |
|||
0% { |
|||
transform: rotate(0deg); |
|||
} |
|||
100% { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
.loading { |
|||
padding: 20px; |
|||
text-align: center; |
|||
color: #666; |
|||
} |
|||
|
|||
.error { |
|||
padding: 20px; |
|||
text-align: center; |
|||
color: #dc3545; |
|||
background: #f8d7da; |
|||
border: 1px solid #f5c6cb; |
|||
border-radius: 4px; |
|||
} |
|||
</style> |
Loading…
Reference in new issue