一. 扩展组件 uni-ui
1. 扩展组件(uni-ui)
- 什么是
uni-ui
?uni-ui
是DCloud
提供的一个UI
组件库,一套基于Vue
组件、flex
布局的跨全端UI
框架uni-ui
不包括uni-app
框架提供的基础组件,而是基础组件的补充- 详情:https://uniapp.dcloud.net.cn/component/uniui/uni-ui.html
uni-ui
特点- 高性能
- 目前为止,在小程序和混合
app
领域,uni-ui
是性能的标杆 - 自动差量更新数据。
uni-app
引擎底层会自动用diff
算法更新数据 - 优化逻辑层和视图层通讯折损。 比如,需要跟手式操作的
UI
组件,底层使用了wxs
、bindingx
等技术,实现了高性能的交互体验WXS(WeiXin Script)
是小程序的一套脚本语言,结合WXML
,可以构建出页面的结构。在iOS
设备上小程序内的WXS
会比js
代码快 2 ~ 20 倍bindingx
技术提供了一种称之为表达式绑定(Expression Binding
) 的机制,在weex
上让手势等复杂交互操作以60fps
的帧率流畅执行,而不会导致卡顿
- 目前为止,在小程序和混合
- 全端
uni-ui
的组件都是多端自适应的,底层会抹平很多小程序平台的差异或bug
uni-ui
还支持nvue
原生渲染、以及PC
宽屏设备
- 风格扩展
uni-ui
的默认风格是中型的,与uni-app
基础组件风格一致- 支持
uni.scss
,可以方便的扩展和切换应用的风格
- 高性能
2. 安装 uni-ui 组件库
方式一(推荐):通过
uni_modules
(插件模块化规范)单独安装组件,通过uni_modules
按需安装某个组件:- 官网找到扩展组件清单,然后将所需要的组件导入到项目,导入后直接使用,无需
import
和注册 - 通常我们还想切换应用风格,这时可以在
uni.scss
导入uni-ui
提供的内置scss
变量,然后重启应用
注意:需要登录
DCloud
账号才能安装- 官网找到扩展组件清单,然后将所需要的组件导入到项目,导入后直接使用,无需
方式二(推荐) :通过
uni_modules
导入全部组件- 如想把所有
uni-ui
组件导入到项目,可以借用HbuilderX
插件导入 - 如没自动导入其他组件,可在
uni-ui
组件目录上右键选择 安装三方插件依赖 即可
- 如想把所有
方式三:在
HBuilderX
新建uni-app
项目时,在模板中选择uni-ui
模板来创建项目- 由于
uni-app
独特的easycom
(自动导包)技术,可以免引入、注册,就直接使用符合规则的vue
组件
- 由于
方式四:
npm
安装- 在
vue-cli
项目中可用npm
安装uni-ui
库 - 或直接在
HBuilderX
项目中用npm
安装
- 在
3. 定制 uni-ui 主题风格
安装
dart-sass
插件(一般都会提示,并自动安装)在项目根目录的
uni.scss
文件中引入uni-ui
组件库的variable.scss
变量文件,然后就可以使用或修改对应的scss
变量变量主要定义的是主题色
scss// uni.scss /* 需要放到文件最上面 */ @import '@/uni_modules/uni-scss/variables.scss'; /* 以下变量是默认值,如不需要修改可以不用给下面的变量重新赋值 */ // 主色 $uni-primary: #2979ff; $uni-primary-disable:mix(#fff,$uni-primary,50%); $uni-primary-light: mix(#fff,$uni-primary,80%); // 辅助色 // 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 $uni-success: #18bc37; $uni-success-disable:mix(#fff,$uni-success,50%); $uni-success-light: mix(#fff,$uni-success,80%); // 中性色 // 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 $uni-main-color: #3a3a3a; // 主要文字 $uni-base-color: #6a6a6a; // 常规文字 $uni-secondary-color: #909399; // 次要文字 $uni-extra-color: #c7c7c7; // 辅助说明 // 边框颜色 $uni-border-1: #F0F0F0; $uni-border-2: #EDEDED; $uni-border-3: #DCDCDC; $uni-border-4: #B9B9B9; // 常规色 $uni-black: #000000; $uni-white: #ffffff; $uni-transparent: rgba($color: #000000, $alpha: 0); // 背景色 $uni-bg-color: #f7f7f7; /* 水平间距 */ $uni-spacing-sm: 8px; $uni-spacing-base: 15px; $uni-spacing-lg: 30px; // 阴影 $uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5); $uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2); $uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5); // 蒙版 $uni-mask: rgba($color: #000000, $alpha: 0.4);
4. uni-forms 组件
uni-froms
组件使用步骤(类似Element Plus
的表单组件用法):- 安装
uni-forms
等组件 uni-forms
搭建表单布局- 编写表单项的验证规则
- 提交表单时验证表单项
- 重置表单
- 安装
5. 重写 uni-forms 组件样式
小程序、
App
直接重写,需要添加important
H5、App和小程序使用:
global( selector )
,需要添加important
H5 、App和小程序使用:
deep( selector )
,需要添加important
scss/* weapp、app */ .uni-forms-item_label { justify-content: center !important; } /* weapp、h5、app */ :global(.uni-forms-item_label) { justify-content: center !important; } /* weapp、h5、app */ :deep(.uni-forms-item_label) { justify-content: center !important; }
二. 跨端兼容实现
1. 跨平台兼容
uni-app
能实现一套代码、多端运行,核心是通过编译器 + 运行时实现的:- 编译器:将
uni-app
统一代码编译生成每个平台支持的特有代码;如在小程序平台,编译器将.vue
文件拆分生成wxml
、wxss
、js
等 - 运行时:动态处理数据绑定、事件代理,保证
Vue
和对应宿主平台 数据的一致性
- 编译器:将
- 跨平台存在的问题:
uni-app
已将常用的组件、JS API
封装到框架中,开发者按照uni-app
规范开发即可保证多平台兼容,大部分业务均可直接满足- 但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况
- 大量写
if else
,会造成代码执行性能低下和管理混乱 - 编译到不同的工程后二次修改,会让后续升级变的很麻烦
- 大量写
- 跨平台兼容解决方案:
- 在
C
语言中,通过#ifdef
、#ifndef
的方式,为windows
、mac
等不同os
编译不同的代码 uni-app
参考这个思路,为uni-app
提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现
- 在
2. 条件编译

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台
具体的语法:以
#ifdef
或#ifndef
加%PLATFORM%
开头,以#endif
结尾#ifdef
:if defined
仅在某平台存在#ifndef
:if not defined
除了某平台,其它平台均存在%PLATFORM%
:平台名称
支持编写条件编译的文件,如下:
.vue(template 、script 、style)
.js
、.ts
、pages.json
.css
、.scss
、.less
、.stylus
例如:设置页面的标题
H5
专有API
:document.title = ''
- 微信小程序专有
API
:wx.setNavigationBarTitle(object)
3. 注意事项
- 条件编译是利用注释实现的,在不同语法里注释写法不一样
js
使用// 注释
css
使用/* 注释 */
vue/nvue
模板里使用<!-- 注释 -->
- 条件编译
APP-PLUS
包含 :APP-NVUE
和APP-VUE
APP-PLUS-NVUE
和APP-NVUE
没什么区别,为了简写后面出了APP-NVUE
- 使用条件编译请保证编译前和编译后文件的正确性,比如
json
文件中不能有多余的逗号 Android
和iOS
平台不支持条件编译,若需区分Android
、iOS
平台,请通过调用uni.getSystemInfo
来获取平台信息- 微信小程序主题色是绿色,而百度支付宝小程序是蓝色,应用想分平台适配颜色,条件编译是代码量最低、最容易维护的
三. 页面路由和传参
1. 新建 Page 页面
uni-app
页面是编写在pages
目录下:- 可直接在
uni-app
项目上右键 " 新建页面 ",HBuilderX
会自动在pages.json
中完成页面注册 HBuilderX
还内置了常用的页面模板(如图文列表、商品列表等),这些模板可以大幅提升你的开发效率
- 可直接在
- 注意事项:
- 每次新建页面,需在
pages.json
中配置pages
列表(手动才需配置) - 未在
pages.json => pages
中配置的页面,uni-app
会在编译阶段进行忽略
- 每次新建页面,需在
- 删除页面:
- 删除
.vue
文件或.nvue
文件 - 删除
pages.json => pages
列表项中的配置
- 删除
- 配置
tabBar
color
:tab
上的文字默认颜色selectedColor
:tab
上的文字选中时的颜色list
:tab
的列表,详见list
属性说明,最少2个、最多5个tab
2. 页面路由
uni-app
有两种页面路由跳转方式:使用navigator
组件跳转、调用API
跳转(类似小程序,与vue-router
不同)- 组件:
navigator
API
:navigateTo
、redirectTo
、navigateBack
、switchTab
- 组件:
3. 页面间通讯
在
uni-app
中,常见页面通讯方式:- 方式一:
url
查询字符串和EventChannel
- 方式二:使用事件总线
- 方式三:全局数据
globalData
- 方式四:本地数据存储
- 方式五:
Vuex
和Pinia
,状态管理库
- 方式一:
方式一:
url
和EventChannel
(兼容h5
、weapp
、app
)- 直接在
url
后面通过查询字符串的方式拼接- 如
url
查询字符串出现特殊字符等格式,需编码
- 如
- 然后可在
onLoad
生命周期中获取url
传递的参数 url
有长度限制,太长的字符串会传递失败,可使用窗体通信、全局变量,或encodeURIComponent
等多种方式解决,如下为encodeURIComponent
示例
html<navigator :url="'/pages/aaa/bbb?item='+ encodeURIComponent(JSON.stringify(item))"></navigator>
js// bbb.vue页面接受参数 onLoad: function (option) { const item = JSON.parse(decodeURIComponent(option.item)); }
- 直接在
EventChannel
对象的获取方式Options
语法:this.getOpenerEventChannel()
Composition
语法:getCurrentInstance().proxy
、getOpenerEventChannel()
4. 事件总线
方式二:事件总线
uni.$emit( eventName, OBJECT )
触发全局的自定义事件uni.$on( eventName, callback )
监听全局的自定义事件。由uni.$emit
触发uni.$once( eventName, callback )
只监听一次全局的自定义事件。由uni.$emit
触发uni.$off( eventName, callback )
移除全局自定义事件监听器- 如果没有提供参数,则移除所有的事件监听器
注意:
- 需先监听,再触发事件,比如:你在A界面触发,然后跳转到B页面后才监听是不行的
- 通常
on
和off
是同时使用,可以避免多次重复监听 - 适合页面返回传递参数、适合跨组件通讯,不适合界面跳转传递参数
5. 页面生命周期
uni-app
常用的页面生命周期函数:函数名 说明 onLoad
监听页面加载,其参数为上个页面传递的数据,参数类型为 Object
(用于页面传参),参考示例onShow
监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 onReady
监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 onHide
监听页面隐藏 onUnload
监听页面卸载 onPullDownRefresh
监听用户下拉动作,一般用于下拉刷新,参考示例 onReachBottom
页面滚动到底部的事件(不是 scroll-view
滚到底),常用于下拉下一页数据。具体见下方注意事项更多: https://uniapp.dcloud.net.cn/tutorial/page.html#lifecycle
注意:
- 页面可以使用
Vue
组件生命周期吗? 可以的 - 页面滚动才会触发
onReachBottom
回调,如果自行通过overflow
实现的滚动不会触发onReachBottom
回调
- 页面可以使用
四. 其他常用 API
1. 网络请求
uni.request(OBJECT)
发起网络请求- 登录各个小程序管理后台,给网络相关的
API
配置合法域名(域名白名单) - 微信小程序开发工具,在开发阶段可以配置:不校验合法域名
- 运行到手机时,资源没有出来时可以打开手机的调试模式
- 请求的
header
中content-type
默认为application/json
- 登录各个小程序管理后台,给网络相关的
- 文档:https://uniapp.dcloud.net.cn/api/request/request.html#request
2. 数据缓存
uni.setStorage(OBJECT)
- 将数据存储在本地缓存中指定的
key
中,会覆盖掉原来该key
对应的内容,这是一个异步接口
- 将数据存储在本地缓存中指定的
uni.setStorageSync(KEY, DATA)
- 将
data
存储在本地缓存中指定的key
中,会覆盖掉原来该key
对应的内容,这是一个同步接口
- 将
uni.getStorage(OBJECT)
- 从本地缓存中异步获取指定
key
对应的内容
- 从本地缓存中异步获取指定
uni.getStorageSync(KEY)
- 从本地缓存中同步获取指定
key
对应的内容
- 从本地缓存中同步获取指定
uni.removeStorage(OBJECT)
- 从本地缓存中异步移除指定
key
- 从本地缓存中异步移除指定
uni.removeStorageSync(KEY)
- 从本地缓存中同步移除指定
key
- 从本地缓存中同步移除指定
五. 自定义组件
1. 组件(Component)
uni-app
组件与Vue
标准组件基本相同,但是也有一点区别,比如:传统
vue
组件,需要创建组件、引用、注册,三个步骤后才能使用组件,easycom
组件模式可以将其精简为一步easycom
组件规范:- 组件需符合
components
/组件名称/组件名称.vue
的目录结构 - 符合以上目录结构的就可不用引用、注册,直接在页面中使用该组件了
- 组件需符合
2. 组件生命周期
uni-app
组件支持的生命周期,与Vue
组件的生命周期相同- 组件中可以使用页面的生命周期吗?
- 在
Options API
语法:组件中不支持使用页面生命周期 - 在
Composition API
语法:组件中支持页面生命周期,不同端支持情况有差异
- 在
- 组件中可以使用页面的生命周期吗?
六. 状态管理 pinia
认识
Pinia
Pinia
(发音为/piːnjʌ/
,如英语中的peenya
) 是Vue
的存储库,它允许跨组件、页面共享状态uni-app
内置了Pinia
,使用HBuilderX
不需要手动安装,直接使用即可uni-app
内置了vuex
使用
CLI
需要手动安装bash# yarn yarn add pinia # npm npm i pinia
Pinia
的初体验,步骤如下:第一步:在
main.js
中安装Pinia
插件,app.use(Pinia.createPinia())
jsimport { createSSRApp } from 'vue' import * as Pinia from 'pinia' export function createApp() { const app = createSSRApp(App) app.use(Pinia.createPinia()) return { app, Pinia, // 此处必须将 Pinia 返回 }; }
第二步:接着创建一个
store
js// stores/counter.js import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => { return { count: 0 }; }, // 也可以这样定义 // state: () => ({ count: 0 }) actions: { increment() { this.count++ }, }, });
第三步:然后在组件中就可以直接使用了
jsimport { useCounterStore } from '@/stores/counter' export default { setup() { const counter = useCounterStore() counter.count++ // 可以手动触发 counter.$patch({ count: counter.count + 1 }) // 或者使用 actions counter.increment(); }, };
七. uni-app 项目实战
1. 项目目录结构
{
}
2. 微信小程序-打包配置
- 注册一个小程序账号: https://mp.weixin.qq.com/wxopen/waregister?action=step1
- 登录已注册好的账号,拿到小程序
APPID
:wxbc30134b589795b0
(需要用你自己申请的) - 修改一下
manifest.json
的基础配置和微信小程序配置(比如:appid
、es6-es5
、压缩) - 发行 => 打包微信小程序
- 在微信开发者工具中点击 上传 代码


3. H5-打包配置(一)


4. H5-打包配置(二)
购买阿里云服务器
连接阿里云服务器(
VSCode
安装Remove SSH
插件)安装
Nginx
服务器shellsudo yum install nginx # 安装nginx sudo systemctl enable nginx # 设置开机启动
启动
Nginx
服务器shellsudo service nginx start # 启动nginx服务 sudo service nginx restart # 重启nginx服务
修改
Nginx
的配置(/etc/nginx/nginx.conf
)- 切换为
root
用户,修改部署路径
- 切换为
打包和部署项目
5. Android-云打包配置
- 注册一个
Dcloud
账号: https://dev.dcloud.net.cn/ 或在HBuilderX
中注册 HBuilderX
登录已注册好的账号,然后在manifest.json
中配置应用基本信息- 云打包
Android
时,会自动生成证书(也可以手动生成) - 开始执行云打包



6. Android-离线本地打包(一)
生成本地打包
App
资源- 先完成社区身份验证,请点击链接 https://ask.dcloud.net.cn/account/setting/profile
- 验证后再重新打包:原生
App
=> 本地打包 => 生成本地打包App
资源

7. Android-离线本地打包(二)
生成证书(
jks
文件)- 文件密码
- 证书别名:
hymall01
(根据你自己的来) - 证书密码
通过证书获取
sha1
(https://ask.dcloud.net.cn/article/35777)keytool -list -v -keystore
生成的证书文件D2:15:91:B8:24:97:D1:BC:B9:8B:CF:07:44:DA:C7:90:C4:44:C8:E5
8. Android-离线本地打包(三)
获取
Appkey
- 登录
DCloud
开发者中心:https://dev.dcloud.net.cn/pages/app/list - 我的应用中找到需要打包的应用,然后点击该应用查看应用的信息,选择离线打包
key
管理Appkey
:58129cb2c328630a7416913c58ba6a9f
- 登录
9. Android-离线本地打包(四)
离线打包
apk
常见配置(项目路径不支持中文):- 配置
Appkey
:Appkey
- 配置应用版本号:
versionCode
- 应用的版本名称:
versionName
- 应用的包名,一般设置为反向域名:
applicationId
SDK
最低支持版本21:minSdkVersion
- 配置应用名称
app_name
,建议与manifest.json
中name
同为一个 - 图标名称:
icon.png
为应用的图标splash.png
为应用启动页的图标push.png
为推送消息的图标- 资源配置,包括:导出的
app
资源和data
资源 dcloud_control.xml
中的appid
为拷贝过来的uni-app
的id
- 配置