多端统一开发实践:taocarts PC/小程序/APP的Vue3+Uniapp微前端方案
导读:代购平台的用户可能通过PC网页、小程序或者移动端APP访问,如何用一套代码库维护多个端?本文分享taocarts基于Vue3和Uniapp的多端统一开发实践。
一、多端开发的工程化痛点
代购系统的前端需要覆盖多个端。PC端是后台运营管理的主要入口,用户移动端小程序是海外用户首选的购物入口,iOS和Android原生App提供更好的性能和体验。如果每个端都独立开发一套前端工程,代码量膨胀、测试成本倍增、需求迭代时三端同步效率极低。
taocarts在前端多端方案上采用了Vue3 + Uniapp为核心的分层架构。底层是跨平台兼容的能力层适配不同端(Web、微信小程序、支付宝小程序、iOS、Android)的API 差异。中间层是业务逻辑层,沉淀跨端复用的状态管理和工具函数。最上层是视图层,各端可能存在一定的UI差异,但整体逻辑保持一致。底层能力用npm包的方式在各端项目之间复用,工程效率大幅提升。
二、跨端复用核心逻辑
<!-- 商品详情页组件(多端复用) -->
<template>
<view class="product-detail">
<view class="product-gallery">
<swiper v-if="product.images" :indicator-dots="true" :autoplay="false">
<swiper-item v-for="(img, index) in product.images" :key="index">
<image :src="img" mode="aspectFill" @click="previewImage(index)" />
</swiper-item>
</swiper>
</view>
<view class="product-info">
<text class="product-title">{{ product.title }}</text>
<view class="product-price">
<text class="price-symbol">{{ currencySymbol }}</text>
<text class="price-value">{{ displayPrice }}</text>
</view>
<view class="product-specs" v-if="product.specs.length">
<view class="spec-item" v-for="spec in product.specs" :key="spec.id">
<text class="spec-label">{{ spec.name }}:</text>
<view class="spec-options">
<text
v-for="opt in spec.options"
:key="opt.value"
:class="['spec-option', { active: selectedSpecs[spec.name] === opt.value }]"
@click="selectSpec(spec.name, opt.value)"
>
{{ opt.label }}
</text>
</view>
</view>
</view>
</view>
<view class="product-actions">
<button class="btn-add-cart" @click="addToCart" :disabled="!product.inStock">
加入购物车
</button>
<button class="btn-buy-now" @click="buyNow" :disabled="!product.inStock">
立即购买
</button>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useProductStore } from '@/stores/product'
import { useCartStore } from '@/stores/cart'
import { useCurrencyStore } from '@/stores/currency'
import { onLoad, onShareAppMessage } from '@dcloudio/uni-app'
import { toast, previewImage as uniPreviewImage } from '@/utils/platform'
const props = defineProps(['productId'])
const productStore = useProductStore()
const cartStore = useCartStore()
const currencyStore = useCurrencyStore()
const product = ref({})
const selectedSpecs = ref({})
onLoad(async () => {
await loadProduct()
})
const loadProduct = async () => {
product.value = await productStore.fetchProductDetail(props.productId)
}
const displayPrice = computed(() => {
if (!product.value.price) return '0.00'
return currencyStore.convert(product.value.price)
})
const currencySymbol = computed(() => currencyStore.symbol)
const addToCart = async () => {
try {
await cartStore.addItem({
productId: product.value.id,
quantity: 1,
specs: selectedSpecs.value
})
toast({ title: '添加成功', icon: 'success' })
} catch (error) {
toast({ title: error.message, icon: 'none' })
}
}
const previewImage = (index) => {
uniPreviewImage({
current: index,
urls: product.value.images
})
}
// 多端分享配置
onShareAppMessage(() => {
return {
title: product.value.title,
path: `/pages/product/detail?id=${product.value.id}`,
imageUrl: product.value.images[0]
}
})
</script>
三、微前端架构在后台管理系统中的应用
后台运营管理系统模块多、功能复杂,各模块(商品管理、订单管理、物流管理、财务管理等)独立开发部署的需求强烈。taocarts后台采用了qiankun微前端 架构,各业务团队独立开发子应用,主应用负责统一的登录鉴权、菜单路由和全局状态管理。
// qiankun微前端配置
import { registerMicroApps, start } from 'qiankun';
const apps = [
{
name: 'product-manager',
entry: '//localhost:8081',
container: '#subapp-container',
activeRule: '/product',
props: { authToken: getToken() }
},
{
name: 'order-manager',
entry: '//localhost:8082',
container: '#subapp-container',
activeRule: '/order',
props: { authToken: getToken() }
},
{
name: 'logistics-manager',
entry: '//localhost:8083',
container: '#subapp-container',
activeRule: '/logistics',
props: { authToken: getToken() }
}
];
registerMicroApps(apps, {
beforeLoad: app => console.log('before load', app.name),
beforeMount: app => console.log('before mount', app.name)
});
start({ prefetch: true });
微前端落地过程中遇到过一些兼容性问题——各子应用的路由冲突、全局样式污染、公共依赖库重复加载等。taocarts的解决方案是通过约定主应用提供统一的全局变量和服务,子应用按约定接入,有效解决了这些问题。多端统一开发降低了代码维护成本,一批需求可以一次性发布到全部平台。