小程序+UniApp开发笔记
一、小程序简介
1.小程序开发与普通网页开发的区别
(1)运行环境不同:网页运行在浏览器环境中,小程序运行在微信环境中
(2)API不同:由于运行环境不同,所以小程序中无法调用DOM和BOM的API,但是小程序中可以调用微信环境提供的各种API,例如:
- 地理定位
- 扫码
- 支付
(3)开发模式不同:网页的开发模式为浏览器+代码编辑器,小程序的开发模式为:
- 申请小程序开发账号
- 安装小程序开发工具
- 创建和配置小程序项目
二、UniApp快速入门
1.UniApp介绍
(1)什么是UniApp:uni-app是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5,以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多平台,方便开发者快速交付,不需要转换开发思维,不需要更改开发习惯
(2)为什么选择UniApp:
- 开发者/案例数量更多:应用多、月活高、用户多
- 平台能力不受限:在跨端的同时,通过条件编译+平台特有API调用,可以优雅的为某平台写个个性化代码,调用专有能力而不影响其他平台
- 性能体验优秀:加载新页面速更快、自动diff更新数据,App端支持原生渲染支撑更流畅的用户体验,小程序端的性能优于市场其他框架
- 周边生态丰富:插件市场的数千款插件,支持NPM、支持小程序组件和SDK,微信生态的各种SDK可直接用于跨平台App
- 学习成本低:基于通用的前端技术栈,采用Vue语法+微信小程序API,无额外学习成本
(3)功能框架:

(4)UniApp开发环境搭建
- 下载开发工具HBuilderX:HBuilderX是通用的前端开发工具,但为uni-app做了特别强化,下载App开发版,可开箱即用;
- 创建uni-app项目:选择uni-app类型,输入工程名,选择模板,点击创建,即可完成创建。uni-app自带的模板有Hello uni-app,是官方的组件和API示例,还有一个重要的模板是uni ui项目模板,日常开发推荐使用该模板,已内置大量常用组件
- 运行uni-app:浏览器运行、真机运行、小程序运行等
- 发布uni-app:云端原生App、离线原生App、H5、各种小程序
2.UniApp初始化相关配置
(1)工具目录结构
├── components uni-app组件目录
├── hybrid 存放本地网页的目录(自建)
├── platforms 存放各平台专用页面的目录(自建)
├── pages 业务页面文件存放的目录
├── static 存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├── wxcomponents 存放小程序组件的目录(自建)
├── common 公共资源(自建)
├── api 请求封装(自建)
├── store 状态管理(自建)
├── main.js Vue初始化入口文件
├── App.vue 应用配置,用来配置App全局样式以及监听应用生命周期
├── mainfest.json 配置应用名称、appid、logo、版本等打包信息
└── pages.json 配置页面路由、导航条、选项卡等页面类信息
static下目录的js文件不会被webpack编译,里面如果有ES6的代码,不经过转换直接运行,在手机设备上会报错- 所以
less、scss等资源同样不要放在static目录下,建议这些公共的资源放在common目录下
(2)应用配置mainfest.json
mainfest.json文件是应用的配置文件,用于指定应用的名称、图标、权限等,也可以在这里为Vue为H5设置跨域拦截处理器
(3)编译配置vue.config.js
vue.config.js是一个可选的配置文件,如果项目的根目录中存在这个文件,那么它会被自动加载,一般用于配置webpack等编译选项
(4)全局配置page.json
-
page.json文件用对uni-app进行全局配置,决定页面文件按的路径、窗口样式、原生的导航栏、底部的原生tabbar等。它类似微信小程序中app.json的页面管理部分属性 类型 必填 描述 globalStyle Object 否 设置默认页面的窗口表现 pages Object Array 是 设置页面路径及窗口表现 easycom Object 否 组件自动引入规则 tabBar Object 否 组件自动引入规则 condition Object 否 启动模式配置 subPackages Object Array 否 分包加载配置 preloadRule Object 否 分包预下载规则
(5)全局样式uni.scss
uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置uni.scss官方扩展插件(uni ui)及插件市场上很多三方插件军使用了这些样式变量,如果你是插件开发者,建议使用scss预处理,并在插件代码中直接使用这些变量(无需import这个文件),方便使用户通过搭积木的方式开发整体风格一致的Appuni.scss是一个特殊文件,在代码中无需import这个文件即可在scss代码中使用这里的样式变量。uni-app中的编译器在webpack配置中特殊处理了这个uni.scss,是的每个scss文件都被注入了这个uni.scss,达到全局可用的效果。如果开发者想要less、stylus的全局使用,需要在vue.config.js中自行配置webpack策略
(6)主组件App.vue
App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写试图元素- 这个文件作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储
globalData - 应用生命周期仅可在
App.vue中监听,在页面监听无效
(7)入口文件main.js
main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex
(8)UniApp开发规范及资源路径
-
开发规范约定
- 页面文件向导
Vue单文件组件(SFC)规范,结构template、脚本script、样式style - 组件标签靠近小程序规范,详见
uni-app组件规范 - 互连能力(JS API)靠近微信小程序规范,但需要将wx替换为nui,详见
uni-app接口规范 - 数据绑定及时间处理同
Vue.js规范,同时补充了App和页面的生命周期 - 为兼容多端运行,建议使用
flex布局新型开发
- 页面文件向导
-
资源路径说明
- template内约定静态资源,如:
image、video等标签的src属性,可以使用相对路径或绝对路径,形式入下:
<!-- 绝对路径,/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>- 注意:
- @初始化的绝对路径以及相对路径会通过
base64转换规则校验 - 约定的静态资源在非
H5平台,均不转为base64 H5平台,小于4KB的资源会被转译成base 64,其余不转
- @初始化的绝对路径以及相对路径会通过
js文件或script标签内,可以使用相对路径和绝对路径,形式如下:
// 绝对路径,@指向项目根目录,在cli项目中@指向src目录 import add from '@/common/add.js' // 相对路径 import add from '../../common/add.js'css文件或style标签内,可以使用相对路径和绝对路径,形式如下:
// 绝对路径 @import url('/common/uni.css') @import url('@/common/uni.css') //相对路径 @import url('../../common/uni.css')css文件或style标签内引用的图片路径,可以使用相对路径也可以使用绝对路径,形式如下:
// 绝对路径 background-image: url(/static/logo.png) background-image: url(@/static/logo.png) // 相对路径 background-image: url(../../static/logo.png) - template内约定静态资源,如:
3.UniApp生命周期
- 学习工具的核心是为了解决核心业务逻辑问题,
uni-app完整支持Vue实例的生命周期,同时还新增应用生命周期及页面生命周期
(1)应用生命周期
| 函数名 | 说明 |
|---|---|
| onLaunch | 当uni-app初始化完成时触发(全局只出发一次) |
| onShow | 当uni-app启动,或从后台进入前台显示 |
| onHide | 当uni-app从前台进入后台 |
| onError | 当uni-app报错时触发 |
| onUniNViewMessage | 对nvue页面发送的数据进行监听,可参考nvue向vue通讯 |
| onUnhandleRejection | 对未处理的Promise拒绝事件监听函数 |
| onPageNotFound | 页面不存在监听函数 |
| onThemeChange | 监听系统主题变化 |
(2)页面生命周期
| 函数名 | 说明 |
|---|---|
| onLoad | 监听页面加载,参数为上个页面传递的数据,参数类型为Object(用于页面传参) |
| onShow | 监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 |
| onReady | 监听页面初次渲染完成,注意如果渲染速度快,会在页面进入动画完成前触发 |
| onHide | 监听页面隐藏 |
| onUnload | 监听页面卸载 |
| onResize | 监听窗口尺寸变化 |
| onReachBottom | 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据 |
| onTabItemTap | 点击tab时触发,参数为Object, |
| onShareAppMessage | 用户点击右上角分享 |
| onPageScroll | 监听页面滚动,参数为Object |
| onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为Object |
| onBackPress | 监听页面返回 |
| onNavigationBarSearchInputChanged | 监听原生标题搜索输入框输入内容变化事件 |
| onNavigationBarSearchInputConfirmed | 监听原生标题栏搜索事件,用户点击软键盘上的“搜索”按钮时触发 |
| onNavigationBarSearchInputClicked | 监听原生标题栏搜索输入框点击事件 |
| onShareTimeline | 监听用户点击右上角转发到朋友圈 |
| onAddToFavorites | 监听用户点击右上角收藏 |
4.UniApp路由配置及页面跳转
(1)路由配置
uni-app页面路由全部交给框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式(类似小程序在app.json中配置页面路由)
{
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",//设置页面标题文字
"enablePullDownRefresh":true//开启下拉刷新
}
},
...
]
}
(2)路由跳转
uni-app有两种页面路由跳转方式:使用navigator组件跳转(标签式导航)、调用API跳转(编程式导航)- 框架已栈的形式管理当前所有页面,当发生路由切换时,页面栈表现如下:
| 路由方式 | 页面栈表现 | 触发时机 |
|---|---|---|
| 初始化 | 新页面入栈 | uni-app打开的第一个页面 |
| 打开新页面 | 新页面入栈 | 调用API:uni.navigateTo使用组件<navigator open-type="navigate" /> |
| 页面重定向 | 当前页面出栈,新页面进栈 | 调用API:uni-redirectTo使用组件 |
| 页面返回 | 页面不断出栈,直到目标返回页 | 调用API:uni.navigateBack使用组件,用户按左上角返回按钮、安卓用户点击物理back按键 |
| Tab切换 | 页面全部出栈,只留下新的Tab页面 | 调用API:uni.switchTab使用组件 |
| 重加载 | 页面全部出栈,只留下新的页面 | 调用API:uni.reLaunch使用组件 |
(3)获取当前页面栈
getCurrentPages()函数用户获取当前页面栈的实例,一数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面- 注意:
getCurrentPages()仅用于展示页面栈的情况,请勿修改页面栈,以免造成页面状态错误
(4)路由传参与接收
- 说明:页面生命周期的
onLoad()监听页面加载,其参数为上个页面传递的数据,如:
// 页面跳转并传递参数
uni.navigateTo({
url: 'page2?name=Tom&message=Hello'
});
url为将要跳转的页面路径,路径后可以带参数,参数与路径之间用?分割,参数键与参数值用=相连,不同参数用&分割,如:path?key1=value2&key2=value2,path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数
// 页面2接收参数
onLoad: function (option) { // option为object类型,会序列化上个页面传递的参数
console.log(option.name); // 打印上个页面传递的参数
console.log(option.message); // 打印上个页面传递的参数
}
- 注意:
url有长度限制,太长的字符串会传递失败,并且不规范的字符格式也可能导致传递失败,所以对于复杂参数建议使用encodeURI、decodeURI进行处理后传递
(5)小程序由分包配置
- 因为小程序体积和资源加载限制,各家小程序平台提供了分包方式,优化小程序下载和启动速度。所谓主包,即防止默认启动页面及
TabBar页面;而分包则是根据page.json的配置进行划分 - 在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后在进行展示,此时终端界面会有等待提示、
"subPackages": [{
"root": "subpages",
"pages": [{
"path": "news/news",
"style": {
"navigationBarTitleText": "新闻中心",
"enablePullDownRefresh": false
}
}]
}],
// 预下载分包设置
"preloadRule": {
"pages/index": {
"network": "all",
"packages": ["activities"]
}
},
5.UniApp常用组件简介
uni-app为开发者提供了一系列基础组件,类似HTML里的基础标签元素,但uni-app的组件与HTML不同,而是与小程序相同,更适合手机端使用- 虽然不推荐使用
HTML标签,但实际上如果开发者写了div等标签,在编译到非H5平台时会被编译器转换为view标签类似的还有span转text、a转navigator等,包括CSS里元素选择器也会转,但为了管理方便、策略统一,新写代码时仍然建议使用view等组件 - 开发者可以通过组合这些基础组件进行快速开发,基于内置的基础组件,可以开发各种扩展组件,组件规范与
Vue组件相同
6.UniApp常用API简介
-
uni-app的js代码,H5端运行于浏览器中,非H5端Android平台运行在v8引擎中,iOS平台运行在iOS自带的jscore引擎中,所以,uni-app的js API由标准ECMAScript的js API和uni扩展js API者两部分组成 -
ECMAScript由Ecma国际管理,时基础js语法,浏览器基于标准js扩充了windows、document等js API,Node.js基于标准js扩充了fs等模块,小程序也基于标准js扩展了各种wx.xx、my.xx、swan.xx的API,标准ECMAScript的API非常多,比如:console、settimeout等 -
非
H5端,虽然不支持window、document、navigator等浏览器的js API,但也支持标准ECMAScript,开发者不要把浏览器里的js等价于标准js -
所以
uni-app的非H5端,一样支持标准js,支持if、for等语法,支持字符串、数组、事件等变量及各种处理方法,仅仅是不支持浏览器专用对象
7.UniApp自定义组件于通信
(1)自定义组件概念
- 组件是
Vue技术中非常重要的部分,组件是的于UI相关的轮子可以方便的制造和共享,进而是的Vue使用者的开发效率大幅提升,在项目component目录下存放组件,uni-app仅支持Vue单文件组件(.vue组件) - 组件可以使用【全局注册】和【页面引入】两种方式进行使用,使用非为三步:
- 导入
import xxx from 'xxx' - 注册
Vue.use('xxx',xxx),componets:{ xxx } - 使用
<xxx />
- 导入
(2)父子组件通信
- 父组件通过自定义属性向子组件传递数据
- 子组件通过
props接收父组件传递的数据 - 父组件通过自定义事件标签向子组件传递事件
- 子组件通过触发父组件定义事件方式修改父组件数据
(3)slot数据分发与作用域插槽
- 父组件通过调用子组件内部嵌套
html内容作为slot分发给子组件 - 子组件通过
slot标签添加属性,向父组件通信数据,作用域插槽
(4)全局事件定义及通信
- 在整个应用的任何地方均可以使用
uni.$on创建一个全局事件 - 在整个应用的任何地方也均可以使用
uni.$emit来触发全局事件,实现多组件间的数据通信
8.UniApp Vuex状态管理
(1)概念
Vuex是一个专为Vue.js应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
(2)应用场景
Vue多个组件之间需要共享数据或状态
(3)关键规则
State:存储状态数据Getter:冲状态数据派生数据,相当于State的计算属性Mutation:存储用于同步更改状态数据的方法,默认传入的参数为StateAction:存储用于异步更改状态数据,但不是直接更改,而是通过触发Mutation方法实现,默认参数为contextModule:Vuex模块化
9.运行环境判断与跨端兼容
(1)开发环境和生产环境
uni-app可通过process.env.NODE_ENV判断当前环境是开发环境还是生产环境,一般用于连接测试服务器或生产服务器的动态切换- 在
HBuilderX中,点击【运行】编译出来的代码是开发环境,点击【发行】编译出来的代码是生产环境
if (process.env.NODE_ENV === 'development') {
console.log('开发环境')
} else {
console.log('生产环境')
}
(2)判断平台
- 平台判断有2种场景,一种是在编译期判断,一种是运行期判断
- 编译期判断,即条件编译,不同平台在编译出包后已经是不同的代码
// #ifdef H5
alert("只有H5平台才有alert方法")
// #endif
// 如上代码指挥编译到H5发行包里,其他平台的包不会包含如上代码
- 运行期判断是指代码已经打入包中,仍然需要在运行期判断平台,此时可使用
uni.getSystemInfoSync().platform判断客户端环境是Android、iOS还是消除程序开发工具
switch (uni.getSystemInfoSync().platform) {
case 'android':
console.log('运行在Android上')
break;
case 'ios':
console.log('运行在iOS上')
break;
default:
console.log('运行在开发者工具上')
break;
}
(3)跨端兼容
uni-app已将常用的组件、JS API封装到框架中,开发者按照uni-app规范开发即可保证多平台兼容,大部分业务均可直接满足,但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况- 大量写
if else,会造成代码执行性能低下和管理混乱 - 编译到不同的工程后二次修改,会让后续需升级变得很麻烦
- 大量写
- 在C语言中,通过
#ifdef、#ifndef的方式,为windows、mac等不同OS编译不同的代码,uni-app参考这个思路,为uni-app提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现 - 条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台,写法:以
#ifdef或#ifndef加%PLATFORM%开头,以#endif结尾#ifdef:if defined仅在某平台存在#ifndef:if not defined除了某平台均存在%PLATFORM%:平台名称
%PLATFORM%可取值如下:
| 值 | 平台 |
|---|---|
| APP-PLUS | App |
| APP-PLUS-NVUE | App nvue |
| H5 | H5 |
| MP-WEIXIN | 微信小程序 |
| MP-ALIPY | 支付宝小程序 |
| MP-BAIDU | 百度小程序 |
| MP-TOUTIAO | 字节跳动小程序 |
| MP-QQ | QQ小程序 |
| MP-360 | 360小程序 |
| MP | 微信小程序/支付宝小程序/百度小程序/字节跳动小程序/QQ小程序/360小程序 |
| QUICKAPP-WEBVIEW | 快应用通用(包含联盟、华为) |
| QUICKAPP-WEBVIEW-UNION | 快应用联盟 |
| QUICKAPP-WEBVIEW-HUAWEI | 快应用华为 |

本文介绍了uni-app框架,它允许开发者使用Vue.js编写代码,实现多平台应用发布,包括微信、支付宝等小程序。uni-app的开发环境包括HBuilderX,项目结构、配置文件如mainfest.json和vue.config.js等进行了详细说明。此外,文章还涵盖了uni-app的生命周期、页面路由配置、组件和API使用,以及跨端兼容和状态管理(Vuex)等内容。
295

被折叠的 条评论
为什么被折叠?



