5.1 KiB
5.1 KiB
Project Structure Analysis: Vue.js Migration from Blade
Overview
The BukidBountyApp has been fully migrated from Blade templates to a Vue 3 SPA (Single Page Application) with Pinia for state management.
1. Application Architecture
Entry Point (resources/js/app.js)
- Vue 3 app created with
createApp() - Pinia state manager initialized via
createPinia() - Auto-imports all Vue components from
./Pages/**/*.vue(excluding Fragments) - Main layout structure:
TopHeader(fixed header at top)main-contentarea for page routingBottomNav(fixed bottom navigation bar)BaseModal(global modal component)
Key Components
Layout Components
| Component | Location | Description |
|---|---|---|
TopHeader.vue |
Pages/Core/Fragments/ | Fixed header with back button, title, and settings action |
BottomNav.vue |
Pages/Core/Fragments/ | Bottom navigation with Home, Cart, Properties links |
BaseModal.vue |
Components/Core/BaseModal.vue | Global modal using Teleport to body |
2. Pinia Stores Usage
Current Store: resources/js/stores/network.js
The project currently has one Pinia store for network status management:
import { defineStore } from 'pinia'
export const useNetworkStore = defineStore('network', {
state: () => ({
isOnline: navigator.onLine,
isLoading: false
}),
actions: {
setOnline(status) {
this.isOnline = status
if (status) this.isLoading = false
},
startLoading() { this.isLoading = true },
stopLoading() { this.isLoading = false }
}
})
How to Use Pinia Stores in Components
<script setup>
import { useNetworkStore } from '../stores/network'
// Call the store factory function
const network = useNetworkStore()
// Access reactive state
console.log(network.isOnline) // true/false
console.log(network.isLoading) // true/false
// Call actions
network.setOnline(true)
network.startLoading()
network.stopLoading()
</script>
Creating a New Store
// stores/example.js
import { defineStore } from 'pinia'
export const useExampleStore = defineStore('example', {
state: () => ({
count: 0,
items: []
}),
getters: {
doubledCount: (state) => state.count * 2
},
actions: {
increment() { this.count++ },
addItem(item) { this.items.push(item) }
}
})
Then use in component:
<script setup>
import { useExampleStore } from '../stores/example'
const store = useExampleStore()
store.increment()
</script>
3. Composables (Vue Composition API)
Key Composables
| Composable | Location | Purpose |
|---|---|---|
useNavigate |
composables/Core/useNavigate.js | SPA navigation between pages |
useModal |
composables/Core/useModal.js | Global modal management |
useAuth |
composables/Core/useAuth.js | User authentication/role state |
Navigation Pattern
<script setup>
import { useNavigate } from '../composables/Core/useNavigate'
const { navigate } = useNavigate()
// Navigate to another page
navigate({ page: 'CartProductMarket' })
navigate({
page: 'ViewStoreMarket',
props: { storeId: 123 }
})
// Reload current page
navigate.reloadPage()
</script>
Global $navigate Helper
The app exposes window.$navigateHelper which can be accessed via:
- In components:
this.$navigate - Globally:
window.$navigateHelper({ page, props })
4. Page Routing System
How It Works
- Initial page is defined in
index.html:data-page='{"component":"Home","props":{}}' - Pages are auto-imported from
resources/js/Pages/directory - Component names use dot notation (e.g.,
Auth.Login,AccountSettings) - URLs use path notation:
/,/login,/auth/login
Page File Structure
Pages/
├── Home.vue → /
├── Auth/
│ └── Login.vue → /auth/login
├── AccountSettings.vue → /account/settings
└── Market/
├── ListProductsMarket.vue
└── ViewStoreMarket.vue
5. Dependencies
{
"dependencies": {
"vue": "^3.5.27",
"pinia": "^3.0.4",
"axios": "^1.13.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.3",
"vite": "^7.3.1"
}
}
6. Summary: How to Access Pinia Stores
From a Vue Component (Composition API)
<script setup>
import { useNetworkStore } from '../stores/network'
const network = useNetworkStore()
// Use: network.isOnline, network.isLoading, network.actions()
</script>
From a Composable or Setup Function
import { useNetworkStore } from '../stores/network'
const network = useNetworkStore()
// Now you can access the store's state and actions
Global Access (Not Recommended)
window.$networkStore = useNetworkStore() // Available if defined globally
Migration Notes
The project has successfully migrated from Blade to Vue with:
- ✅ SPA routing via
useNavigatecomposable - ✅ Pinia for state management
- ✅ Global modal system
- ✅ Auto-imported page components
- ✅ Browser history navigation (popstate support)