初衷
近期公司要开发一个电商小程序,之前的mpvue已经停更别再选了,原生嘛 也没啥意思,因为是vue党所所以团队就选择了 uni-app来试试水,一周多使用下来使用感受 还是可以的。
会vue的 话简直就是无脑开发,看完这篇文章 直接上手撸。
小程序 分包加载:链接
底层实现原理:链接
uni-app runtime :
逻辑层和视图层分离,且非H5端通信有折损
uni-app 在非H5端运行时,从架构上分为逻辑层和视图层两个部分。逻辑层负责执行业务逻辑,也就是运行js代码,视图层负责页面渲染。
虽然开发者在一个vue页面里写js和css,但其实,编译时就已经将它们拆分了。
逻辑层详解
逻辑层是运行在一个独立的jscore里的,它不依赖于本机的webview,所以一方面它没有浏览器兼容问题,可以在Android4.4上跑es6代码,另一方面,它无法运行window、document、navigator、localstorage等浏览器专用的js API。
uni-app的App端和小程序端的js引擎,其实是在jscore上补充了一批手机端常用的JS API,比如扫码。
视图层详解
通常:h5和小程序平台,以及app-vue,视图层是webview。而app-nvue的视图层是基于weex改造的原生视图。
uni-app的js基本没有不同手机的兼容问题(因为js引擎自带了),而视图层的css,在app-vue上会有手机浏览器的css兼容问题。所以在app-vue的场景中尽量不要使用太新的css语法,除非你不打算支持低端机。
当然这样做也是有 利弊的 详情查看
项目创建
两种方式
1. 通过 HBuilderX 可视化界面
这个超级简单 开箱即用,无需配置nodejs。
下载好 IDE在点击工具栏里的文件 -> 新建 -> 项目 ,喜欢哪个模板选一个就完事儿了(推荐 hello uni-app)。
2. 通过vue-cli命令行 ( vue玩家推荐)
通过vuecli3.0+ 做为支持,所以 需要先安装 npm install -g @vue/cli
然后=》创建项目: vue create -p dcloudio/uni-preset-vue my-project
自带各种脚本,秀的不行啊!
通过这个方式,可以安装各种 你想要的 css预处理器、第三方插件等等,玩vue项目的都懂的。
关于NPM支持
cli项目默认已经有package.json了。
HBuilderX创建的项目默认没有,需要通过初始化命令来创建。
关于页面配置
跟小程序一样放在 : pages.json
{"pages": [{"path": "pages/component/index","style": {"navigationBarTitleText": "组件"}}]}
开发规范
为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:
- 页面文件遵循 vue编写方式 Vue 单文件组件规范

- 组件标签靠近小程序规范,(比如基本的 view、text、image)详见uni-app 组件规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀
wx替换为uni,详见uni-app接口规范 - 数据绑定及事件处理同
Vue.js规范,同时补充了App及页面的生命周期 - 为兼容多端运行,建议使用flex布局进行开发
资源路径说明
@开头的绝对路径以及相对路径会经过base64转换规则校验
模板内引入静态资源
<!-- 绝对路径,/static指根目录下的static目录,在cli项目中/static指src目录下的static目录 --><image class="logo" src="/static/logo.png"></image><image class="logo" src="@/static/logo.png"></image><!-- 相对路径 --><image class="logo" src="../../static/logo.png"></image>
js文件引入
/ 绝对路径,@指向项目根目录,在cli项目中@指向src目录import add from '@/common/add.js'// 相对路径import add from '../../common/add.js'
css引入静态资源
/* 绝对路径 */@import url('/common/uni.css');@import url('@/common/uni.css');/* 相对路径 */@import url('../../common/uni.css');
页面
getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。
最好 自己打印出来 看下 所需信息 const pages = getCurrentPages()
尺寸单位
uni-app 支持的通用 css 单位包括 px、rpx
- px 即屏幕像素
- rpx 即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大。
生命周期
详情 链接
| onLoad | 监听页面加载,主要通过这个获取页面参数 onLoad(option)}{},参考示例 |
|---|---|
| onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 |
| onReady | 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 |
| onHide | 监听页面隐藏 |
| onUnload | 监听页面卸载 |
全局页面通讯
触发全局的自定事件
uni.$emit(eventName,OBJECT) 附加参数都会传给监听器回调。栗子: uni.$emit('update',{msg:'页面更新'})
监听全局的自定义事件
uni.$on(eventName,callback)事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数。
uni.$on('update',function(data){console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);})
注意事项
uni.$emit、 uni.$on 、 uni.$once 、uni.$off触发的事件都是 App 全局级别的,跨任意组件,页面,nvue,vue 等- 使用时,注意及时销毁事件监听,比如,页面 onLoad 里边
uni.$on注册监听,onUnload 里边uni.$off移除,或者一次性的事件,直接使用uni.$once监听
样式
使用 uni-app 组件的时候 有时候修改内部组件样式 无效,需要使用 /deep/ .xxx { } 才可以生效。
页面通用模式
<template><view class="container"><view class="user-section"><image class="bg" src="/static/user-bg.jpg"></image></view><view class="info-box"><text class="username">{{userInfo.nickname || '游客'}}</text></view></view></template>// 基本上和vue一摸一样<script>import { getMyInfo } from '@/api/my.js'import { mapState } from 'vuex';import mixins_share from '@/mixins/share.js'export default {mixins: [mixins_share],data() {return {userInfo: {},vipTheme: {},};},computed: {...mapState(['accessToken'])},onLoad(option) {this.nickName = option.nickName},onShow() {},methods: {scroll: function(e) {console.log(e);},goOrderList() {uni.navigateTo({url: '/pages/orderList/list'})}}};</script>// 使用 css插件需要安装<style lang="scss" scoped>.mine {min-height: 100vh;background-color: #f5f5f5;.mine-header {}}</style>
注意事项:
- 页面生命周期 优先使用 小程序那一套,
onLoad(option) {}获取参数,onShow() {}页面显示.
页面跳转方式
保留当前页面,跳转到某个页面
使用uni.navigateBack可以返回到原页面。
/在起始页面跳转到test.vue页面并传递参数uni.navigateTo({url: 'test?id=1&name=uniapp'});
注意: 跳转到 tabBar 页面只能使用 switchTab 跳转
关闭当前页面,跳转到应用内的某个页面。
uni.redirectTo(OBJECT)
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
uni.switchTab(OBJECT)
关闭当前页面,返回上一页面或多级页面
uni.navigateBack(OBJECT)可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
// 在C页面内 navigateBack,将返回A页面uni.navigateBack({delta: 2});
想了解更多?那点我官方走起
数据缓存
同步的话 在后面+Sync 例如:uni.setStorageSync
数据存储在本地缓存(异步接口)
uni.setStorage(OBJECT)指定的 key 中,会覆盖掉原来该 key 对应的内容
uni.setStorage({key: 'storage_key',data: JSON.stringify(data), // 需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象success: function () {console.log('success');}});
从本地缓存中异步获取指定 key 对应的内容
uni.getStorage({key: 'storage_key',success: function (res) {console.log(res.data);}});
异步移除指定 key
uni.removeStorage({key: 'storage_key',success: function (res) {console.log('success');}});
清理本地数据缓存。
uni.clearStorage()
注意:
uni-app的Storage在不同端的实现不同:
- H5端为localStorage,浏览器限制5M大小,是缓存概念,可能会被清理
- App端为原生的plus.storage,无大小限制,不是缓存,是持久化的
- 各个小程序端为其自带的storage api,数据存储生命周期跟小程序本身一致,即除用户主动删除或超过一定时间被自动清理,否则数据都一直可用。
- 微信小程序单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
- 支付宝小程序单条数据转换成字符串后,字符串长度最大200*1024。同一个支付宝用户,同一个小程序缓存总上限为10MB。
- 百度、字节跳动小程序文档未说明大小限制
网络请求
发起网络请求: 官网介绍
uni.request({url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。data: {text: 'uni.request'},header: {'custom-header': 'hello' //自定义请求头信息},success: (res) => {console.log(res.data);this.text = 'request success';}});
- 单次网络请求数据量建议控制在50K以下(仅指json数据,不含图片),过多数据应分页获取,以提升应用体验。
上传文件(图片)
uni.uploadFile(OBJECT)
如页面通过 uni.chooseImage 等接口获取到一个本地资源的临时文件路径后,可通过此接口将本地资源上传到指定服务器。另外选择和上传非图像、视频文件参考:https://ask.dcloud.net.cn/article/35547。
uni.chooseImage({success: (chooseImageRes) => {const tempFilePaths = chooseImageRes.tempFilePaths;uni.uploadFile({url: 'https://www.example.com/upload', //仅为示例,非真实的接口地址filePath: tempFilePaths[0],name: 'file',formData: {'user': 'test'},success: (uploadFileRes) => {console.log(uploadFileRes.data);}});}});
媒体文件操作 官网介绍

常用界面操作 官网介绍

其他辅助功能 官网介绍

使用cli创建项目和使用HBuilderX可视化界面创建项目有什么区别
编译器的区别
cli创建的项目,编译器安装在项目下。并且不会跟随HBuilderX升级。如需升级编译器,执行npm update。- HBuilderX可视化界面创建的项目,编译器在HBuilderX的安装目录下的plugin目录,随着HBuilderX的升级会自动升级编译器。
- 已经使用
cli创建的项目,如果想继续在HBuilderX里使用,可以把工程拖到HBuilderX中。注意如果是把整个项目拖入HBuilderX,则编译时走的是项目下的编译器。如果是把src目录拖入到HBuilderX中,则走的是HBuilderX安装目录下plugin目录下的编译器。 cli版如果想安装less、scss、ts等编译器,需自己手动npm安装。在HBuilderX的插件管理界面安装无效,那个只作用于HBuilderX创建的项目。
结语
所有的评测都只是提供决策依据,最后的结果还是要依赖开发者的团队技术栈、业务诉求、未来规划等。
不过作为一篇评测文章的结语,我们还是要给出自己的建议:
- 如果你熟悉React,不懂Vue.js,推荐Taro;
- 如果你熟悉Vue.js,则推荐 uni-app;
- 如果你已经有H5代码,只想增加微信小程序平台,并且对性能要求不高,可以考虑kbone;
- 如果你的业务涉及多端,更推荐 uni-app;
- 如果你希望通过 serverless 方案快速上线业务,推荐 uni-app。
此结语摘自隔壁大佬:作者:CHB 链接:https://juejin.im/post/5e8e8d5a6fb9a03c6d3d9f42
先到这里了,关注 后期慢慢更新更多~
问题记录
1、需求描述:小程序页面分享带参数 u=userid,别人打开的时候 第一次会走 onLaunch 来获取参数并存储。如果 再打开 另一个人分享的 userid是不同的,此时 onLaunch不在走了,怎么获取参数?
解决方案: 在main.js 里 混入 onLoad
Vue.mixin({onLoad(options){// 获取到参数 操作}}
2、全局 添加 分享功能,实现每个页面都可以 进行特性模式 分享。
解决方案:
Vue.mixin({onShareAppMessage(e) {const merchant = this.$store.getters.merchantreturn {title: merchant.subName,path: `/pages/tabBar/vhome${'?refId='+this.$store.getters.userInfo.uid}`,imageUrl: merchant.posterImg}}})
