Pinia第四章:模块化架构与 Store 组合

4.1 模块化设计原则
4.1.1 项目结构规范
src/
├─ stores/
│  ├─ modules/
│  │  ├─ auth.store.ts     # 认证相关状态
│  │  ├─ cart.store.ts     # 购物车管理
│  │  ├─ product.store.ts  # 商品数据
│  │  └─ ui.store.ts       # UI 全局状态
│  ├─ shared/
│  │  ├─ api.client.ts     # 封装的请求客户端
│  │  └─ cache.utils.ts    # 缓存工具函数
│  └─ index.ts             # 统一导出入口

模块划分策略:

  1. 按业务领域拆分(用户、商品、订单等)
  2. 按功能类型划分(数据层、UI 层、配置层)
  3. 共享工具统一管理(请求库、本地存储等)

4.1.2 统一导出模式
// stores/index.ts
export { useAuthStore } from './modules/auth.store'
export { useCartStore } from './modules/cart.store'
export { useProductStore } from './modules/product.store'
export { useUIStore } from './modules/ui.store'

// 组件中使用:
import { useAuthStore, useCartStore } from '@/stores'

4.2 Store 间通信模式
4.2.1 直接引用模式
// modules/cart.store.ts
export const useCartStore = defineStore('cart', {
  actions: {
    async checkout() {
      const authStore = useAuthStore()
      const uiStore = useUIStore()
      
      if (!authStore.isLoggedIn) {
        uiStore.showLoginModal()  // 触发 UI 变更
        throw new Error('需要登录')
      }
      
      await this.validateStock()
      await this.processPayment()
    }
  }
})
4.2.2 事件总线模式
// shared/event-bus.ts
import mitt from 'mitt'
type Events = {
  'cart:updated': CartItem[]
  'auth:loggedIn': UserProfile
}
export const bus = mitt<Events>()

// modules/cart.store.ts
bus.emit('cart:updated', this.items)

// modules/analytics.store.ts
bus.on('cart:updated', (items) => {
  this.trackEvent('cart_update', { itemCount: items.length })
})
4.2.3 共享根 Store
// modules/core.store.ts
export const useCoreStore = defineStore('core', {
  state: () => ({
    appVersion: '1.0.0',
    config: {} as AppConfig
  }),
  actions: {
    async loadConfig() {
      this.config = await fetchConfig()
    }
  }
})

// 其他 Store 中使用
const coreStore = useCoreStore()
const apiClient = createClient(coreStore.config.apiBase)

4.3 高级组合模式
4.3.1 组合函数封装
// composables/useCheckout.ts
export function useCheckout() {
  const cart = useCartStore()
  const user = useUserStore()
  const router = useRouter()
  
  // 私有状态
  const loading = ref(false)
  const error = ref<Error | null>(null)

  async function execute() {
    try {
      loading.value = true
      await cart.validate()
      await user.validatePayment()
      const result = await cart.submitOrder()
      router.push(`/orders/${result.orderId}`)
    } catch (err) {
      error.value = err
      throw err
    } finally {
      loading.value = false
    }
  }

  return { 
    execute,
    loading,
    error
  }
}

// 组件中使用:
const { execute, loading } = useCheckout()
4.3.2 跨 Store 状态同步
// plugins/sync.ts
export const createSyncPlugin = (sourceStoreId: string, targetStoreId: string, keys: string[]) => {
  return ({ pinia }) => {
    const source = pinia._s.get(sourceStoreId)
    const target = pinia._s.get(targetStoreId)
    
    source.$subscribe((_, state) => {
      const partial = keys.reduce((obj, key) => {
        obj[key] = state[key]
        return obj
      }, {})
      target.$patch(partial)
    })
  }
}

// 使用示例(同步用户基础信息)
pinia.use(createSyncPlugin('user', 'profile', ['name', 'avatar']))

4.4 动态模块注册
4.4.1 按需加载 Store
// stores/lazy.ts
const dynamicStores = new Map<string, Promise<any>>()

export async function useDynamicStore<T>(id: string, loader: () => Promise<T>): Promise<T> {
  if (!dynamicStores.has(id)) {
    dynamicStores.set(id, loader())
  }
  return dynamicStores.get(id)!
}

// 组件中使用
const adminStore = await useDynamicStore('admin', () => import('./modules/admin.store'))
4.4.2 运行时注册 Store
// utils/registerStore.ts
export function registerStore(id: string, definition: StoreDefinition) {
  const pinia = usePinia()
  
  if (!pinia._s.has(id)) {
    pinia._s.set(id, defineStore(id, definition)())
  }
  
  return pinia._s.get(id)
}

// 动态注册示例
registerStore('experimental', {
  state: () => ({ features: [] }),
  actions: {
    toggleFeature(name: string) {
      // ...
    }
  }
})

4.5 微前端场景实践
4.5.1 主应用配置
// main-app/src/stores/shared.ts
export const useSharedStore = defineStore('shared', {
  state: () => ({
    globalToken: '',
    microfrontends: {} as Record<string, any>
  }),
  actions: {
    registerMicroStore(name: string, store: any) {
      this.microfrontends[name] = store
    }
  }
})
4.5.2 子应用集成
// micro-app/src/stores/local.ts
export const useMicroStore = defineStore('micro', {
  actions: {
    init(sharedStore: any) {
      sharedStore.registerMicroStore('microApp', {
        getData: this.fetchData,
        reset: this.clearCache
      })
    }
  }
})

// 子应用挂载时
const sharedStore = window.parent.getSharedStore()
useMicroStore().init(sharedStore)

本章核心总结:

  1. 模块化架构:采用垂直切割(按业务)与水平分层(按功能)结合的方式
  2. 通信模式选择
    • 直接引用:简单场景
    • 事件总线:解耦模块
    • 共享核心:基础数据
  3. 组合模式
    • 使用 Composables 封装复杂逻辑
    • 通过插件实现自动同步
  4. 动态能力
    • 按需加载提升性能
    • 运行时注册增强扩展性
  5. 微前端集成:通过共享 Store 实现跨应用状态管理
<think>嗯,用户想了解如何基于uni-app技术栈开发多端融合的旅行社交应用,使用Vue3、TypeScript,还有涉及跨平台代码复用、UI组件库、地图导航、状态管理、Axios拦截器、鉴权、性能优化等方面。首先,我需要整理uni-app的基本概念,说明它的多端能力。然后,分步骤讲解各个模块的实现,比如项目初始化、UI组件选择、地图导航集成、状态管理用Pinia还是Vuex,以及如何优化包体积等。 用户提到的技术点很多,需要逐一覆盖。比如跨平台代码复用,uni-app的条件编译很重要,得举例说明。UI组件库推荐uView,地图部分可能用uni-app内置的map组件或者第三方如腾讯地图。状态管理方面,Vue3更适合用Pinia,但需要结合引用中的Pinia配置方法。Axios拦截器用于鉴权和异常处理,需要给出示例代码。性能优化方面,虚拟滚动和分包加载是关键,引用里提到了小程序分包和预下载配置,可以引用相关内容。 还要注意引用用户提供的文档内容,比如Pinia的安装和初始化步骤,分包配置方法,以及获取微信appId的方式。需要确保回答结构清晰,分步骤说明,每个部分给出代码示例,并自然添加引用标识。最后生成相关问题,帮助用户进一步探索。</think>### 基于uni-app的多端融合旅行社交应用开发指南 #### 一、技术选型项目初始化 1. **uni-app核心能力** uni-app支持一次开发多端发布(微信小程序、H5、App等),通过条件编译实现平台差异化代码。使用Vue3+TypeScript组合可提升代码可维护性,利用组合式API简化复杂逻辑开发[^2]。 2. **项目搭建步骤** ```bash # 创建uni-app TypeScript项目 npx degit dcloudio/uni-preset-vue#vite my-travel-app ``` 安装Pinia状态管理库: ```bash pnpm add pinia@2.0.30 # 引用[1] ``` 初始化Pinia: ```typescript // main.ts import { createSSRApp } from "vue"; import { createPinia } from 'pinia'; // 引用[3] const app = createSSRApp(App).use(createPinia()); ``` #### 二、核心功能模块实现 1. **跨平台代码复用** - 通用逻辑使用`.ts`文件封装 - 平台差异代码通过条件编译处理: ```javascript // #ifdef MP-WEIXIN const appId = uni.getAccountInfoSync().miniProgram.appId // 引用[2] // #endif ``` 2. **UI组件库地图导航** - 推荐使用`uView`跨端组件库 - 地图模块实现: ```vue <template> <map :markers="markers" @tap="handleMapClick"></map> </template> <script setup lang="ts"> const markers = ref([{latitude: 39.909, longitude: 116.39742}]) </script> ``` 3. **状态管理架构** 采用Pinia+Vuex混合模式: ```typescript // stores/trip.ts export const useTripStore = defineStore('trip', { state: () => ({ currentLocation: null }), actions: { /* 位置更新方法 */ } }) ``` 4. **网络请求层封装** Axios拦截器实现鉴权异常处理: ```typescript axios.interceptors.request.use(config => { config.headers.Authorization = store.token // 引用[1] return config }) ``` #### 三、性能优化策略 1. **虚拟滚动优化列表** ```vue <uv-list :virtual="true" :height="800" :item-size="100"> <template v-slot="{ index }"> <trip-card :data="listData[index]"/> </template> </uv-list> ``` 2. **分包加载配置** ```json // pages.json "preloadRule": { "pages/home/home": { "network": "all", "packages": ["subpackage_trip"] // 引用[2] } } ``` 3. **小程序包体积控制** - 使用自动化压缩工具`uni-app-packer` - 非核心功能动态加载 - 图片资源使用CDN托管 #### 四、社交功能扩展 1. **即时通讯集成** 使用uni-app原生`uni.connectSocket` API或第三方SDK 2. **内容分享系统** 实现多平台分享接口: ```typescript uni.share({ provider: 'weixin', type: 0, summary: '发现精彩旅行路线!' }) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道不尽世间的沧桑

作者想喝瓶哇哈哈,谢谢大佬

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值