第264集:Vue 3多页面应用配置与实践

概述

在Vue 3生态中,单页应用(SPA)是最常见的构建模式,但在某些场景下,多页面应用(MPA)仍然是更合适的选择。本集将深入探讨Vue 3多页面应用的配置、开发和部署,帮助你在合适的场景下选择正确的架构模式。

单页应用 vs 多页面应用

特性 单页应用(SPA) 多页面应用(MPA)
页面切换 客户端动态更新 服务器重新加载
初始加载速度 较慢(需加载完整应用) 较快(只加载当前页面)
路由管理 客户端路由 服务器路由 + 可选客户端路由
SEO友好度 需特殊处理(SSR/SSG) 天然友好
适用场景 复杂交互应用(管理系统、社交应用) 内容驱动网站(博客、电商、企业官网)

MPA适用场景

  • 内容驱动的网站(如博客、新闻站点)
  • SEO要求极高的应用
  • 由多个独立功能模块组成的大型系统
  • 需要与传统后端紧密集成的应用
  • 对初始加载速度要求严格的场景

配置Vite构建多页面应用

Vite原生支持多页面应用配置,只需在vite.config.ts中进行简单设置。

1. 项目结构设计

├── src/
│   ├── main/              # 主页面
│   │   ├── assets/        # 主页面资源
│   │   ├── components/    # 主页面组件
│   │   ├── App.vue        # 主页面根组件
│   │   └── main.ts        # 主页面入口
│   ├── admin/             # 管理页面
│   │   ├── assets/        # 管理页面资源
│   │   ├── components/    # 管理页面组件
│   │   ├── App.vue        # 管理页面根组件
│   │   └── main.ts        # 管理页面入口
│   └── shared/            # 共享资源
│       ├── components/    # 共享组件
│       ├── utils/         # 共享工具函数
│       └── styles/        # 共享样式
├── public/                # 静态资源
├── index.html             # 主页面模板
├── admin.html             # 管理页面模板
├── vite.config.ts         # Vite配置
└── package.json           # 项目配置

2. 配置vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  // 配置多页面应用
  build: {
    rollupOptions: {
      input: {
        // 配置每个页面的入口文件
        main: resolve(__dirname, 'index.html'),
        admin: resolve(__dirname, 'admin.html')
      }
    }
  },
  // 配置别名
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
      '@shared': resolve(__dirname, 'src/shared')
    }
  }
})

3. 创建HTML模板文件

index.html(主页面)

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue 3 MPA - 主页面</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main/main.ts"></script>
  </body>
</html>

admin.html(管理页面)

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue 3 MPA - 管理页面</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/admin/main.ts"></script>
  </body>
</html>

4. 配置页面入口文件

src/main/main.ts

import { createApp } from 'vue'
import App from './App.vue'
import './assets/main.css'

// 创建主页面应用实例
const app = createApp(App)
app.mount('#app')

src/admin/main.ts

import { createApp } from 'vue'
import App from './App.vue'
import './assets/main.css'

// 创建管理页面应用实例
const app = createApp(App)
app.mount('#app')

多页面应用路由设计

在MPA中,路由可以采用多种策略,包括纯服务器路由、纯客户端路由或混合路由模式。

1. 纯服务器路由

最传统的MPA路由模式,所有路由请求都由服务器处理,每个页面都是独立的HTML文件。

优势

  • 天然SEO友好
  • 初始加载速度快
  • 服务器端可以直接访问数据库和其他资源

劣势

  • 页面切换时需要重新加载
  • 无法实现复杂的客户端交互

2. 混合路由模式

在MPA中,每个页面内部使用Vue Router实现客户端路由,页面之间使用服务器路由。

配置示例

安装Vue Router

npm install vue-router@4

配置主页面路由

// src/main/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const router = createRouter({
  history: createWebHistory('/'),
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/about',
      name: 'About',
      component: About
    }
  ]
})

export default router

配置管理页面路由

// src/admin/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import Dashboard from '../views/Dashboard.vue'
import Users from '../views/Users.vue'

const router = createRouter({
  history: createWebHistory('/admin/'),
  routes: [
    {
      path: '/',
      name: 'Dashboard',
      component: Dashboard
    },
    {
      path: '/users',
      name: 'Users',
      component: Users
    }
  ]
})

export default router

在入口文件中使用路由

// src/main/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './assets/main.css'

const app = createApp(App)
app.use(router)
app.mount('#app')

3. 路由链接设计

  • 页面间跳转:使用普通&lt;a&gt;标签或window.location.href
  • 页面内跳转:使用Vue Router的&lt;router-link&gt;router.push()
<!-- 页面间跳转示例 -->
<a href="/admin">进入管理后台</a>
<button @click="goToAdmin">进入管理后台</button>

<!-- 页面内跳转示例 -->
<router-link to="/about">关于我们</router-link>
<button @click="$router.push('/about')">关于我们</button>

<script setup lang="ts">
const goToAdmin = () => {
  window.location.href = '/admin'
}
</script>

多页面应用状态管理

在MPA中,状态管理需要考虑页面间状态共享和页面内状态管理两个方面。

1. 页面内状态管理

每个页面可以独立使用Pinia或Vuex进行状态管理,配置方式与SPA相同。

安装Pinia

npm install pinia

配置主页面状态管理

// src/main/stores/counter.ts
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  }
})

在入口文件中使用Pinia

// src/main/main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import './assets/main.css'

const app = createApp(App)
const pinia = createPinia()

app.use(pinia)
app.use(router)
app.mount('#app')

2. 页面间状态共享

在MPA中,页面间状态共享可以通过以下方式实现:

a. URL参数

适用于简单状态传递,如筛选条件、分页信息等。

// 页面A:设置URL参数
window.location.href = `/admin?userId=123&status=active`

// 页面B:获取URL参数
const urlParams = new URLSearchParams(window.location.search)
const userId = urlParams.get('userId') // '123'
const status = urlParams.get('status') // 'active'

b. LocalStorage/SessionStorage

适用于需要持久化存储的状态,如用户偏好设置、认证信息等。

// 页面A:存储数据
localStorage.setItem('userInfo', JSON.stringify({ id: 123, name: '张三' }))

// 页面B:读取数据
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')

c. Cookies

适用于需要跨域共享的状态,如认证令牌。

// 设置Cookie
const setCookie = (name: string, value: string, days: number) => {
  const expires = new Date(Date.now() + days * 86400000).toUTCString()
  document.cookie = `${name}=${value}; expires=${expires}; path=/`
}

// 读取Cookie
const getCookie = (name: string) => {
  return document.cookie.split('; ')
    .find(row => row.startsWith(`${name}=`))?.split('=')[1] || ''
}

d. 服务器端存储

适用于需要持久化且安全的状态,如用户会话、购物车数据等。

多页面应用部署策略

1. 静态部署

如果MPA不依赖服务器端逻辑,可以直接部署到静态文件服务器(如Nginx、Apache、Netlify、Vercel等)。

构建命令

npm run build

构建输出结构

dist/
├── assets/               # 静态资源文件
│   ├── main-*.css        # 主页面CSS
│   ├── main-*.js         # 主页面JS
│   ├── admin-*.css       # 管理页面CSS
│   └── admin-*.js        # 管理页面JS
├── index.html            # 主页面HTML
└── admin.html            # 管理页面HTML

2. 服务器部署

如果MPA依赖服务器端逻辑,需要将构建产物部署到Web服务器中。

Nginx配置示例

server {
    listen 80;
    server_name example.com;
    root /path/to/dist;
    index index.html;

    # 主页面路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 管理页面路由
    location /admin {
        try_files $uri $uri/ /admin.html;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800";
    }
}

3. CDN加速

对于静态资源,可以使用CDN加速,提高全球访问速度。

配置vite.config.ts

export default defineConfig({
  // ...
  build: {
    // ...
    assetsDir: 'assets',
    // 配置CDN路径
    base: 'https://cdn.example.com/'
  }
})

多页面应用优化策略

1. 代码共享

  • 将公共组件、工具函数、样式等放在shared目录下
  • 使用Vite的optimizeDeps配置预构建第三方依赖
  • 利用Tree Shaking减少最终打包体积

2. 构建优化

  • 使用vite build --mode production构建生产版本
  • 配置build.rollupOptions.output.manualChunks进行代码分割
  • 使用build.sourcemap: false关闭源码映射(生产环境)

3. 性能优化

  • 启用HTTP/2或HTTP/3
  • 配置适当的缓存策略
  • 使用图片优化工具(如vite-plugin-imagemin
  • 实现懒加载和代码分割

4. SEO优化

  • 为每个页面设置独立的titlemeta标签
  • 使用服务器端渲染或静态站点生成(SSG)
  • 配置robots.txtsitemap.xml

最佳实践

  1. 合理划分页面:根据业务功能和访问量合理划分页面,避免页面过大或过小
  2. 统一技术栈:在所有页面中使用统一的技术栈和编码规范
  3. 共享资源管理:建立清晰的共享资源管理机制,避免代码重复
  4. 独立开发和部署:支持各页面独立开发、测试和部署
  5. 监控和分析:为每个页面配置独立的监控和分析,便于性能优化
  6. 渐进式增强:在保证基本功能的前提下,逐步增强用户体验

总结

本集详细介绍了Vue 3多页面应用的配置、开发和部署,包括:

  1. MPA的概念和适用场景
  2. 使用Vite配置MPA的方法
  3. MPA中的路由设计策略
  4. 页面内和页面间的状态管理
  5. MPA的部署和优化策略

在实际开发中,应根据项目需求选择合适的架构模式。对于内容驱动、SEO要求高、初始加载速度敏感的项目,MPA是一个不错的选择。而对于交互复杂、用户体验要求高的应用,SPA可能更合适。

在下一集中,我们将继续探讨Vue 3构建工具链的更多高级特性,敬请期待!

« 上一篇 Vue 3 自定义构建流程:提高构建效率与质量 下一篇 » Vue 3 库开发与发布实战:构建高质量开源库