Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Building a Modular Vue Application with Dynamic Routing and Data Fetching

Tech 1

Project scaffolding begins with the Vue Command Line Interface. Installation requires Node.js and a package manager.

npm install -g @vue/cli
vue create mobile-shop
cd mobile-shop

The generated project follows a standardized directory layout. Dependencies reside in node_modules, static assets like favicons and public HTML templates belong in public, while the development workspace sits under src. Configuration files such as .gitignore, package.json, and Babel settings sit at the root level. Inside src, key directories include assets for media, components for reusable blocks, router for path mappings, store for global state, and views for route-level pages. The application bootstraps via main.js and App.vue.

Initialize the development server with npm run serve. Single File Components (SFCs) consolidate template markup, script logic, and scoped styles in to a single .vue extension.

Define the primary layout shell in App.vue. The structure typically consists of a scrollable central area flanked by fixed header and footer sections. Styling leverages CSS Flexbox for responsive alignment.

<!-- App.vue -->
<template>
  <div class="app-shell">
    <main class="main-content">
      <router-view />
    </main>
    <nav class="bottom-nav">
      <ul class="nav-list">
        <router-link to="/home" tag="li" exact-active-class="active">
          <i class="icon-home"></i><span>Home</span>
        </router-link>
        <router-link to="/category" tag="li" exact-active-class="active">
          <i class="icon-cat"></i><span>Categories</span>
        </router-link>
        <router-link to="/cart" tag="li" exact-active-class="active">
          <i class="icon-cart"></i><span>Cart</span>
        </router-link>
        <router-link to="/profile" tag="li" exact-active-class="active">
          <i class="icon-user"></i><span>Profile</span>
        </router-link>
      </ul>
    </nav>
  </div>
</template>

<style scoped lang="scss">
$primary-color: #ff5a6f;
$bg-light: #f5f5f5;

.app-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  main.main-content {
    flex: 1;
    overflow-y: auto;
    background: #fff;
  }
  nav.bottom-nav {
    height: 3.5rem;
    background: $bg-light;
    ul.nav-list {
      display: flex;
      justify-content: space-around;
      align-items: center;
      padding: 0; margin: 0;
      list-style: none;
      li {
        display: flex;
        flex-direction: column;
        align-items: center;
        font-size: 0.75rem;
        color: #666;
        &.active {
          color: $primary-color;
        }
      }
    }
  }
}
</style>

Route definitions manage view transitions based on URL paths. Create page components inside src/views. Each corresponds to a terminal screen. Lazy loading optimizes initial bundle size by splitting chunks per route.

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  { path: '/', redirect: '/home' },
  { 
    path: '/home', 
    name: 'HomePage', 
    component: () => import('@/views/HomeView.vue') 
  },
  { 
    path: '/category', 
    name: 'CategoryPage', 
    component: () => import('@/views/CategoryView.vue') 
  },
  { 
    path: '/cart', 
    name: 'CartPage', 
    component: () => import('@/views/CartView.vue') 
  },
  { 
    path: '/profile', 
    name: 'ProfilePage', 
    component: () => import('@/views/ProfileView.vue') 
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

Integrate third-party WebFont icon libraries by referencing their CDN stylesheet in public/index.html. Apply the corresponding classes to navigation anchors to render graphical markers alongside text labels. Style the icons using descendant selectors within the component stylesheet.

Product listings should be encapsulated to promote reusability across different views. Construct a dedicated block that accepts an array of objects via props and iterates through them to generate markup.

<!-- src/components/ProductCard.vue -->
<template>
  <ul class="product-grid">
    <li v-for="product in items" :key="product.id" class="card-row">
      <div class="media-wrapper">
        <img :src="product.thumbnail" :alt="product.title" />
      </div>
      <div class="details-wrapper">
        <h3 class="item-title">{{ product.title }}</h3>
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'ProductCard',
  props: {
    items: { type: Array, required: true }
  }
}
</script>

<style scoped lang="scss">
.product-grid { list-style: none; padding: 0; margin: 0; }
.card-row {
  display: flex;
  align-items: center;
  padding: 0.8rem 0;
  border-bottom: 1px solid #eee;
  .media-wrapper img {
    width: 4rem; height: 4rem;
    object-fit: cover;
    margin-right: 0.8rem;
    border-radius: 4px;
  }
  .details-wrapper { flex: 1; }
  .item-title { margin: 0; font-size: 1rem; }
}
</style>

Retrieve remote datasets using asynchronous request hendlers. Install the HTTP client library, trigger fetch operations during the component lifecycle hook, and pass the resolved payload down to the presentation layer. Add security meta tags to the public HTML template to prevent referrer header leakage when loading external assets.

// In src/views/HomeView.vue
<script>
import axios from 'axios'
import ProductCard from '@/components/ProductCard.vue'

export default {
  components: { ProductCard },
  data() {
    return { inventory: [] }
  },
  async mounted() {
    try {
      const response = await axios.get('https://api.example.com/products')
      this.inventory = response.data.results
    } catch (error) {
      console.error('Data retrieval failed:', error)
    }
  }
}
</script>

Template integration binds the fetched array to the custom component.

<!-- HomeView.vue snippet -->
<template>
  <section class="view-container">
    <ProductCard :items="inventory" />
  </section>
</template>

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.