一文带你深入比较微信小程序与uniapp(纯干货)_微信小程序uniapp
不同:
-
架构与定位不同
特性 uniapp 微信小程序 开发定位 跨平台框架,支持同时开发小程序,H5,app(ios/android),快应用等 仅针对微信生态的轻量级应用开发平台 技术栈 基于 Vue.js(支持 Vue 2 和 Vue 3),使用类似 HTML/CSS/JS 的语法 自主研发的框架,使WXML/WXSS/JS(类似 HTML/CSS/JS 但有差异) 编译模式 编译为各平台原生代码或 WebView 渲染 运行在微信客户端的 JSCore 和 WebView 沙箱环境中 生态范围 支持多平台发布,依赖各平台自身生态 完全依赖微信生态,需遵守微信审核规则 条件编译 支持通过 #ifdef
、#ifndef
等语法针对不同平台编写特殊代码不支持(仅微信环境) uniapp条件编译示例:
// #ifdef h5console.log(\'这是h5平台\')// #endif// #ifdef MP-WEIXINconsole.log(\'这是微信小程序\')// #endif
微信小程序:在app.json中,第一个页面路径就是首页
uniapp使用vue.js的单文件组件(.vue文件
)(包含template、script、css).是基于vue封装的框架
const a=1; const getList = ()=> {}
pages节点的第一项为应用入口页(即首页)
-
基本语法不同
-
条件渲染:
微信小程序:wx:if 、wx:else
<view wx:if={{list.length>0}} >
uniapp:v-if、v-else
0\">
-
列表渲染:
微信小程序:wx:for、wx:key
<view wx:for={{list}} wx:key=\"index\" wx:for-item=\"info\">//若没有wx:for-item,默认语法是{{item.title}} 有重命名则是:{{info.title}}<view wx:for={{list}} wx:key={{item.id}}>
uniapp: v-for 、 v-bind:key
-
事件处理:
微信小程序:bindtap 、catchtap
//bindtap点击时,bindInput表单输入时,bindconfirm表单输入确定时//要求点击不冒泡用catchtap<view catchtap=\"toshow\" data-index=\"1\" data-id={{item.id}}>
uniapp: v-on:click 、 v-on:tap
//或者可以写为//@tap通过事件冒泡机制传递,可使用@tap.stop阻止冒泡,避免穿透关闭蒙层
-
事件传参:
微信小程序:
<view bindtap=\"doSomething\" data-id=\"2\" data-msg={{item.title}}>//在js文件中page({ doSomething:function(e){ const id = e.target.dataset.id const msg = e.target.dataset.msg }})
uniapp:
//传递动态参数,使用箭头函数包裹事件处理函数 handleItem(item.id,e)\">//不用箭头函数写法//传递静态参数 const id = ref(\'\') const countid = ref(\'\') const toDo = (e)=> { id.value = e.currenttarget.dataset.id} const handleItem = (id,e) => {countid.value = id ; console.log(e) }
-
数据更新机制:
微信小程序:基于数据驱动视图,需通过this.setData({})手动触发更新,单向数据流(数据--视图),批量合并,多次setData会合并成一次渲染
page({ data:{ count:1 }increment(){// 多次setData会合并为一次渲染 this.setData({ count:this.data.count+1 }) this.setData({ b: 2 })// 实际只触发一次DOM更新,将多个需要更新的数据字段合并到一个对象中,通过一次 setData 调用完成更新: this.setData({ count:this.data.count+1, b: 2 }) }})
uniapp:基于proxy响应式系统,支持双向数据绑定(v-model)(视图--数据--视图),不需要手动更新
{{count}}import {ref} from \'vue\' const count = ref(1) const toAdd = ()=> { //直接修改数据,视图自动更新 count.value++ }
-
Javascript API 不同
-
框架基础
功能 微信小程序API uniapp API APP初始化 app.js中 App({}) 无需手动调用,通过 pages.json 配置 页面注册 Page({
data:{}
})
基于 Vue 单文件组件(.vue)
全局数据 getApp().globalData Vuex/Pinia 或 globalData(同微信 路由跳转 wx.navigateTo、wx.redirectTo 等 uni.navigateTo、uni.redirectTo 等(完全兼容)
-
//微信小程序路由跳转wx.navigatorTo({ url:\'/pages/home/index?id=\'+this.data.id})//uniapp路由跳转wx.navigatorTo({ url:\'/pages/home/index?id=123\'})
-
UI交互
-
功能 微信小程序API uniapp API 提示框 wx.showToast、wx.showModal 等 uni.showToast、uni.showModal 等(完全兼容) 加载提示 wx.showLoading、wx.hideLoading uni.showLoading、uni.hideLoading(完全兼容) 下拉刷新 页面配置 \"enablePullDownRefresh\" + onPullDownRefresh 同微信,支持更多平台配置(如 App 端的原生刷新) 导航栏 wx.setNavigationBarTitle 等 uni.setNavigationBarTitle 等(完全兼容)
//微信小程序提示wx.showtoast({ title:\'修改成功\', icon:\'none\' , //或者\'success\'之类 duration:2000 //延迟毫秒数})//uniapp提示uni.showToast({ title:\'修改成功\', icon:\'none\' , //或者\'success\'之类 duration:2000 //延迟毫秒数})
具体可查看微信官方文档微信开放文档 / API 或uniapp官网API 概述 | uni-app官网
-
网络请求
//微信小程序网络请求wx.request({ url:\'https://api.example.com/data\', method:\'GET\', success:(res)=> { console.log(res.data) }});//uniapp网络请求uni.request({ url:\'https://api.example.com/data\', method:\'GET\', success:(res)=> { console.log(res.data) }});
微信小程序上传文件
page({ chooseAndUploadImage(){ //1.调用wx.chooseImage选择图片 wx.chooseMedia({ count:1,//最多选择一张图片 sizeType:[\'original\',\'compressed\'] ,//可以是原图或压缩图 sourceType:[\'album\',\'camera\'] //可以从相册或相机选择 success:(res) => { //2.获取临时文件路径 const tempFilePath = res.tempFilePaths[0]; //3.调用wx.uploadFile上传文件 wx.uploadFile({ url:\'https://example.com/upload\' //服务器上传接口 filePath: tempFilePath, name:\'file\' , //上传文件的字段名,需与服务端保持一致 formData:{ //额外表单数据(可选) userId:wx.getStorageSync(\'userId\'), // 假设已存储用户ID } success:(uploadRes) => { //处理上传成功响应 if(uploadRes.code==200){...} } }) } }) }
uniapp上传文件的区别在于将wx.chooseMedia改为了uni.chooseMedia
-
数据存储
本地存储与异步存储的本质区别在于数据操作时是否阻塞主线程wx.setStorageSync
和 wx.getStorageSync
属于微信小程序的同步存储 API,其特点是阻塞式执行,即代码会暂停执行直到存储操作完成。
Sync
结尾(如 getStorageSync
)Sync
后缀(如 getStorage
)const data = wx.getStorageSync(\'key\')
)success
回调获取结果try-catch
捕获错误fail
回调中处理错误//微信小程序异步存储wx.setStorage({ key:\'userInfo\', data:{ name:\'你的名字\',age:18 }})wx.getStorage({ key:\'userInfo\', success:(res)=>{ console.log(res.data) }})
-
//同步写入数据try { wx.setStorageSync(\'userInfo\', { name: \'张三\', age: 25 }); console.log(\'数据同步存储成功\');} catch (e) { console.error(\'同步存储失败:\', e);}//同步读取数据try { const userInfo = wx.getStorageSync(\'userInfo\'); if (userInfo) { console.log(\'读取到用户信息:\', userInfo); }} catch (e) { console.error(\'读取失败:\', e);}
-
支付与第三方服务
-
UI框架支持不同:
uniapp:支持uView、Vant、Element等多种UI框架
微信小程序:支持WeUi、Vant Weapp介绍 - Vant Weapp等特定框架
-
开发工具不同:
Uniapp:推荐使用 HBuilderX(官方 IDE),也可使用 VSCode 等
微信小程序:必须使用微信开发者工具
生命周期比较:
-
应用级生命周期对比:
微信小程序:
//app.jsApp({ //小程序初始化完成时触发,全局只触发一次 onLaunch(options){ console.log(\'小程序启动\',options) }, //小程序启动,或从后台进入前台显示时触发 onShow(options){ console.log(\'小程序显示\',options) }, //小程序从前台进入后台时触发 onHide(){ console.log(\'小程序隐藏\') }, // 小程序发生脚本错误,或 API 调用失败时触发 onError(error) { console.error(\'小程序错误:\', error) }, //监听小程序全局错误(如未捕获的Promise错误) onPageNotFound(res){ console.log(\'页面不存在\',res) }})
Uniapp:(Vue3模式)
// App.vueimport { onLaunch, onShow, onHide, onError } from \'@dcloudio/uni-app\';// 小程序初始化完成时触发(全局只触发一次)onLaunch((options) => {console.log(\'应用启动:\', options);});// 应用启动或从后台进入前台时触发onShow((options) => { console.log(\'应用显示:\', options);});// 应用从前台进入后台时触发onHide(() => { console.log(\'应用隐藏\');});// 监听应用错误onError((error) => { console.error(\'应用错误:\', error);});
相同点:
- 都具备应用初始化(
onLaunch
)、显示(onShow
)、隐藏(onHide
)等核心钩子 - 错误监听机制类似(
onError
)
不同点:
getApp()
获取全局实例uni.getApp()
或直接导入onPageNotFound
onPageNotFound
)页面级生命周期对比:
相同点
-
核心钩子功能一致:
onLoad
(加载)、onReady
(初次渲染完成)、onShow
(显示)、onHide
(隐藏)、onUnload
(卸载) -
都支持下拉刷新(
onPullDownRefresh
)、上拉触底(onReachBottom
)、页面滚动(onPageScroll
)和分享(onShareAppMessage
)
不同点
onLoad
)注册onResize
)setData
更新视图.json
文件中配置页面属性pages.json
中统一配置,支持条件编译组件生命周期对比:
微信小程序:
// components/my-component/my-component.jsComponent({//组件生命周期:在组件实例进入页面节点树时执行 created(){ console.log(\'组件创建\') }//组件生命周期:在组件实例进入页面节点树时执行 attached(){ console.log(\'组件挂载\') }//组件生命周期:在组件布局完成后执行 ready(){ console.log(\'组件布局完成\') }//组件生命周期:在组件实例被移动到节点树另一个位置时执行 moved(){ console.log(\'组件移动) }//组件生命周期:在组件实例被从节点树移除时执行 detached(){ console.log(\'组件卸载) } // 组件属性变化时触发 observers: { \'propertyA, propertyB\': function(newA, newB) { console.log(\'属性变化:\', newA, newB); } }})
Uniapp:(Vue3模式):
组件内容import { onMounted, onUpdated, onUnmounted, watch } from \'vue\';// 组件挂载后执行(对应微信的 ready)onMounted(() => { console.log(\'组件挂载完成\');});// 组件更新后执行onUpdated(() => { console.log(\'组件更新完成\');});// 组件卸载前执行onUnmounted(() => { console.log(\'组件卸载前\');});// 监听属性变化(替代微信的 observers)const props = defineProps({ propertyA: String, propertyB: Number});watch([() => props.propertyA, () => props.propertyB], (newValues) => { console.log(\'属性变化:\', newValues);});
相同点
- 都有组件创建、挂载、更新、卸载的概念
- 都支持监听属性变化
不同点
created
、attached
、ready
等onMounted
、onUpdated
等)observers
对象watch
函数总结对比:
1. 相同点总结
- 核心生命周期概念一致(应用初始化、页面加载 / 显示 / 隐藏、组件挂载 / 卸载)
- 都提供了丰富的事件钩子来处理各种场景
2. 不同点总结
setData
onReady
)onMounted
)微信小程序渲染顺序:
- 组件渲染顺序
1. 页面解析WXML时发现组件标签2. 创建组件实例(触发created生命周期)3. 组件数据初始化(触发attached生命周期)4. 组件数据传递到视图层5. 组件视图层渲染(触发ready生命周期)6. 页面继续渲染剩余内容
- 关键生命周期顺序:
页面onLoad → 页面onShow → 组件created → 组件attached → 组件ready → 页面onReady
Uniapp渲染顺序:
- 组件渲染顺序:
1. 父组件渲染过程中遇到子组件标签2. 创建子组件实例3. 初始化子组件props和data4. 触发子组件setup函数5. 子组件渲染(生成虚拟DOM → 真实DOM)6. 触发子组件onMounted生命周期7. 父组件继续渲染剩余内容
- 关键生命周期顺序:
页面onLoad → 页面created(Vue)→ 页面onMounted(Vue)→ 页面onShow → 子组件onMounted