Vue.js 从零基础到精通:生态圈拓展

15.39.1 Nuxt.js服务端渲染

Nuxt.js是一个基于Vue.js的高级框架,用于构建现代Web应用。它提供了服务端渲染(SSR)、静态站点生成(SSG)、路由自动生成等功能,极大地简化了Vue应用的开发流程。

Nuxt.js核心特性

  • **服务端渲染(SSR)**:将Vue组件在服务器上渲染为HTML,然后发送到客户端,提高首屏加载速度和SEO友好性
  • **静态站点生成(SSG)**:在构建时预渲染所有页面为静态HTML文件,结合CDN提供极致的性能
  • 自动路由生成:基于文件系统自动生成路由配置,无需手动编写
  • 模块化架构:内置多种模块,如axios、pwa、auth等,轻松扩展功能
  • 开发体验优化:热更新、错误页面、调试工具等

创建Nuxt.js项目

# 使用npx创建Nuxt 3项目
npx nuxi init my-nuxt-app
cd my-nuxt-app
npm install

# 启动开发服务器
npm run dev

Nuxt.js项目结构

my-nuxt-app/
├── app.vue              # 根组件
├── assets/              # 静态资源
├── components/          # Vue组件
├── composables/         # 组合式函数
├── layouts/             # 布局组件
├── middleware/          # 中间件
├── pages/               # 页面组件(自动生成路由)
├── plugins/             # 插件
├── public/              # 静态文件
├── server/              # 服务器端代码
├── nuxt.config.ts       # Nuxt配置文件
└── tsconfig.json        # TypeScript配置

页面与路由

Nuxt.js根据pages/目录下的文件结构自动生成路由:

<!-- pages/index.vue -->
<template>
  <div>
    <h1>首页</h1>
    <NuxtLink to="/about">关于我们</NuxtLink>
  </div>
</template>

<!-- pages/about.vue -->
<template>
  <div>
    <h1>关于我们</h1>
    <NuxtLink to="/">返回首页</NuxtLink>
  </div>
</template>

服务端渲染示例

<!-- pages/posts/[id].vue -->
<template>
  <div>
    <h1>{{ post.title }}</h1>
    <div>{{ post.content }}</div>
  </div>
</template>

<script setup lang="ts">
const route = useRoute()
const { data: post } = await useAsyncData('post', () =>
  $fetch(`https://api.example.com/posts/${route.params.id}`)
)
</script>

静态站点生成

# 生成静态站点
npm run generate

# 部署到静态托管服务
npm run preview

15.39.2 Vue + Electron桌面应用

Electron是一个使用JavaScript、HTML和CSS构建跨平台桌面应用的框架。它允许开发者使用Web技术创建在Windows、macOS和Linux上运行的原生应用。

Electron核心架构

  • **主进程(Main Process)**:负责管理应用生命周期、窗口创建、系统资源访问等
  • **渲染进程(Renderer Process)**:每个Electron窗口都是一个渲染进程,运行Vue应用
  • **预加载脚本(Preload Script)**:在渲染进程加载前执行,用于安全地暴露Node.js API给渲染进程

创建Vue + Electron项目

# 使用Vite创建Vue项目
npm create vue@latest my-electron-app
cd my-electron-app
npm install

# 安装Electron相关依赖
npm install electron electron-builder --save-dev
npm install vite-plugin-electron --save-dev

配置Vite + Electron

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

export default defineConfig({
  plugins: [
    vue(),
    electron({
      entry: 'electron/main.ts',
    })
  ],
})

Electron主进程代码

// electron/main.ts
import { app, BrowserWindow } from 'electron'
import path from 'path'

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false
    }
  })

  // 加载Vite开发服务器或打包后的HTML文件
  if (process.env.VITE_DEV_SERVER_URL) {
    win.loadURL(process.env.VITE_DEV_SERVER_URL)
    win.webContents.openDevTools()
  } else {
    win.loadFile(path.join(__dirname, '../dist/index.html'))
  }
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

预加载脚本

// electron/preload.ts
import { contextBridge, ipcRenderer } from 'electron'

contextBridge.exposeInMainWorld('electronAPI', {
  getAppVersion: () => ipcRenderer.invoke('app:getVersion'),
  onUpdateAvailable: (callback: () => void) => ipcRenderer.on('update:available', callback)
})

Vue组件中使用Electron API

<script setup lang="ts">
import { ref, onMounted } from 'vue'

const appVersion = ref('')

onMounted(async () => {
  // 使用暴露的Electron API
  appVersion.value = await (window as any).electronAPI.getAppVersion()
})
</script>

<template>
  <div>
    <h1>我的Electron应用</h1>
    <p>版本: {{ appVersion }}</p>
  </div>
</template>

打包Electron应用

// package.json
{
  "scripts": {
    "electron:dev": "vite dev",
    "electron:build": "vite build && electron-builder"
  },
  "build": {
    "appId": "com.myapp.electron",
    "productName": "My Electron App",
    "directories": {
      "output": "dist-electron"
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "win": {
      "target": "nsis"
    },
    "mac": {
      "target": "dmg"
    },
    "linux": {
      "target": "deb"
    }
  }
}

15.39.3 Vue + Capacitor移动应用

Capacitor是一个由Ionic团队开发的跨平台移动应用框架,允许开发者使用Web技术(HTML、CSS、JavaScript)构建原生移动应用。与Cordova相比,Capacitor提供了更现代的API和更好的性能。

Capacitor核心特性

  • 原生API访问:通过插件系统访问设备原生功能,如相机、GPS、文件系统等
  • 跨平台支持:一套代码可构建iOS、Android和Web应用
  • 现代构建工具:与Vite、Webpack等现代构建工具无缝集成
  • 原生项目管理:自动生成Xcode和Android Studio项目,支持原生代码扩展

创建Vue + Capacitor项目

# 使用Vite创建Vue项目
npm create vue@latest my-capacitor-app
cd my-capacitor-app
npm install

# 安装Capacitor相关依赖
npm install @capacitor/core @capacitor/cli
npm install @capacitor/ios @capacitor/android

# 初始化Capacitor
npx cap init

配置Capacitor

// capacitor.config.ts
import { CapacitorConfig } from '@capacitor/cli'

const config: CapacitorConfig = {
  appId: 'com.myapp.capacitor',
  appName: 'My Capacitor App',
  webDir: 'dist',
  server: {
    androidScheme: 'https'
  }
}

export default config

添加平台支持

# 构建Vue应用
npm run build

# 添加iOS平台
npx cap add ios

# 添加Android平台  
npx cap add android

运行Capacitor应用

# 在iOS模拟器运行
npx cap run ios

# 在Android模拟器运行
npx cap run android

# 打开Xcode项目
npx cap open ios

# 打开Android Studio项目
npx cap open android

使用Capacitor插件

# 安装相机插件
npm install @capacitor/camera
npx cap sync

在Vue组件中使用相机插件

<script setup lang="ts">
import { ref } from 'vue'
import { Camera, CameraResultType } from '@capacitor/camera'

const photo = ref('')

async function takePhoto() {
  const image = await Camera.getPhoto({
    quality: 90,
    allowEditing: true,
    resultType: CameraResultType.Uri
  })

  photo.value = image.webPath || ''
}
</script>

<template>
  <div>
    <h1>我的相机应用</h1>
    <button @click="takePhoto">拍照</button>
    <img v-if="photo" :src="photo" alt="拍摄的照片" />
  </div>
</template>

常用Capacitor插件

  • @capacitor/camera:相机访问
  • @capacitor/geolocation:地理位置
  • @capacitor/storage:本地存储
  • @capacitor/filesystem:文件系统
  • @capacitor/push-notifications:推送通知
  • @capacitor/browser:浏览器集成

15.39.4 微前端架构实践

微前端是一种将大型前端应用拆分为多个独立、可部署的小型应用的架构模式。每个微应用可以由不同的团队开发,使用不同的技术栈,最终组合成一个完整的应用。

微前端核心概念

  • **主应用(Host)**:负责管理微应用的加载、卸载和通信
  • **微应用(MicroApp)**:独立开发、部署的小型前端应用
  • 路由分配:将不同的URL路径分配给不同的微应用
  • 通信机制:微应用之间以及微应用与主应用之间的通信方式
  • 样式隔离:防止微应用之间的样式冲突

常见微前端解决方案

1. Single-SPA

Single-SPA是一个用于构建微前端应用的JavaScript框架,它允许在同一页面上运行多个框架。

# 安装Single-SPA CLI
npm install -g create-single-spa

# 创建主应用
create-single-spa
# 选择 "single-spa root config"

# 创建Vue微应用
create-single-spa
# 选择 "single-spa application / parcel"
# 选择 "vue"

2. qiankun

qiankun是由蚂蚁集团开发的微前端框架,基于Single-SPA,提供了更完善的功能和更好的开发体验。

# 安装qiankun
npm install qiankun

使用qiankun构建微前端

主应用配置

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { registerMicroApps, start } from 'qiankun'

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

// 注册微应用
registerMicroApps([
  {
    name: 'vue-app',
    entry: '//localhost:8081',
    container: '#micro-app-container',
    activeRule: '/vue'
  },
  {
    name: 'react-app',
    entry: '//localhost:8082',
    container: '#micro-app-container',
    activeRule: '/react'
  }
])

// 启动qiankun
start()
<!-- App.vue -->
<template>
  <div>
    <h1>主应用</h1>
    <nav>
      <a href="/vue">Vue应用</a>
      <a href="/react">React应用</a>
    </nav>
    <div id="micro-app-container"></div>
  </div>
</template>

Vue微应用配置

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

let app: any = null

function render(props: any) {
  app = createApp(App)
  app.use(router)
  app.mount(props.container ? props.container.querySelector('#app') : '#app')
}

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render({})
}

// 微应用生命周期
export async function bootstrap() {
  console.log('Vue app bootstraped')
}

export async function mount(props: any) {
  console.log('Vue app mounted', props)
  render(props)
}

export async function unmount() {
  console.log('Vue app unmounted')
  app.unmount()
  app = null
}
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 8081,
    headers: {
      'Access-Control-Allow-Origin': '*'
    }
  },
  build: {
    rollupOptions: {
      output: {
        format: 'umd',
        name: 'vueApp',
        globals: {
          vue: 'Vue'
        }
      }
    }
  }
})

微前端通信机制

1. 基于Props的通信

// 主应用传递数据给微应用
registerMicroApps([
  {
    name: 'vue-app',
    // ...
    props: {
      userInfo: { name: '张三', age: 25 },
      onMessage: (msg: string) => console.log('Received message:', msg)
    }
  }
])

2. 基于Event Bus的通信

// 主应用创建Event Bus
import mitt from 'mitt'
const eventBus = mitt()

// 注册微应用时传递Event Bus
registerMicroApps([
  {
    name: 'vue-app',
    // ...
    props: { eventBus }
  }
])

3. 基于状态管理的通信

可以使用Vuex、Pinia或Redux等状态管理库在主应用中维护全局状态,微应用通过props获取状态或状态更新函数。

微前端最佳实践

  1. 技术栈选型:主应用和微应用可以使用不同的技术栈,但建议核心框架保持一致
  2. 样式隔离:使用CSS Modules、Shadow DOM或CSS-in-JS等方式避免样式冲突
  3. 路由设计:采用嵌套路由或前缀路由方式,确保主应用和微应用路由不冲突
  4. 版本管理:微应用应独立版本化,支持灰度发布和回滚
  5. 性能优化:采用懒加载、预加载等方式优化微应用加载性能
  6. 开发流程:建立统一的开发规范和CI/CD流程

总结

Vue.js生态圈非常丰富,除了核心框架外,还有Nuxt.js、Electron、Capacitor和微前端架构等多种拓展方向。这些技术允许开发者使用Vue.js构建从Web应用到桌面应用、移动应用以及复杂的微前端系统。

通过学习Vue.js生态圈的各种技术,开发者可以根据项目需求选择最合适的技术栈,提高开发效率和应用性能。无论是构建单页应用、服务端渲染应用还是跨平台移动应用,Vue.js都提供了成熟的解决方案。

在实际项目中,建议根据项目规模、性能要求、团队技术栈等因素综合考虑,选择合适的技术组合。同时,要关注Vue.js生态的最新发展,及时学习和应用新技术,保持技术竞争力。

« 上一篇 37-advanced-vue-features