目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

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插件安装

image.png

通过uni-app框架创建项目

HBuilderX可视化方式(只能在XBuild中运行)

HBuilderX工具下载 https://www.dcloud.io/hbuilderx.html

image.png

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

image.png

目录结构

名称描述
node_modules 目录放置项目的依赖文件
src 目录放置开发的代码文件
pages 目录放置页面文件
static 目录放置静态文件
App.vue页面入口文件
env.d.tsvue文件的类型说明文件
main.ts程序的入口文件,加载各种公共组件
manifest.json5+App拓展文件,打包app时要使用
pages.json全局配置文件,配置页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar等等
uni.scssuniapp的默认css样式
.gitignoregit忽略文件
index.html项目总的入口文件
package.json项目依赖的描述文件
pnpm-lock.yaml锁定项目的依赖包版本
tsconfig.jsonTS的语法识别和执行配置文件
vite.config.ts编译工具vite的配置文件

uni-app项目运行在微信小程序调试

image.png
image.png

uni-app框架的生命周期

image.png

生命周期函数

  • 在项目运行过程中,各个阶段执行的回调函数成为生命周期钩子函数
  • 在合适的时机做合适的任务,也就是对应的回调函数执行
  • 在之前的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中配置。

配置项列表

属性类型必填描述平台兼容
globalStyleObject设置默认页面的窗口表现
pagesObject Array设置页面路径及窗口表现
easycomObject组件自动引入规则2.5.5+
tabBarObject设置底部 tab 的表现
conditionObject启动模式配置
subPackagesObject Array分包加载配置H5 不支持
preloadRuleObject分包预下载规则微信小程序
workersStringWorker 代码放置的目录微信小程序
leftWindowObject大屏左侧窗口H5
topWindowObject大屏顶部窗口H5
rightWindowObject大屏右侧窗口H5
uniIdRouterObject自动跳转相关配置,新增于HBuilderX 3.5.0
entryPagePathString默认启动首页,新增于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)
    })
})

image.png

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 参数说明

参数名类型必填默认值说明平台差异说明
urlString 开发者服务器接口地址
dataObject/String/ArrayBuffer 请求的参数App 3.3.7 以下不支持 ArrayBuffer 类型
headerObject 设置请求的 header,header 中不能设置 RefererApp、H5端会自动带上cookie,且H5端不可手动修改
methodStringGET有效值详见下方说明
timeoutNumber60000超时时间,单位 msH5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
dataTypeStringjson如果设为 json,会对返回的数据进行一次 JSON.parse,非 json 不会进行 JSON.parse
responseTypeStringtext设置响应的数据类型。合法值:text、arraybuffer支付宝小程序不支持
sslVerifyBooleantrue验证 ssl 证书仅App安卓端支持(HBuilderX 2.3.3+),不支持离线打包
withCredentialsBooleanfalse跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
firstIpv4BooleanfalseDNS解析时优先使用ipv4仅 App-Android 支持 (HBuilderX 2.8.0+)
enableHttp2Booleanfalse开启 http2微信小程序
enableQuicBooleanfalse开启 quic微信小程序
enableCacheBooleanfalse开启 cache微信小程序、抖音小程序 2.31.0+
enableHttpDNSBooleanfalse是否开启 HttpDNS 服务。如开启,需要同时填入 httpDNSServiceId 。 HttpDNS 用法详见 移动解析HttpDNS微信小程序
httpDNSServiceIdString HttpDNS 服务商 Id。 HttpDNS 用法详见 移动解析HttpDNS微信小程序
enableChunkedBooleanfalse开启 transfer-encoding chunked微信小程序
forceCellularNetworkBooleanfalsewifi下使用移动网络发送请求微信小程序
enableCookieBooleanfalse开启后可在headers中编辑cookie支付宝小程序 10.2.33+
cloudCacheObject/Booleanfalse是否开启云加速(详见云加速服务百度小程序 3.310.11+
deferBooleanfalse控制当前请求是否延时至首屏内容渲染后发送百度小程序 3.310.11+
successFunction 收到开发者服务器成功返回的回调函数
failFunction 接口调用失败的回调函数
completeFunction 接口调用结束的回调函数(调用成功、失败都会执行)

数据缓存 uni.setStorage

onLoad(() => {
    //setStorageSync
    uni.setStorageSync('token', 'soulboy')
    console.log(uni.getStorageSync('token'))
    uni.clearStorageSync()
    setTimeout(() => {
        uni.removeStorageSync('token')
    },5000)
})
异步方法同步方法
设置uni.setStorageuni.setStorageSync
获取uni.getStorageuni.getStorageSync
删除指定keyuni.removeStorageuni.removeStorageSync
清理缓存uni.clearStorageuni.clearStorageSync

界面API

API功能描述
uni.showToast显示消息提示框
uni.setNavigationBarTitle动态设置当前页面的标题
uni.setTabBarItem动态设置 tabBar某一项的内容
uni.pageScrollTo将页面滚动到目标位置
uni.onWindowResize监听窗口尺寸变化事件

第三方API

API功能描述
uni.login显示消息提示框
uni.requestPayment统一各平台的客户端支付API,不管是在某家小程序还是在App中,客户端均使用本API调用支付

项目初始化

image.png

### 初始化代码
# 安装 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)

作者:Soulboy