一套代码跑多端:uni-app 跨端待办小程序

举报
静水流深-云海 发表于 2026/09/13 19:05:56 2026/09/13
【摘要】 用 uni-app 写跨端待办:Vue 语法一套 + pages.json 路由 + uni 存储本地持久化,编译到微信/H5/App 多端。讲条件编译处理端差异、rpx 适配、以及"跨端≠跨端同步"的存储取舍。

一、背景:不想为每个端重写一遍待办

待办这种小应用,可能想在微信小程序里用、想在 H5 网页里用、想在 App 里用。如果每套端用各自技术栈写一遍,三套代码、三倍维护,改个逻辑三处同步,纯折磨。uni-app 的思路是用 Vue 语法写一套,编译到多个端(微信/支付宝小程序、H5、App),一次开发多端运行,对小团队和个人特别划算。

本文用 uni-app 写一个跨端待办:列表、添加、完成、删除,数据用本地存储。讲清 uni-app 的页面结构、条件编译(不同端差异怎么写)、本地存储 API。具体 API 和编译目标以官方文档为准。前面写过 Vue3 记账本、Golang 待办后端,这里换成"uni-app 跨端"视角,重点是"一套代码多端"这件事本身。

image.png

二、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 是页面生命周期、进来时从本地存储读 todosuni.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 生命周期。定位是"一套代码多端跑、各端本地存",数据端间不互通;要同步得上后端。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。