学废uni-app

401 阅读13分钟

关于uni-app

什么是uni-app

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

uni-app优势

  • 开发者/案例数量更多
  • 平台能力不受限
  • 性能体验优秀
  • 周边生态丰富
  • 学习成本低
  • 开发成本低

功能框架图

8728f5385e484a4ff512d9c27588ad59_uni-function-diagram.png

环境构建

开发工具

这里使用HBuilderX作为开发工具。

HBuilderX是通用的前端开发工具,但为uni-app做了特别强化。

创建 uni-app 项目

点击工具栏里的文件 -> 新建 -> 项目:

8edf45565e37274388132a93717fbb7d_hx-create-01.png 选择uni-app类型,输入工程名,选择模板,点击创建,即可成功创建。

uni-app自带的模板有 默认的空项目模板、Hello uni-app 官方组件和API示例,还有一个重要模板是 uni ui项目模板,日常开发推荐使用该模板,已内置大量常用组件。

35f7576fbaa8a3cc9464feaab9d6b7ae_create-uniapp.jpg

运行 uni-app应用

  • 浏览器运行
    • 点击工具栏的运行 -> 运行到浏览器 -> 选择浏览器

7554794c367b07db5c98809b5adb4f3b_menurun.png

  • 小程序中运行
    • 点击工具栏的运行 -> 运行到小程序模拟器 -> 微信开发者工具

2be81765a0468624ec7416419dc01d62_menurunminiapp.png 注意:如果是第一次使用,需要先配置小程序ide的相关路径,才能运行成功。如下图,需在输入框输入微信开发者工具的安装路径。

f377a1a2b29360dbaf4d4b8c487cba00_weixin-setting.png

注意:微信开发者工具需要开启服务端口 在微信工具的设置->安全中

  • 运行App到手机或模拟器

    • 使用电压足够的usb端口连接手机,设置中开启USB调试,手机上允许电脑设备调试手机,进入hello-uniapp项目,点击工具栏的运行 -> 运行App到手机或模拟器,即可在该设备里面体验uni-app。

8956073fe6a290e37b83aa4035bada86_menurunapp.png

如有问题可参考常见故障排查指南

uni-app工程配置

  • 目录结构
┌─uniCloud              云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb
│─components            符合vue组件规范的uni-app组件目录
│  └─comp-a.vue         可复用的a组件
├─utssdk                存放uts文件
├─pages                 业务页面文件存放的目录
│  ├─index
│  │  └─index.vue       index页面
│  └─list
│     └─list.vue        list页面
├─static                存放应用引用的本地静态资源(如图片、视频等)的目录,注意: 静态资源只能存放于此
├─uni_modules           存放[uni_module](/uni_modules)。
├─platforms             存放各平台专用页面的目录
├─nativeplugins         App原生语言插件
├─nativeResources       App端原生资源目录
│  └─android            Android原生资源目录 
├─hybrid                App端存放本地html文件的目录
├─wxcomponents          存放小程序组件的目录
├─unpackage             非工程代码,一般存放运行或发行的编译结果
├─AndroidManifest.xml   Android原生应用清单文件
├─main.js               Vue初始化入口文件
├─App.vue               应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json         配置应用名称、appid、logo、版本等打包信息
├─pages.json            配置页面路由、导航条、选项卡等页面类信息
└─uni.scss              这里是uni-app内置的常用样式变量
  • static目录 使用注意

    • 编译到任意平台时,static 目录下除不满足条件编译的文件,会直接复制到最终的打包目录,不会打包编译。非 static 目录下的文件(vue、js、css 等)只有被引用时,才会被打包编译。
    • cssless/scss 等资源不要放在 static 目录下,建议这些公用的资源放在自建的 common 目录下。
  • manifest.json 应用配置

    • manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。
  • pages.json页面路由

    • pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。它类似微信小程序中app.json页面管理部分。注意定位权限申请等原属于app.json的内容,在uni-app中是在manifest中配置。
  • 全局样式 uni.scss

    • uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。
    • uni-app 官方扩展插件(uni ui)及 插件市场 上很多三方插件均使用了这些样式变量,如果你是插件开发者,建议你使用 scss 预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App。
    • uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的编译器在webpack配置中特殊处理了这个uni.scss,使得每个scss文件都被注入这个uni.scss,达到全局可用的效果。如果开发者想要less、stylus的全局使用,需要在vue.config.js中自行配置webpack策略。
  • 主组件 App.vue

    • App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素,也就是没有<template>
    • 这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData
    • 应用生命周期仅可在App.vue中监听,在页面监听无效。
  • 入口文件 main.js

    • main.js是 uni-app 的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex

开发规范

为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:

  • 页面文件遵循 Vue 单文件组件 (SFC) 规范,即每个页面是一个.vue文件
  • 组件标签靠近小程序规范,详见uni-app 组件规范
  • 接口能力(JS API)靠近小程序规范,但需将前缀 wxmy 等替换为 uni,详见uni-app接口规范
  • 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
  • 如需兼容app-nvue平台,建议使用flex布局进行开发

生命周期

uni-app 完整支持 Vue 实例的生命周期,同时还新增 应用生命周期页面生命周期

  • 应用生命周期
函数名说明
onLaunchuni-app 初始化完成时触发(全局只触发一次)
onShow当 uni-app 启动,或从后台进入前台显示
onHide当 uni-app 从前台进入后台
onError当 uni-app 报错时触发
onUniNViewMessage对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯
onUnhandledRejection对未处理的 Promise 拒绝事件监听函数(2.8.1+)
onPageNotFound页面不存在监听函数
onThemeChange监听系统主题变化
  • 页面生命周期
函数名说明
onLoad监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参),参考示例
onShow监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
onHide监听页面隐藏
onUnload监听页面卸载
onResize监听窗口尺寸变化

...

uni-app路由配置及页面跳转

页面路由

uni-app 页面路由全部交给框架统一管理,需要在pages.json里配置每个路由页面的路径及页面样式(类似小程序在 app.json 中配置页面路由)。

	"pages": [{
		"path": "pages/component/index",
		"style": {
			"navigationBarTitleText": "组件"
		}
	}, {
		"path": "pages/API/index",
		"style": {
			"navigationBarTitleText": "接口"
		}
	}, {
		"path": "pages/component/view/index",
		"style": {
			"navigationBarTitleText": "view"
		}
	}]

路由跳转

uni-app 有两种页面路由跳转方式:使用navigator组件跳转、调用API跳转。

该组件类似HTML中的<a>组件,但只能跳转本地页面。目标页面必须在pages.json中注册。

uni-app以栈的形式管理当前所有页面, 当发生路由切换的时候,页面栈的表现如下:

路由方式页面栈表现触发时机
初始化新页面入栈uni-app 打开的第一个页面
打开新页面新页面入栈调用 API   uni.navigateTo  、使用组件  <navigator open-type="navigate"/>
页面重定向当前页面出栈,新页面入栈调用 API   uni.redirectTo  、使用组件  <navigator open-type="redirectTo"/>
页面返回页面不断出栈,直到目标返回页调用 API  uni.navigateBack   、使用组件 <navigator open-type="navigateBack"/> 、用户按左上角返回按钮、安卓用户点击物理back按键
Tab 切换页面全部出栈,只留下新的 Tab 页面调用 API  uni.switchTab  、使用组件  <navigator open-type="switchTab"/>  、用户切换 Tab
重加载页面全部出栈,只留下新的页面调用 API  uni.reLaunch  、使用组件  <navigator open-type="reLaunch"/>

获取当前页面栈

  • getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面
  • 注意:  getCurrentPages()仅用于展示页面栈的情况,请勿修改页面栈,以免造成页面状态错误

路由参数传递与接收

//在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
	url: 'test?id=1&name=lisi'
});
// 在test.vue页面接受参数
export default {
	onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
		console.log(option); //打印出上个页面传递的参数。
	}
}

image.png

小程序的分包加载--subPackages

  • 小程序有体积和资源加载限制,各家小程序平台提供了分包方式,优化小程序的下载和启动速度。
  • 所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据pages.json的配置进行划分。
  • 小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示。此时终端界面会有等待提示。
  • App默认为整包。从uni-app 2.7.12+ 开始,也兼容了小程序的分包配置。其目的不用于下载提速,而用于首页是vue时的启动提速。App下开启分包,除在pages.json中配置分包规则外,还需要在manifest中设置在app端开启分包设置
	"subPackages": [{
		"root": "pagesA",
		"pages": [{
			"path": "list/list",
			"style": { ...}
		}]
	}, {
		"root": "pagesB",
		"pages": [{
			"path": "detail/detail",
			"style": { ...}
		}]
	}]
        

uni-app的组件

  • uni-app为开发者提供了一系列基础组件,类似HTML里的基础标签元素
  • uni-app的组件与HTML不同,而是与小程序相同,可更好的满足手机端的使用习惯
  • 不推荐使用HTML标签,但实际上如果开发者写了div等标签,在编译到非H5平台时也会被编译器转换为view标签,类似的还有spantextanavigator等,包括css里的元素选择器也会转。但为了管理方便、策略统一,新写代码时仍然建议使用view等组件

uni-app的API

  • uni-app的 js API 由标准 ECMAScript 的 js API 和 uni 扩展 API 这两部分组成
  • 标准 ECMAScript 的 js 仅是最基础的 js。浏览器基于它扩展了 window、document、navigator 等对象。小程序也基于标准 js 扩展了各种 wx.xx、my.xx、swan.xx 的 API。node 也扩展了 fs 等模块
  • uni-app 基于 ECMAScript 扩展了 uni 对象,并且 API 命名与小程序保持兼容

标准 js 和浏览器 js 的区别

uni-app的 js 代码,web端运行于浏览器中。非web端(包含小程序和 App),Android 平台运行在 v8 引擎中,iOS 平台运行在 iOS 自带的 jscore 引擎中,都没有运行在浏览器或 webview 里。

非web端,虽然不支持 window、document、navigator 等浏览器的 js API,但也支持标准 ECMAScript。

注意不要把浏览器里的 js 等价于标准 js。

uni-app 的web端,一样支持标准 js,支持 if、for 等语法,支持字符串、数字、时间、布尔值、数组、自定义对象等变量类型及各种处理方法。仅仅是不支持 window、document、navigator 等浏览器专用对象。

API调用

除了 uni-app 框架内置的跨端 API,各端自己的特色 API 也可通过条件编译自由使用

各端特色 API 规范参考各端的开发文档。其中 App 端的 JS API 参考html5plus.org;uni-app 也支持通过扩展原生插件来丰富 App 端的开发能力,具体参考插件开发文档

各平台的 API 新增,不需要 uni-app 升级,开发者就可以直接使用。

uni.chooseImage({
	count: 6, //默认9
	sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
	sourceType: ['album'], //从相册选择
	success: function (res) {
		console.log(JSON.stringify(res.tempFilePaths));
	}
});

uni-app之vuex全局状态管理

  • vuex是什么?

    • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
  • 核心概念

    • State:存储状态数据
    • Getter:从状态数据派生数据,相当于 State 的计算属性
    • Mutation:存储用于同步更改状态数据的方法,默认传入的参数为 state
    • Action:存储用于异步更改状态数据,但不是直接更改,而是通过触发 Mutation 方法实现,默认参数为context
    • Module:Vuex 模块化
  • 关系图

2.png

uni-app运行环境与跨端兼容

区分生产、开发环境

  • uni-app 可通过 process.env.NODE_ENV 判断当前环境是开发环境还是生产环境。
  • HBuilderX 中,点击“运行”编译出来的代码是开发环境,点击“发行”编译出来的代码是生产环境
if (process.env.NODE_ENV === 'development') {
	console.log('开发环境');
} else {
	console.log('生产环境');
}

判断平台

平台判断有 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;
}

如有必要,也可以在条件编译里自己定义一个变量,赋不同值。在后续运行代码中动态判断环境。

跨端兼容

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% :平台名称

传送门:uniapp.dcloud.net.cn/tutorial/pl…