uni-app
uni-app
uni-app
是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
DCloud
公司拥有900万开发者、数百万应用、12亿手机端月活用户、数千款uni-app插件、70+微信/qq群。阿里小程序工具官方内置uni-app(详见),腾讯课堂官方为uni-app录制培训课程(详见),开发者可以放心选择。
uni-app
在手,做啥都不愁。即使不跨端,uni-app
也是更好的小程序开发框架(详见)、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。
看视频,10分钟了解uni-app
为什么要选择uni-app?
uni-app
在开发者数量、案例、跨端抹平度、扩展灵活性、性能体验、周边生态、学习成本、开发成本等8大关键指标上拥有更强的优势。
功能框架图
一套代码编到14个平台,这不是梦想。眼见为实,扫描14个二维码,亲自体验最全面的跨平台效果!
一套代码,运行到多个平台
uni-app
实现了一套代码,同时运行到多个平台;如下图所示,一套代码,同时运行到iOS模拟器、Android模拟器、web、微信开发者工具、支付宝小程序Studio、百度开发者工具、字节跳动开发者工具、QQ开发者工具(底部每个终端选项卡,代表1个终端模拟器):
快速上手
在manifest.jon文件中填写你自己注册下来小程序AppID
HBuilderX与微信开发者工具联动
目录结构
目录名 | 功能描述 |
---|---|
pages目录 | 存放页面文件 |
static目录 | 存放静态文件 (图片) |
App.vue文件 | 所有小程序页面都被引用到该文件运行 |
main.js文件 | 项目入口文件,用来初始化VUE对象,定义全局组件等 |
manifest.json文件 | 工程配置文件,声明应用的名称、图标、权限等 |
pages.json文件 | 页面注册文件,配置页面路径、窗口样式、标题文字等 |
uni.scss文件 | 全局样式文件 |
什么是uniapp框架
使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到 iOS、Android、Web、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台
官网地址:https://uniapp.dcloud.net.cn/
VScode插件安装
通过uni-app框架创建项目
HBuilderX可视化方式(只能在XBuild中运行)
HBuilderX工具下载
https://www.dcloud.io/hbuilderx.html
vue-cli命令行方式(可以再VS code中运行)
### 环境安装
# 查看是否安装有@vue/cli
vue -V
# 设置镜像源
npm config set registry https://registry.npmmirror.com
# 无则执行命令安装
npm install -g @vue/cli
### 安装 Vue3/vite/typescript 项目模板
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project
### 直接访问官网提供的gitee地址下载
https://gitee.com/dcloud/uni-preset-vue/repository/archive/vite-ts.zip
### pmpm下载项目依赖
# powershell超级管理员运行
PS C:\WINDOWS\system32> set-ExecutionPolicy RemoteSigned(默认值为“N”): y
# 查看是否安装pnpm
pnpm -v
# 无则安装
npm install -g pnpm
# 设置淘宝镜像源
pnpm config set registry https://registry.npmmirror.com/
# 下载依赖
pnpm i
# 运行
pnpm dev:h5
目录结构
名称 | 描述 |
---|---|
node_modules 目录 | 放置项目的依赖文件 |
src 目录 | 放置开发的代码文件 |
pages 目录 | 放置页面文件 |
static 目录 | 放置静态文件 |
App.vue | 页面入口文件 |
env.d.ts | vue文件的类型说明文件 |
main.ts | 程序的入口文件,加载各种公共组件 |
manifest.json | 5+App拓展文件,打包app时要使用 |
pages.json | 全局配置文件,配置页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar等等 |
uni.scss | uniapp的默认css样式 |
.gitignore | git忽略文件 |
index.html | 项目总的入口文件 |
package.json | 项目依赖的描述文件 |
pnpm-lock.yaml | 锁定项目的依赖包版本 |
tsconfig.json | TS的语法识别和执行配置文件 |
vite.config.ts | 编译工具vite的配置文件 |
uni-app项目运行在微信小程序调试
uni-app框架的生命周期
生命周期函数
- 在项目运行过程中,各个阶段执行的回调函数成为生命周期钩子函数
- 在合适的时机做合适的任务,也就是对应的回调函数执行
- 在之前的vue项目中是vue实例的生命周期
- uni-app不止支持vue实例的生命周期,还新增了其他的生命周期
uni-app生命周期分类
- 应用生命周期
- 页面生命周期
- 组件生命周期
应用生命周期
- 官网文档地址
- 应用生命周期仅可在App.vue中监听,在页面监听无效
- App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素,也就是没有
页面生命周期
- 官网文档地址
- 支持vue标准的生命周期函数,同时新增了很多其他的生命周期函数
- 在page目录下配置的页面文件才能生效
- uni-app会将 pages.json ==> pages 配置项中的第一个页面,作为当前工程的首页(启动页)
组件生命周期
- 官网文档地址
- 与vue标准组件的生命周期函数相同
- 没有页面级新增的onLoad等生命周期函数
路由配置使用和页面跳转传参
组件式路由跳转传参
组件式路由跳转
<navigator url="/pages/about/index" open-type="navigate" hover-class="navigator-hover">
去个人中心
</navigator>
路由传参
### 传递参数
<navigator url="/pages/mine/index?title=小滴课堂" open-type="navigate" hover-class="navigator-hover">
去个人中心
</navigator>
### 接受参数
onLoad((option)=>{
console.log(option?.title)
})
函数式路由跳转传参
函数式路由跳转
自动补全的插件:uni-app-snippets
uni.navigateTo({
url: '/pages/index/index'
})
路由传参
### 传递参数
uni.navigateTo({
url: '/pages/index/index?title=xdclass.net'
})
### 接受参数
onLoad((option)=>{
console.log(option?.title)
})
传参的问题
- url值有长度限制,太长的字符串会传递失败
- 解决
- 通过uniapp的全局自定义事件
- 通过全局状态管理库处理
- pinia
- vuex
不同路由跳转配置的使用
pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。
它类似微信小程序中app.json的页面管理部分。注意定位权限申请等原属于app.json的内容,在uni-app中是在manifest中配置。
属性 | 类型 | 必填 | 描述 | 平台兼容 |
---|---|---|---|---|
globalStyle | Object | 否 | 设置默认页面的窗口表现 | |
pages | Object Array | 是 | 设置页面路径及窗口表现 | |
easycom | Object | 否 | 组件自动引入规则 | 2.5.5+ |
tabBar | Object | 否 | 设置底部 tab 的表现 | |
condition | Object | 否 | 启动模式配置 | |
subPackages | Object Array | 否 | 分包加载配置 | H5 不支持 |
preloadRule | Object | 否 | 分包预下载规则 | 微信小程序 |
workers | String | 否 | Worker 代码放置的目录 | 微信小程序 |
leftWindow | Object | 否 | 大屏左侧窗口 | H5 |
topWindow | Object | 否 | 大屏顶部窗口 | H5 |
rightWindow | Object | 否 | 大屏右侧窗口 | H5 |
uniIdRouter | Object | 否 | 自动跳转相关配置,新增于HBuilderX 3.5.0 | |
entryPagePath | String | 否 | 默认启动首页,新增于HBuilderX 3.7.0 | 微信小程序、支付宝小程序 |
配置2个一级导航页面(tabBar)
- pages目录新建vue文件
- pages.json配置tabBar
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"text": "首页"
},
{
"pagePath": "pages/mine/index",
"text": "我的"
}
]
}
路由配置分类
跳转方法 | 说明 |
---|---|
uni.navigateTo() | 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack 可以返回到原页面 |
uni.redirectTo() | 关闭当前页面,跳转到应用内的某个页面 |
uni.reLaunch() | 关闭所有页面,打开到应用内的某个页面 |
uni.switchTab() | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
uni.navigateBack() | 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层 |
navigateTo
,redirectTo
只能打开非 tabBar 页面。switchTab
只能打开tabBar
页面。reLaunch
可以打开任意页面- 字节跳动小程序与飞书小程序不支持
总结
- 一般进行页面的跳转使用uni.navigateTo
- tabbar页面的跳转使用uni.switchTab或者uni.reLaunch
<view @click="toMinePage">去我的页面</view>
<view @click="toTabbarPage">去tabBar页面</view>
<view @click="toAllPage">reLaunch可以去任意类型的页面
<view @click="back">返回</view>
const toMinePage = () => {
uni.navigateTo({url: '/pages/common/index'})
}
const toTabbarPage = () => {
uni.switchTab({url: '/pages/mine/index'})
}
const toAllPage = () => {
uni.reLaunch({url: '/pages/mine/index'})
}
const back = () => { //返回上上级页面
uni.navigateBack({ delta: 2 })
}
详解uni.navigateTo()
参数 | 说明 |
---|---|
url | 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2',path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数 |
animationType | 窗口显示的动画效果,详见:窗口动画 |
animationDuration | 窗口动画持续时间,单位为 ms |
events | 页面间通信接口,用于监听被打开页面发送到当前页面的数据。2.8.9+ 开始支持。 |
success | 接口调用成功的回调函数 |
fail | 接口调用失败的回调函数 |
complete | 接口调用结束的回调函数(调用成功、失败都会执行) |
### 首页
const toMinePage = () => {
uni.navigateTo({
url: '/pages/common/index',
animationType: 'pop-in',
animationDuration: 300,
events: {
//为指定时间添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function (data: string) {
console.log(data)
}
},
success: function (res){
// 通过evenChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', {data : '路由成功success回调函数传入的数据'})
}
})
}
### common页面
import { onLoad } from '@dcloudio/uni-app'
import { getCurrentInstance } from 'vue'
onLoad(() => {
const instance = getCurrentInstance()?.proxy
// @ts-expect-error-error
const eventChannel = instance.getOpenerEventChannel()
eventChannel.emit('acceptDataFromOpenedPage', { data: '从about页面传回的数据'})
eventChannel.on('acceptDataFromOpenerPage', function (data: any){
console.log(data)
})
})
getCurrentPages() 使用
获取当前的页面栈,以数组形式按栈的顺序给出,第一个元素为起首页,最后一个元素为当前页面 。
# 获取当前页面栈信息
onLoad(() => {
const pages = getCurrentPages()
// @ts-expect-error-error
console.log(pages[pages.length - 1].$page);
})
# 获取起始页栈信息
onLoad(() => {
const pages = getCurrentPages()
// @ts-expect-error-error
console.log(pages[0].$page);
})
# 当前页栈信息
{
"id": 5,
"path": "/pages/common/index",
"route": "pages/common/index",
"fullPath": "/pages/common/index",
"options": {},
"meta": {
"id": 5,
"backgroundColor": "#F8F8F8",
"navigationBar": {
"backgroundColor": "#F8F8F8",
"titleText": "普通页面",
"type": "default",
"titleColor": "#000000",
"titleSize": "16px"
},
"isNVue": false,
"route": "pages/common/index",
"pullToRefresh": {}
},
"openType": "navigateTo",
"statusBarStyle": "dark"
}
# 起始页栈信息
{
"id": 4,
"path": "/pages/index/index",
"route": "pages/index/index",
"fullPath": "/pages/index/index",
"options": {},
"meta": {
"id": 4,
"backgroundColor": "#F8F8F8",
"navigationBar": {
"backgroundColor": "#F8F8F8",
"titleText": "首页",
"type": "default",
"titleColor": "#000000",
"titleSize": "16px"
},
"isNVue": false,
"isQuit": true,
"isEntry": true,
"isTabBar": true,
"tabBarIndex": 0,
"route": "pages/index/index",
"pullToRefresh": {}
},
"openType": "navigateTo",
"statusBarStyle": "dark"
}
uniapp常用的组件使用
名称 | 描述 |
---|---|
view | 它类似于传统html中的div,用于包裹各种元素内容 |
scroll-view | 可滚动视图区域,用于区域滚动 |
swiper | 滑块视图容器,banner轮播图 |
match-media | 适配不同屏幕的基本视图组件 |
movable-area | 可拖动区域 |
movable-view | 可移动的视图容器,在页面中可以拖拽滑动或双指缩放 |
名称 | 描述 |
---|---|
icon | 图标 |
text | 文本组件,用于包裹文本内容;组件内只支持嵌套 |
progress | 进度条 |
表单组件(Form)
标签名 | 说明 |
---|---|
button | 按钮 |
checkbox | 多项选择器 |
editor | 富文本输入框 |
form | 表单 |
input | 输入框 |
label | 标签 |
picker | 弹出式列表选择器 |
picker-view | 窗体内嵌式列表选择器 |
radio | 单项选择器 |
slider | 滑动选择器 |
switch | 开关选择器 |
textarea | 多行文本输入框 |
媒体组件(Media)
组件名 | 说明 |
---|---|
audio | 音频 |
camera | 相机 |
image | 图片 |
video | 视频 |
live-player | 直播播放 |
live-pusher | 实时音视频录制,也称直播推流 |
uniapp常用的API使用
发起网络请求uni.request
在各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。
onLoad(() => {
//uni.request
uni.request({ url: 'https://api-v2.xdclass.net/api/card/v1/list'}).then((res) => {
console.log(res)
})
})
OBJECT 参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
url | String | 是 | 开发者服务器接口地址 | ||
data | Object/String/ArrayBuffer | 否 | 请求的参数 | App 3.3.7 以下不支持 ArrayBuffer 类型 | |
header | Object | 否 | 设置请求的 header,header 中不能设置 Referer | App、H5端会自动带上cookie,且H5端不可手动修改 | |
method | String | 否 | GET | 有效值详见下方说明 | |
timeout | Number | 否 | 60000 | 超时时间,单位 ms | H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序 |
dataType | String | 否 | json | 如果设为 json,会对返回的数据进行一次 JSON.parse,非 json 不会进行 JSON.parse | |
responseType | String | 否 | text | 设置响应的数据类型。合法值:text、arraybuffer | 支付宝小程序不支持 |
sslVerify | Boolean | 否 | true | 验证 ssl 证书 | 仅App安卓端支持(HBuilderX 2.3.3+),不支持离线打包 |
withCredentials | Boolean | 否 | false | 跨域请求时是否携带凭证(cookies) | 仅H5支持(HBuilderX 2.6.15+) |
firstIpv4 | Boolean | 否 | false | DNS解析时优先使用ipv4 | 仅 App-Android 支持 (HBuilderX 2.8.0+) |
enableHttp2 | Boolean | 否 | false | 开启 http2 | 微信小程序 |
enableQuic | Boolean | 否 | false | 开启 quic | 微信小程序 |
enableCache | Boolean | 否 | false | 开启 cache | 微信小程序、抖音小程序 2.31.0+ |
enableHttpDNS | Boolean | 否 | false | 是否开启 HttpDNS 服务。如开启,需要同时填入 httpDNSServiceId 。 HttpDNS 用法详见 移动解析HttpDNS | 微信小程序 |
httpDNSServiceId | String | 否 | HttpDNS 服务商 Id。 HttpDNS 用法详见 移动解析HttpDNS | 微信小程序 | |
enableChunked | Boolean | 否 | false | 开启 transfer-encoding chunked | 微信小程序 |
forceCellularNetwork | Boolean | 否 | false | wifi下使用移动网络发送请求 | 微信小程序 |
enableCookie | Boolean | 否 | false | 开启后可在headers中编辑cookie | 支付宝小程序 10.2.33+ |
cloudCache | Object/Boolean | 否 | false | 是否开启云加速(详见云加速服务) | 百度小程序 3.310.11+ |
defer | Boolean | 否 | false | 控制当前请求是否延时至首屏内容渲染后发送 | 百度小程序 3.310.11+ |
success | Function | 否 | 收到开发者服务器成功返回的回调函数 | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
数据缓存 uni.setStorage
onLoad(() => {
//setStorageSync
uni.setStorageSync('token', 'soulboy')
console.log(uni.getStorageSync('token'))
uni.clearStorageSync()
setTimeout(() => {
uni.removeStorageSync('token')
},5000)
})
异步方法 | 同步方法 | |
---|---|---|
设置 | uni.setStorage | uni.setStorageSync |
获取 | uni.getStorage | uni.getStorageSync |
删除指定key | uni.removeStorage | uni.removeStorageSync |
清理缓存 | uni.clearStorage | uni.clearStorageSync |
界面API
API | 功能描述 |
---|---|
uni.showToast | 显示消息提示框 |
uni.setNavigationBarTitle | 动态设置当前页面的标题 |
uni.setTabBarItem | 动态设置 tabBar某一项的内容 |
uni.pageScrollTo | 将页面滚动到目标位置 |
uni.onWindowResize | 监听窗口尺寸变化事件 |
第三方API
API | 功能描述 |
---|---|
uni.login | 显示消息提示框 |
uni.requestPayment | 统一各平台的客户端支付API,不管是在某家小程序还是在App中,客户端均使用本API调用支付 |
项目初始化
### 初始化代码
# 安装 Vue3/vite/typescript 项目模板
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project
# 也可以直接访问官网提供的gitee地址下载
https://gitee.com/dcloud/uni-preset-vue/repository/archive/vite-ts.zip
### Gitee代码仓库管理
git init
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin https://gitee.com/wang-chao1990/uniapp-xdclass.git
git push -u origin "master"
git push -f origin "master"
### unocss配置
# unocss.config.ts
import presetWeapp from 'unocss-preset-weapp'
import { defineConfig } from 'unocss'
import { transformerAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
export default defineConfig({
presets: [
presetWeapp(), // 工具预设
],
transformers: [
transformerAttributify(), // 支持属性化模式
transformerClass(), // 转换转义类名,支持class写法
],
shortcuts: [
{ center: 'flex items-center justify-center' },
{ around: 'flex items-center justify-around' },
{ between: 'flex items-center justify-between' },
]
})
# main.ts
import 'uno.css'
# vite.config.ts
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
import Unocss from 'unocss/vite'
export default defineConfig({
plugins: [uni(),Unocss()],
});
# 安装插件
PS D:\Project\my-vue3-project> pnpm i unocss-preset-weapp unocss
### 响应式语法糖和自动引入插件配置
# 下载插件
pnpm i unplugin-auto-import
# vite.config.ts
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
import Unocss from 'unocss/vite'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
uni({
vueOptions: {
reactivityTransform: true
}
}),
Unocss(),
AutoImport({
dts: 'src/typings/auto-imports.d.ts',
imports: ['vue', 'uni-app', 'pinia'],
dirs: ['src/composables']
}),
],
});
### Pinia状态管理的配置
# 安装插件
pnpm i pinia@2.0.30 pinia-plugin-persistedstate@3.0.2 -S
# 引入Pinia // main.ts
import { createSSRApp } from "vue";
import App from "./App.vue";
import { createPinia } from 'pinia';
import { createPersistedState } from 'pinia-plugin-persistedstate';
import 'uno.css'
# 测试Pinia配置成功与否 引入Pinia和持久缓存的设置
const pinia = createPinia().use(
createPersistedState({
storage: {
getItem(key: string) {
return uni.getStorageSync(key);
},
setItem(key: string, value: string) {
uni.setStorageSync(key, value);
},
},
})
);
export function createApp() {
const app = createSSRApp(App).use(pinia);
return {
app,
};
}
# index.vue页面中进行测试
const { isLogin} = $(useUser())
console.log('isLogin:',isLogin)