一套代码跑多端:uni-app 跨端待办小程序
一、背景:不想为每个端重写一遍待办
待办这种小应用,可能想在微信小程序里用、想在 H5 网页里用、想在 App 里用。如果每套端用各自技术栈写一遍,三套代码、三倍维护,改个逻辑三处同步,纯折磨。uni-app 的思路是用 Vue 语法写一套,编译到多个端(微信/支付宝小程序、H5、App),一次开发多端运行,对小团队和个人特别划算。
本文用 uni-app 写一个跨端待办:列表、添加、完成、删除,数据用本地存储。讲清 uni-app 的页面结构、条件编译(不同端差异怎么写)、本地存储 API。具体 API 和编译目标以官方文档为准。前面写过 Vue3 记账本、Golang 待办后端,这里换成"uni-app 跨端"视角,重点是"一套代码多端"这件事本身。

二、uni-app 的页面结构
一个 uni-app 页面由 vue 文件 + pages.json 路由组成。页面用 Vue 写法,但 API 走 uni 的跨端封装:
<template>
<view>
<input v-model="draft" placeholder="写个待办" />
<button @click="add">添加</button>
<view v-for="t in todos" :key="t.id" @click="toggle(t.id)">
<text :class="{ done: t.done }">{{ t.text }}</text>
</view>
</view>
</template>
<script>
export default {
data() { return { todos: [], draft: '' } },
onLoad() { this.todos = uni.getStorageSync('todos') || [] },
methods: {
add() {
if (!this.draft.trim()) return
this.todos.push({ id: Date.now(), text: this.draft, done: false })
uni.setStorageSync('todos', this.todos)
this.draft = ''
},
toggle(id) {
const t = this.todos.find(x => x.id === id)
t.done = !t.done
uni.setStorageSync('todos', this.todos)
}
}
}
</script>
data() 返回状态(Vue 选项式写法,uni-app 同时支持选项式和组合式),onLoad 是页面生命周期、进来时从本地存储读 todos。uni.getStorageSync/setStorageSync 是 uni 的跨端存储 API,编译到各端会映射成对应平台的存储(小程序 wx.setStorage、H5 的 localStorage 等),你不用管差异。add 推一条、toggle 翻转完成态、都 setStorageSync 落盘。模板用 view/input/button/text(uni 的跨端组件),编译到小程序就是原生组件、到 H5 就是对应 HTML。
三、条件编译:不同端有差异怎么办
一套代码多端跑,但难免有"某端特殊"的需求——比如微信小程序要调 wx.login 拿 openid、H5 不用;某段样式只在 App 生效。uni-app 用条件编译注释区隔:
// #ifdef MP-WEIXIN
wx.login({ success: r => console.log(r.code) }) // 仅微信小程序编译这段
// #endif
// #ifdef H5
console.log('在浏览器里') // 仅 H5 编译这段
// #endif
// #ifdef MP-WEIXIN … // #endif 包裹的代码,只会在编译到微信小程序时保留,其它端剔除;H5 同理。这样"公共逻辑一套、平台差异用条件编译收口",既复用又不被差异拖垮。模板里也能用 <!-- #ifdef MP-WEIXIN --> 做同样的区隔。条件编译的宏名(MP-WEIXIN / H5 / APP 等)以官方文档为准。
四、跨端存储的取舍
待办数据用 uni.setStorageSync 存在各端本地:小程序存在小程序沙箱、H5 存在浏览器 localStorage、App 存在应用沙箱。好处是零后端、各端各自持久化;坏处是数据不互通——同一用户在小程序加的待办,H5 上看不到,因为各端存储彼此独立、都没上云。
要"多端数据同步",得加后端(把待办存服务器/对象存储,各端登录后拉取),那就超出"纯本地跨端"范围。本文定位是"一套代码多端跑、各端本地存",接受"端间不互通";若要多端同步,存储层换成远程 API,页面逻辑不变。这个取舍想清楚,别把"跨端"误解成"跨端同步"。
五、几个要注意的点
第一,组件要用 uni 的跨端组件。模板里写 <view> 而非 <div>、<text> 而非 <span>,uni 会映射到各端;直接写 <div> 在微信小程序里不识别。这是 uni-app 和纯 Vue Web 最容易混的点,跨端项目遵守它的组件集。
第二,样式单位用 rpx。uni-app 的 rpx 是响应式像素,750rpx = 屏宽,自动适配不同屏幕,比写死 px 在各端一致性好。写样式优先 rpx,尤其小程序端。具体换算以官方文档为准。
第三,生命周期用 uni 的。页面用 onLoad/onShow 而非纯 Web 的 mounted(虽部分兼容,但 onLoad 在端上语义更准)。组件内仍可用 Vue 的 mounted 等,但页面级建议用 uni 生命周期。
第四,条件编译别滥用。能公共的就公共,只有真有端差异才上 #ifdef,否则代码被切得七零八落、难维护。先写一套尽量通用的,差异收敛到少数几个编译块。
第五,API 能力差异。不是所有 uni API 每端都完全一致(如某些原生能力只有 App 有),用到时查官方文档确认目标端支持,别假设"写一次全端都有"。
六、小结
uni-app 写跨端待办:Vue 语法一套、pages.json 配路由、uni.getStorageSync 做本地持久化,编译到微信/H5/App 多端运行。端间差异用条件编译(// #ifdef MP-WEIXIN)收口,公共逻辑复用。注意用 uni 跨端组件(view/text 而非 div/span)、rpx 适配屏幕、页面用 onLoad 生命周期。定位是"一套代码多端跑、各端本地存",数据端间不互通;要同步得上后端。
- 点赞
- 收藏
- 关注作者
评论(0)