Lesson 13-Vue Project Architecture and Engineering

Project Architecture Design

SPA and MPA Architecture Design

Single Page Application (SPA) Core Architecture:

  • Client-side routing based on Vue Router
  • Centralized state management (Vuex/Pinia)
  • Component-based UI construction
  • On-demand resource loading
// SPA routing configuration example
const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/dashboard',
      component: () => import('@/views/Dashboard.vue'), // Lazy loading
      meta: { requiresAuth: true }
    }
  ]
})

Multi-Page Application (MPA) Architecture Features:

  • Multiple independent HTML entry points
  • Independent build configurations
  • Suitable for SEO-intensive scenarios
  • Implemented via Webpack’s multi-entry configuration
// MPA Webpack configuration example
module.exports = {
  entry: {
    home: './src/pages/home/index.js',
    about: './src/pages/about/index.js'
  },
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist')
  }
}

Modularization and Componentization Design

Modularization Design Principles:

  1. Single Responsibility Principle
  2. Clear dependency relationships
  3. Interface segregation
  4. Layered architecture (Presentation Layer/Business Layer/Data Layer)

Componentization Design Standards:

components/
├── common/         # General-purpose components
│   ├── Button.vue
│   └── Modal.vue
├── layout/         # Layout components
│   ├── Header.vue
│   └── Sidebar.vue
└── features/       # Business-specific components
    ├── user/
    │   ├── UserProfile.vue
    │   └── UserList.vue
    └── product/
        ├── ProductCard.vue
        └── ProductDetail.vue

Component Communication Strategies:

  1. Props/Events (Parent-child components)
  2. Provide/Inject (Cross-level communication)
  3. Vuex/Pinia (Global state management)
  4. Event Bus (Non-parent-child communication)
  5. v-model syntax sugar (Two-way binding)

State Management Architecture

Pinia State Management Example:

// stores/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    token: localStorage.getItem('token') || '',
    profile: null
  }),
  getters: {
    isAuthenticated: (state) => !!state.token
  },
  actions: {
    async login(credentials) {
      const { data } = await api.login(credentials)
      this.token = data.token
      localStorage.setItem('token', data.token)
    }
  }
})

State Management Best Practices:

  1. Divide stores by business modules
  2. Avoid direct state mutation (use actions)
  3. Cache complex computed properties with getters
  4. Encrypt sensitive data for persistence

Routing Architecture Design

Nested Routing Configuration:

const routes = [
  {
    path: '/admin',
    component: Layout,
    children: [
      {
        path: 'dashboard',
        component: Dashboard
      },
      {
        path: 'users',
        component: Users
      }
    ]
  }
]

Dynamic Routing Implementation:

// Permission-based dynamic routing
router.beforeEach(async (to, from, next) => {
  const { roles } = await store.dispatch('user/getUserInfo')
  const accessRoutes = generateRoutes(roles)
  router.addRoutes(accessRoutes)
  next({ ...to, replace: true })
})

Project Directory Standards

Recommended Directory Structure:

project/
├── public/                 # Static assets
├── src/
   ├── api/                # API request encapsulation
   ├── assets/             # Project asset files
   ├── components/         # Shared components
   ├── composables/        # Composables
   ├── directives/         # Custom directives
   ├── layouts/            # Layout components
   ├── router/             # Routing configuration
   ├── stores/             # State management
   ├── styles/             # Global styles
   ├── utils/              # Utility functions
   ├── views/              # Page components
   ├── App.vue             # Root component
   └── main.js             # Entry file
├── .env.development        # Development environment variables
├── .env.production         # Production environment variables
└── vite.config.js          # Build configuration

Engineering Toolchain

Vue CLI Advanced Configuration

Environment Variable Management:

# .env.development
VUE_APP_API_BASE=http://dev-api.example.com
VUE_APP_DEBUG=true

# .env.production
VUE_APP_API_BASE=https://api.example.com

Plugin Configuration Example:

// vue.config.js
module.exports = {
  pluginOptions: {
    eslint: {
      enable: true,
      config: '.eslintrc.js'
    },
    pwa: {
      name: 'My App',
      themeColor: '#4DBA87'
    }
  }
}

Webpack Advanced Configuration

Custom Loader Example:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          preprocessStyles: true
        }
      },
      {
        test: /\.md$/,
        use: [
          'vue-loader',
          {
            loader: 'markdown-loader',
            options: {
              pedantic: true
            }
          }
        ]
      }
    ]
  }
}

Performance Optimization Strategies:

  1. Use thread-loader for multi-threaded compilation
  2. Configure splitChunks for code splitting
  3. Enable cache-loader to cache build results
  4. Use compression-webpack-plugin to generate gzip files

Vite Application Practices

Vite Configuration Example:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': '/src'
    }
  },
  server: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true
      }
    }
  },
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor': ['vue', 'vue-router', 'pinia']
        }
      }
    }
  }
})

Vite Advantages:

  1. ESM-based development server
  2. On-demand compilation
  3. Built-in hot module replacement
  4. Faster build speeds

Code Standards Configuration

ESLint Configuration Example:

// .eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  extends: [
    'plugin:vue/vue3-recommended',
    'eslint:recommended'
  ],
  rules: {
    'vue/multi-word-component-names': 'off',
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  }
}

Prettier Configuration:

// .prettierrc
{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "none",
  "printWidth": 100
}

Automated Testing

Jest Testing Example:

// tests/unit/example.spec.js
import { mount } from '@vue/test-utils'
import Button from '@/components/Button.vue'

describe('Button.vue', () => {
  it('renders props.text when passed', () => {
    const text = 'Click me'
    const wrapper = mount(Button, {
      props: { text }
    })
    expect(wrapper.text()).toMatch(text)
  })
})

Vue Test Utils Techniques:

  1. Use nextTick to handle async updates
  2. Test props changes with setProps
  3. Simulate user events with trigger
  4. Mock API calls with jest.mock

Performance Optimization and Deployment

Code Splitting Strategies

Route-Level Lazy Loading:

const routes = [
  {
    path: '/dashboard',
    component: () => import(/* webpackChunkName: "dashboard" */ '@/views/Dashboard.vue')
  }
]

Component-Level Lazy Loading:

<template>
  <div>
    <button @click="showModal = true">Open Modal</button>
    <HeavyModal v-if="showModal" />
  </div>
</template>

<script>
import { defineAsyncComponent } from 'vue'

export default {
  components: {
    HeavyModal: defineAsyncComponent(() => 
      import('@/components/HeavyModal.vue')
    )
  },
  data() {
    return { showModal: false }
  }
}
</script>

Resource Optimization Strategies

Gzip Compression Configuration:

// vite.config.js
import viteCompression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    viteCompression({
      algorithm: 'gzip',
      ext: '.gz'
    })
  ]
})

CDN Acceleration Configuration:

// vue.config.js
module.exports = {
  configureWebpack: {
    externals: {
      vue: 'Vue',
      'vue-router': 'VueRouter',
      pinia: 'Pinia'
    }
  }
}

SSR and SSG Solutions

Nuxt.js SSR Configuration:

// nuxt.config.js
export default {
  target: 'server',
  head: {
    title: 'My SSR App'
  },
  render: {
    compressor: {
      threshold: 0
    }
  }
}

Vite SSG Example:

// vite-ssg.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  ssgOptions: {
    formatting: 'minify'
  }
})

Performance Monitoring Solutions

Lighthouse CI Integration:

# .github/workflows/lighthouse.yml
name: Lighthouse Audit
on: [push]
jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: npm install && npm run build
      - uses: treosh/lighthouse-ci-action@v8
        with:
          urls: |
            http://localhost:8080/
            http://localhost:8080/about
          budgetPath: ./lighthouse-budget.json

Web Vitals Monitoring:

// src/main.js
import { getCLS, getFID, getLCP } from 'web-vitals'

getCLS(console.log)
getFID(console.log)
getLCP(console.log)

CI/CD Workflow

Docker Deployment Example:

# Dockerfile
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

GitHub Actions CI Configuration:

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [ main ]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: '16'
      - run: npm install
      - run: npm run build
      - uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

Through systematic architecture design and engineering practices, Vue projects can achieve comprehensive improvements in development efficiency and runtime performance. It’s recommended to gradually adopt suitable optimization strategies and toolchain configurations based on team size and project requirements.

Share your love