初衷
近期公司要开发一个电商小程序,之前的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.merchant
return {
title: merchant.subName,
path: `/pages/tabBar/vhome${'?refId='+this.$store.getters.userInfo.uid}`,
imageUrl: merchant.posterImg
}
}
})