一、概念

1. 原生 VS 跨平台

原生开发

优点

性能稳定,使用流畅,用户体验好、功能齐全,安全性有保证,兼容性好,可使用手机所有硬件功能等

缺点

开发周期长、维护成本高、迭代慢、部署慢、新版本必须重新下载应用
不支持跨平台,必须同时开发多端代码

跨平台开发

优点

  • 可以跨平台,一套代码搞定iOS、Android、微信小程序、H5应用等

  • 开发成本较低,开发周期比原生短

  • 适用于跟系统交互少、页面不太复杂的场景

缺点

  • 对开发者要求高,除了本身JS的了解,还必须熟悉一点原生开发

  • 不适合做高性能、复杂用户体验,以及定制高的应用程序。比如:抖音、微信、QQ等

  • 同时开发多端兼容和适配比较麻烦、调试起来不方便

2. 跨平台框架对比

3. 认识uni-app

4. uni-app VS 微信小程序

相同点

  • 都是接近原生的体验、打开即用、不需要安装

  • 都可开发微信小程序、都有非常完善的官方文档

不同点

  • 跨平台

  • uni-app : 支持跨平台,编写一套代码,可以发布到多个平台

  • 微信小程序 : 不支持

  • 工程化

  • uni-app : 纯Vue体验、高效、统一、工程化强

  • 微信小程序 : 工程化弱、使用小程序开发语言

  • 复杂程度

  • uni-app : 适合不太复杂的应用,因为需要兼容多端,多端一起兼容和适配增加了开发者心智负担

  • 微信小程序 : 适合较复杂、定制性较高、兼容和稳定性更好的应用

如何选择

需要跨平台、不太复杂的应用选 uni-app,复杂的应用使用uni-app反而增加了难度。
不需要跨平台、较复杂、对兼容和稳定性要求高的选原生微信小程序

5. uni-app架构图

二、uni-app初体验

1. 开发工具

Hbuilder X : 是通用的前端开发工具,但为 uni-app 做了特别强化
网址 : hbuilderx

ps : 用Vue3的Composition API 建议用 HBuilder X最新Alpha版,旧版有兼容问题

2. 创建项目

可视化界面创建 ( 推荐 )

  • 点工具栏里的文件 -> 新建 -> 项目 ( 快捷键Ctrl+N )

  • 选择uni-app类型,输入工程名,选择模板,选择Vue版本,点击创建即可

Vue-CLI 命令行创建

3. 运行uni-app

在 浏览器 运行

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

在 微信开发者工具 运行

如果自动启动失败,可用微信开发者工具手动打开项目
项目在unpackage/dist/dev/mp-weixin路径下

01 - 开启服务端口

微信开发者工具需要开启服务端口:
小程序开发工具设置 -> 安全(目的是让HBuilder可以启动微信开发者工具)

02 - 运行

在 手机或模拟器 运行

这里是mac电脑 + ios手机环境

ps : 之所以要用XCode新建一个项目,先打开模拟器,再用hbuilderx打开相同的模拟器
是为了减少bug,不这么做容易有奇奇怪怪的小问题

XCode 设置

01 - 安装XCode
02 - 新建Xcode项⽬
03 - 选择项⽬类型
04 - 填写项⽬信息
05 - 选择路径
06 - 启动Xcode项⽬生成一个IOS模拟器
07 - 运⾏Xcode项⽬的效果

Hbuilderx-Alpha 设置

01 - 安装手机模拟器插件
02 - 配置adb路径(可跳过)

可不配 : 不配会自动去寻找默认的

  • HBuilderX正式版adb目录位置 :

  • windows : 安装路径下的 tools/adbs 目录

  • mac : HBuilderX.app/Contents/tools/adbs目录;

  • HBuilderX Alpha版的adb目录位置:

  • windows : 安装路径下的 plugins/launcher/tools/adbs 目录

  • mac下 : /Applications/HBuilderX-Alpha.app/Contents/HBuilderX/plugins/launcher/tools/adbs目录

  • 在adbs目录下运行./adb ,即可使用adb命令(Win和Mac一样)

03 - 选择模拟器
04 - 选择模拟器
05 - 效果

有个很严重的问题,我的这样没有热更新,每次改完得重新运行,我要崩溃,有没有大佬指点迷津

ios模拟器问题 : 未修复

三、uni-app的架构和配置

1. 目录结构

2. 开发规范

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

  • 页面文件遵循

  • Vue 单文件组件 (SFC) 规范

  • 组件标签靠近小程序规范

  • uni-app 组件规范 => 使用小程序的标签

  • 接口能力(JS API)

  • 靠近微信小程序规范 => 但需将前缀 wx 替换为 uni

  • uni-app接口规范

  • 数据绑定及事件处理

  • 同 Vue.js 规范 => 例如使用@click

  • 生命周期

  • 可用小程序的

  • 也可用vue的

  • 为兼容多端运行

  • 建议使用flex布局

  • 推荐使用rpx单位

  • uni-app的官网文档

  • uni-app官网文档

3. main.js

main.js是 uni-app 的入口文件,主要作用是:

  • 初始化vue实例

  • 定义全局组件

  • 定义全局属性

  • 安装插件,如:pinia、vuex 等

01 - 初始化vue实例

02 - 定义全局组件

import { createSSRApp } from 'vue'//引入组件
import myComponent from './components/my-component/my-component.vue'export function createApp() {const app = createSSRApp(App) //调用app.component方法全局注册组件app.component('my-component', myComponent)return {app}
}

03 - 定义全局属性

// vue2
Vue.prototype.$http = () => {}// vue3
export function createApp() {const app = createSSRApp(App);app.config.globalProperties.$http = () => {}return {app}
}

04 - 安装插件,如:pinia、vuex 等

import { createSSRApp } from 'vue'
// 当然这里要自己先封一下 Pinia
import pinia from '.stores'
export function createApp() {const app = createSSRApp(App);app.use(pinia);return {appPinia // 此处必须将 Pinia 返回}
}

4. App.vue

App.vue : 入口组件

  • App.vue是uni-app的入口组件,所有页面都是在App.vue下进行切换

  • App.vue本身不是页面,这里不能编写视图元素,也就是没有<template>元素

App.vue的作用是 :

  • 应用的生命周期

  • 编写全局样式

  • 定义全局数据 globalData

01 - 应用生命周期

注意:应用生命的周期仅可在App.vue中监听,在页面监听无效。

<script>export default {/** App应用的生命周期*/onLaunch: function(option) {// 可以获取到小程序设置的启动参数console.log('App Launch')},onShow: function() {console.log('App Show')},onHide: function() {console.log('App Hide')}}
</script><style >
/*每个页面公共css */
</style>

02 - 编写全局样式

全局样式 : App.vue 中style的样式,作用于每一个页面(style标签不支持scoped)
App.vue 中通过 @import 语句可以导入外联样式,一样作用于每一个页面

局部样式 : 在 pages 目录下 的 vue 文件的style中的样式为局部样式,只作用对应的页面,并会覆盖 App.vue 中相同的选择器
style标签不支持scoped,默认就是局部样式

<script>
export default {onLaunch: function() {},onShow: function() {},onHide: function() {}
}
</script>
<!-- 这里不支持写scoped属性 -->
<style lang='scss'>/*每个页面公共css *//* 这个文件中定义的变量 */@import '@/static/css/init.scss';@import '@/static/css/base.css';.title{color: red;/* 这里可以使用变量,但是其他页面无法使用,若想使用,那个页面也得导入scss文件 */border: 2rpx solid $mainColor;}
</style>

03 - 定义全局数据 globalData

<script>export default {// 定义全局变量globalData: {text: 'text'},onLaunch: function() {// getApp对象还未获取,暂时可以使用this.globalData获取globalDataconsole.log('App Launch', this.globalData) // App Launch {text: 'text'}},onShow: function() {// 可通过 getApp().globalData.*    来操作,其他页面也是这样调用console.log('App Show', getApp().globalData) // App Show {text: 'text'}},onHide: function() {console.log('App Hide')}}
</script>// 页面使用
onShow() {// getApp() => 全部页面自带,都可以使用console.log('page', getApp().globalData);
}

5. uni.scss

uni.scss 全局样式文件

  • 为了方便整体控制应用风格,默认定义了uni-app框架内置全局变量,也可以存放自定义的全局变量等

  • 在uni.scss中定义的变量,无需 @import 就可以在任意组件中直接使用。

  • 使用uni.scss中的变量,需在 HBuilderX 里面安装 scss 插件(dart-sass插件),

  • 然后在该组件的 style 上加 lang=“scss”,重启即可生效

注意事项 :

  • 这里的uni-app框架内置变量和后面uni-ui组件库的内置变量是不一样的。

  • uni.scss定义的变量是全局可以直接使用,App.vue定义的变量只能在当前组件中使用

uni.scss的作用 :

  • 定义自定义的全局的样式变量

  • 重写uni-app内置的样式变量

  • 重写uni-un内置的样式变量

6. page.json

page.json : 全局页面配置(兼容h5、weapp、app )

  • pages.json 文件用来对 uni-app 进行全局配置,类似微信小程序中app.json

  • 决定页面的路径、窗口样式、原生的导航栏、底部的原生tabbar 等

{"pages": [// 页面窗口的配置,优先级比全局的要高// 首页{"path": "pages/index/index","style": {// 相当于配置页面样式"navigationBarTitleText": "空我,核弹踢!"}}],// 相当于整个小程序的顶部窗口"globalStyle": {// 导航栏标题的颜色 black/white"navigationBarTextStyle": "black",// 导航栏标题的文字,整体的,会被上面的单个页面配置的覆盖"navigationBarTitleText": "迪迦奥特曼,冲啊",// 顶部背景颜色"navigationBarBackgroundColor": "#ff8198",// 下拉刷新时可以看到的那个"backgroundColor": "#F8F8F8"}
}

7. manifest.json

manifest.json : 应用配置

  • Android平台相关配置

  • iOS平台相关配置

  • Web端相关的配置

  • 微信小程序相关配置

  • ......

四、uni-ui组件库

uni-ui是DCloud提供的一个UI组件库,一套基于Vue组件、flex布局的跨全端UI框架
uni-ui不包括uni-app框架提供的基础组件,而是基础组件的补充
网址 : uni-ui

1. 安装 uni-ui 组件库

方式一 : uni_modules按需安装

通过 uni_modules(插件模块化规范)单独安装组件

  • 1. 官网找到扩展组件清单,然后将所需要的组件导入到项目,导入后直接使用,无需import和注册

  • 2. 若想切换应用风格,可以在uni.scss导入uni-ui提供的内置scss变量,然后重启应用

  • ps :需要登录 DCloud 账号才能安装

方式二 : uni_modules全部安装

方式三 : 创建项目时安装

ps: 该方式使得全部组件都下载了

方式四 : npm 安装

2. 定制 uni-ui 主题风格

  • 安装dart-sass插件(一般都会提示,并自动安装)

  • 在项目根目录的uni.scss文件中引入uni-ui组件库的variable.scss变量文件

  • 然后就可以使用或修改对应的scss变量

  • 变量主要定义的是主题色

3. 组件样式穿透

// 小程序 和 app 有效果
.uni-forms-item_label{color:red !important;
}// 小程序 和 app 和 h5
:deep(.uni-forms-item_label){color:red !important;
}// 小程序 和 app 和 h5
:global(.uni-forms-item_label){color:red !important;
}

五、跨端兼容实现

uni-app能实现一套代码、多端运行,核心是通过编译器 + 运行时实现的:

  • 编译器:将uni-app统一代码编译生成每个平台支持的特有代码

  • 如在小程序平台,编译器将.vue文件拆分生成wxml、wxss、js等。

  • 运行时:动态处理数据绑定、事件代理,保证 Vue和对应宿主平台 数据的一致性

1. 存在的问题

跨平台存在的问题:

  • uni-app 已将常用的组件、JS API 封装到框架中,按照 uni-app 规范开发即可保证多平台兼容

  • 大部分业务均可直接满足。

  • 但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况

  • 大量写 if else,会造成代码执行性能低下和管理混乱

  • 编译到不同的工程后二次修改,会让后续升级变的很麻烦

跨平台兼容解决方案:

  • 在 C 语言中,通过 #ifdef、#ifndef 的方式,为 windows、mac 等不同 os 编译不同的代码

  • uni-app 参考这个思路,为 uni-app 提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现

2. 条件编译

01 - 具体语法

// #ifdef  %PLATFORM%
平台特有的API实现
// #endif

02 - 支持的文件

<template><view class="content">页面!!!!<!-- 只在h5中显示 --><!-- #ifdef H5 --><view><uni-badge text="1" type="primary"></uni-badge></view><!-- #endif --><!-- 在微信中 或 app中显示 --><!-- #ifdef MP-WEIXIN || APP-PLUS --><view class="img"></view><!-- #endif --></view>
</template><script>export default {data() {return {title: '1999888'}},onLoad() {// #ifdef H5document.title = 'h5 !!!!!!!'// 可以在这里操作dom// #endif// #ifdef MP-WEIXIN// pages.json中设定的优先级比较高wx.setNavigationBarTitle({title: 'WXapp'})// #endif// #ifdef APP-PLUS// 这个是跨端的uni.setNavigationBarTitle({title: 'APP'})// #endif},onShow() {console.log('page', getApp().globalData);},}
</script><style lang="scss">/* #ifdef H5 */.uni-badge--x {background-color: blue;}/* #endif *//* #ifdef APP-PLUS || MP-WEIXIN */.img {height: 200rpx;background: url("~@/static/abc/logo.png") no-repeat;background-size: contain;}/* #endif */
</style>

03 - 注意事项

Android 和 iOS 平台不支持条件编译
如需区分 Android、iOS 平台,请通过调用 uni.getSystemInfo 来获取平台信息

六、页面 - Page

1. 新建页面

01 - 新建页面

可直接新建页面,不用新建目录,会带同名目录

02 - 在pages.json中配置

一般会自动生成,如果没有,手写即可

03 - 配置tabBar

2. 页面路由

uni-app 有两种页面路由跳转方式:和小程序一模一样
使用navigator组件跳转
调用API跳转(类似小程序,与vue-router不同)

API跳转

跳转到 TabBar 页面

uni.switchTab

跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面

<template><view class="content"><button type="primary" @click="jumpFn">switchTab</button></view>
</template><script>export default {methods: {jumpFn() {uni.switchTab({// 需要跳转的 tabBar 页面的路径(需在 pages.json 的 tabBar 字段定义的页面),路径后不能带参数url: '/pages/about/about',success: (res) => {console.log('success', res); // success {errMsg: 'switchTab:ok'}},fail: (err) => {console.log('fail', err);},complete: (res) => {console.log('complete', res); // complete {errMsg: 'switchTab:ok'}}})}}}
</script>

跳转到 普通 页面

uni.navigateTo

保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面

<template><view class="content"><button type="primary" @click="jumpFn">navigateTo</button></view>
</template><script>export default {methods: {jumpFn() {uni.navigateTo({// 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数url: '/pages/detail/detail?name=coder&age=18',// 仅支持在app端看到运动 效果animationType: 'fade-in',animationDuration: 2000,success: (res) => {console.log('success:', res);},fail: (err) => {console.log('fail:', err);},complete: (res) => {console.log('complete:', res);},})}}}</script>
uni.navigateBack

关闭当前页面,返回上一页面或多级页面
可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层

// 此处是A页面
uni.navigateTo({url: 'B?id=1'
});// 此处是B页面
uni.navigateTo({url: 'C?id=1'
});// 在C页面内 navigateBack,将返回A页面
uni.navigateBack({delta: 2,success: (res) => {console.log('success:', res);},fail: (err) => {console.log('fail:', err);},complete: (res) => {console.log('complete:', res);},
});
uni.redirectTo

关闭当前页面,跳转到应用内的某个页面

uni.redirectTo({url:'test?id=1',success: (res) => {console.log('success:', res);},fail: (err) => {console.log('fail:', err);},complete: (res) => {console.log('complete:', res);},
});
uni.reLaunch

关闭所有页面,打开到应用内的某个页面

uni.reLaunch({url:'test?id=1',success: (res) => {console.log('success:', res);},fail: (err) => {console.log('fail:', err);},complete: (res) => {console.log('complete:', res);},
});

Navigator跳转

跳转到 tabBar 页面

open-type="switchTab" 对应 uni.switchTab 的功能

<navigator open-type="switchTab" url="../profy/profy">跳转到个人</navigator>

跳转到 普通 页面

路由跳转中相互传值

若有特殊字符
传递时 : encodeURIComponent 编码
接受时 : decodeURIComponent 解码

url查询字符 和 直接修改值

首页 => 详情页
jumpFn() {uni.navigateTo({// 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数url: '/pages/detail/detail?name=coder&age=18',// 仅支持在app端看到运动 效果animationType: 'fade-in',animationDuration: 2000,success: (res) => {console.log('success:', res);},fail: (err) => {console.log('fail:', err);},complete: (res) => {console.log('complete:', res);},})
}
详情页 => 首页
export default {// 可在这获取到首页传递过来的值onLoad(option) {console.log(option); // {name: 'coder', age: '18'}},/*** 写在这里的理由 : 用户可能点击顶部状态栏中的返回键,写在这不管怎么返回,都会触发*/// 页面被注销时调用onUnload() {// 1. 获取到已经存在的所有页面const pages = getCurrentPages()// 2. 拿到上一个页面的实例  当前页面为最后一个,所以上一个页面是减2const prePage = pages[pages.length - 2]/*** 3. 设置值*/// H5端// #ifdef H5 prePage.arr[1].name = 'ccc'// #endif// 微信端,有个$vm// #ifdef MP-WEIXIN prePage.$vm.arr[1].name = 'ccc'// #endif// app端,上述两种都可满足,奇怪// #ifdef APP-PLUS// prePage.arr[1].name = 'ccc'prePage.$vm.arr[1].name = 'ccc'// #endif}
}

url查询字符 和 EventChannel修改

只有 uni.navigateTo 才能使用这个哦

首页 => 详情页
jumpFn() {uni.navigateTo({// 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数,如果有特殊字符记得编码url: `/pages/detail/detail?name=${encodeURIComponent('coder')}&age=18`,events: {// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据acceptDataFromOpenedPage: (data) => {console.log('acceptDataFromOpenedPage',data) // acceptDataFromOpenedPage {name: 'coder'}},someEvent: (data) => {console.log('someEvent', data) // someEvent {age: 10}}},success: (res) => {console.log('success:', res);// 通过eventChannel向被打开页面传送数据,用此方式可不用在url上拼接参数res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'data from starter page' })},fail: (err) => {console.log('fail:', err);},complete: (res) => {console.log('complete:', res);},})
}
详情页 => 首页
export default {// 可在这获取到首页传递过来的值onLoad(option) {console.log(option, decodeURIComponent(option.name)); // {name: 'coder', age: '18'}},/*** 写在这里的理由 : 用户可能点击顶部状态栏中的返回键,写在这不管怎么返回,都会触发*/// 页面被注销时调用onUnload() {// 1. 拿到eventChanner渠道const eventChanner = this.getOpenerEventChannel()// 2. 通过渠道,传递数据给上一个页面eventChanner.emit('acceptDataFromOpenedPage', {name: 'coder'})eventChanner.emit('someEvent', {age: 10})// 3. 监听上一个页面传递过来的数据eventChanner.on('acceptDataFromOpenerPage', function(data) {console.log(data) // {data: 'data from starter page'}})}
}

vue3写法

首页 => 详情页
<template><view class="content"><button type="primary" @click="jumpFn">navigateTo</button></view>
</template><script setup>import { ref } from 'vue'const arr = ref([{name: 'coder',age: 12},{name: 'star',age: 18},])const age = ref(-1)const jumpFn = () => {uni.navigateTo({// 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数,如果有特殊字符记得编码url: `/pages/detail/detail?name=${encodeURIComponent('coder——饿$12${}')}&age=18`,events: {// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据acceptDataFromOpenedPage: (data) => {console.log('acceptDataFromOpenedPage',data) // acceptDataFromOpenedPage {name: 'coder'}},someEvent: (data) => {console.log('someEvent', data) // someEvent {age: 10}age.value = data.age}},success: (res) => {console.log('success:', res);},fail: (err) => {console.log('fail:', err);},complete: (res) => {console.log('complete:', res);},})}
</script>
详情页 => 首页
<template><view>detail-view</view>
</template><script setup>import { ref, getCurrentInstance } from 'vue'import { onLoad, onUnload } from "@dcloudio/uni-app";// 方式二 : 也可在defineProps中拿到传递过来的值const props = defaineProps({name: String,age: Number})console.log(option.name,option.age)// 方式一 : 可在这获取到首页传递过来的值onLoad((option) => {console.log(option, decodeURIComponent(option.name)); // {name: 'coder', age: '18'}})// 拿到当前实例,可以理解为thisconst instance = ref(getCurrentInstance().proxy)/*** 写在这里的理由 : 用户可能点击顶部状态栏中的返回键,写在这不管怎么返回,都会触发*/// 页面被注销时调用onUnload(() => {// 1. 拿到eventChanner渠道const eventChanner = instance.value.getOpenerEventChannel()// const eventChanner = getCurrentInstance().proxy.getOpenerEventChannel()// 2. 通过渠道,拿到回调函数,并且传递数据给上一个页面eventChanner.emit('acceptDataFromOpenedPage', {name: 'coder'})eventChanner.emit('someEvent', {age: 10})})
</script>

3. 事件总线

01 - 注意事项

  • 需先监听,再触发事件,比如:你在A界面触发,然后跳转到B页面后才监听是不行的

  • 通常on 和 off 是同时使用,可以避免多次重复监听

  • 适合页面返回传递参数、适合跨组件通讯,不适合界面跳转传递参数

02 - 页面通讯

uni.$emit

触发全局的自定义事件,附加参数都会传给监听器回调

uni.$emit('emitFn',{msg:'页面更新'})

uni.$on

监听全局的自定义事件
事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数

uni.$on('emitFn',(data) => {console.log('监听到事件来自 emitFn ,携带参数 msg 为:' + data.msg);
})

uni.$once

监听全局的自定义事件
事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器

uni.$once('emitFn',(data) => {console.log('监听到事件来自 emitFn ,携带参数 msg 为:' + data.msg);
})

uni.$off

移除全局自定义事件监听器

// 注 : 这样并不能清除监听过的emitFn
uni.$off('emitFn',(data) => {console.log('监听到事件来自 emitFn ,携带参数 msg 为:' + data.msg);
})

03 - 代码示例

需先监听,再触发事件,比如:你在A界面触发,然后跳转到B页面后才监听是不行的
A监听,B发射,A再监听才能拿到值

A组件监听

<template><view class="content"><button type="primary" @click="jumpFn">navigateTo</button></view>
</template><script setup>import { onLoad, onUnload } from "@dcloudio/uni-app";// 跳转到详情页const jumpFn = () => {uni.navigateTo({url: `/pages/detail/detail`,})}const emitFn = (res) => {console.log('emitFn', res);}onLoad(() => {// 监听uni.$on('emitFn', emitFn)})onUnload(() => {// 移除uni.$off('emitFn', emitFn)})
</script>

B组件发射

<template><view>detail-view</view>
</template><script setup>import { onUnload } from "@dcloudio/uni-app";onUnload(() => {uni.$emit('emitFn', {msg: '冲啊,迪迦奥特曼!!!'})})
</script>

4. 生命周期

tabBar的页面不会销毁,不会触发onUnload

Options API

export default {/*** 都会触发* */// 1.页面的生命周期onLoad(options) {console.log('onLoad');},onShow() {console.log('onShow');console.log(this);},onReady() {console.log('onReady');},onHide() {console.log('onHide');},onUnload() {console.log('onUnload');},onPullDownRefresh() {console.log('onPullDownRefresh');setTimeout(() => {uni.stopPullDownRefresh()}, 1000)},onReachBottom() {console.log('onReachBottom');},// 2.Vue组件的生命周期beforeCreate() {console.log('beforeCreate');},created() {console.log('created');},beforeMount() {console.log('beforeMount');},mounted() {console.log('mounted');},beforeDestroy() {console.log('beforeDestroy');},destroyed() {console.log('destroyed');}
}

Composition API

<script setup>import { ref, onBeforeMount, onMounted } from 'vue'import {onLoad,onShow,onReady,onHide,onUnload,onPullDownRefresh,onReachBottom} from '@dcloudio/uni-app'// 1.页面的生命周期onLoad((options) => {console.log('onLoad');})onShow(() => {console.log('onShow');})onReady(() => {console.log('onReady');})onHide(() => {console.log('onHide');})onUnload(() => {console.log('onUnload');})onPullDownRefresh(() => {console.log('onPullDownRefresh');setTimeout(() => {uni.stopPullDownRefresh()}, 1000)})onReachBottom(() => {console.log('onReachBottom');})// 2.Vue组件的生命周期onBeforeMount(() => {console.log('onBeforeMount');})onMounted(() => {console.log('onMounted');})
</script>

七、系统API调用

1. 网络请求

简单使用

偷个懒,文档上复制的~

uni.request({url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。data: {text: 'uni.request'},header: {'custom-header': 'hello' //自定义请求头信息},success: (res) => {console.log(res.data);this.text = 'request success';}
});

01 - 进行封装

目录结构

request目录

index.js
/*** 封装请求*/import { BASE_URL, TIME_OUT } from './config.js'// 封装成类
class StarRequest {// 设定公共URL + 超时时间constructor(url, timeout) {this.baseUrl = urlthis.timeout = timeout}request({ url, method = 'GET', data } = {}) {// 返回一个promisereturn new Promise((resolve, reject) => {uni.request({url: this.baseUrl + url,timeout: this.timeout,method,data,success: (res) => {resolve(res.data)},fail: reject})})}get() {return this.request(option)}post() {return this.request({ ...option, method: 'POST' })}
}
// 可创建多个实例,请求不同的地址
export const sRequest = new StarRequest(BASE_URL, TIME_OUT)
config.js
/*** 设定常量*/
export const BASE_URL = 'http://www.baidu.com/api'
export const TIME_OUT = 10000

modules目录

common.js
/*** 封装公共逻辑*/
import { sRequest } from '@/service/request/index.js'// 获取公共的字典数据
export const getAllDics = () => {return sRequest.request({url: '/common/dic'})
}

统一导出index.js

/***     作统一导出*/// 公共数据
export { getAllDics } from './modules/common'// ...

02 - 使用

import { onLoad, onUnload } from "@dcloudio/uni-app";
import { getAllDics } from '@/service/index.js'// 封装一下请求,可以写在utils中,这里为了方便写在这
const awaitWrap = (promise) => {// 就不用写try...catch了return promise.then(res => [res, null]).catch(err => [null, err])
}onLoad(async () => {// 使用请求const [res, err] = await awaitWrap(getAllDics())// 如果不为空,说明抛出了异常,返回即可if (err !== null) return console.log('请求错误');// 拿到数据console.log(res);
})

2. 数据缓存

sync : 同步,不存储完,不会执行后续代码

八、Vue文档总结

Vue2 - Options API

Vue3 - Composition API

九、打包配置

H5 - 打包配置

1. 修改manifest.json的配置

2. 发行 - 打包H5

3. 部署到服务器即可

可看我的另一篇文章 : 云原生 之 docker

微信小程序 - 打包配置

1. 拿到小程序appId

2. 修改manifest.json的配置

3. 发行-微信小程序

4. 在微信开发者工具中进行上传

APP - 配置

待更新,未操作~

uni-app 之 跨平台开发相关推荐

  1. uni app和php开发微信登录代码,uniapp如何实现微信授权登录

    uniapp实现微信授权登录的方法:首先获取对应的appid和appsecret:然后在uniapp项目的manifest.json中进行APP SDK配置和模块权限配置.最后实现编码. 本教程操作环 ...

  2. andorid 手机APP应用程序开发介绍

    注意:此处的应用程序是一个app应用程序,而不是我们通常指的移动应用程序. 1.结束比较 本机应用 传统的本机应用程序开发模型中有两个主要系统,即iOS和Android,开发自己的应用程序需要使用每种 ...

  3. 原生革命--跨平台开发技术解析

    这篇文章,我将着重分析当前主流跨平台开发解决方案(偏架构)如Flutter.RN.Weex.Hybrid App,并对新晋跨端解决方案Fusion和Chameleon做一些分析,在传统原生开发不断被唱 ...

  4. 【iOS开发】跨平台开发再次袭来

    转自喵神博客:点击打开链接 这篇文章主要想谈谈最近又刮起的移动开发跨平台之风,并着重介绍和对比一下像是Xamarin,NativeScript 和 React Native 之类的东西.不会有特别深入 ...

  5. 跨平台开发时代的 (再次) 到来?

    这篇文章主要想谈谈最近又刮起的移动开发跨平台之风,并着重介绍和对比一下像是Xamarin,NativeScript .React Native和 DeviceOne 之类的东西.不会有特别深入的技术讨 ...

  6. 切换 uniapp_万能前端框架uni app初探03:底部导航开发

    前言 本节我们使用uni app的底部导航功能,点击不同tab会显示不同页面,这个功能在实际项目开发中几乎是必备的. 一.基础知识 1.tabBar 如果应用是一个多 tab 应用,可以通过 tabB ...

  7. 跨平台APP JQuery Mobile开发-张晨光-专题视频课程

    跨平台APP JQuery Mobile开发-1170人已学习 课程介绍         jQuery Mobile 是创建移动 web 应用程序的框架: 适用于所有流行的智能手机和平板电脑,使用 H ...

  8. App跨平台开发方案与抉择

    内心强大才敢于承认错误,但是首先你要敢于去试错. 现在做客户端开发的公司都会面临一个巨大的问题,那么就是跨平台.对于目前上市面上的移动设备来说.Android.IOS.WindowsPhone.Bla ...

  9. 推荐几款App跨平台开发工具

    众所周知开发App比较复杂,不仅要懂多种编程语言还要考虑高额的成本.作为开发者需要找到一个既节省成本又能快速开发App的最佳解决方案.不少跨平台开发工具便应运而生,选择一款适合自己的工具尤为重要,下面 ...

  10. uni app 开发微信小程序及上线体验

    uni app 开发微信小程序及上线体验 项目创建及微信小程序AppId的申请 本次开发的是电商类的微信小程序,这里用到的是HBuilderX这个编辑器.之前用的Visual Studio Code ...

最新文章

  1. add svn 多个文件_深圳信狮SVN技术文档
  2. CodeForces - 1368F Lamps on a Circle(交互+贪心)
  3. python测试开发实战_《python测试开发实战》基于pytest基础部分实例1-Hello
  4. lisp java_从Java调用的LISP代码
  5. php关闭gd库,详解php开启gd库的两种方法
  6. linux安装mysql5.6整套_Linux安装Mysql5.6
  7. element table多选表格_关于layui表格obj.update();无法重渲模板引擎问题
  8. 如何控制局域网网速_科普 | 路由器网速突然变慢怎么办?
  9. vue 下配置标题栏 title 图标及文字的具体步骤
  10. 升序输出三个数_C语言入门经典例题:求100~999的水仙花数
  11. 基于互联网的摄像测量系统(D 题)-- 2021 年全国大学生电子设计竞赛
  12. 建立桌面文件管理格子_win10桌面分区,win10如何创建桌面格子
  13. Mimics三维建模
  14. 浅谈mian函数的参数解析
  15. 从MP3到种子王者海盗湾, 鬼知道今天的去中心化都经历了些什么
  16. 具有催眠作用的螺旋图
  17. python3如何实现一行输入,空格隔开
  18. python 异步io 写excel_python异步IO编程(二)
  19. checkbox多选框,radio单选框
  20. 基频分析方法汇总【笔记】

热门文章

  1. Energia使用入门 总体介绍和I2C的使用-基于MSP432P402R
  2. Bootstrap File Input,最好用的文件上传组件
  3. python语言表白语句简单_100句简短表白情话 表白语句大全
  4. mysql设置id值为索引值_MySQL 索引
  5. 远离负能量,才能获得正能量
  6. ElementUI - <el-image> src 属性使用本地图片加载失败解决方案
  7. iphone14全系列参数对比 苹果14防水吗
  8. day02 JavaScript
  9. Android 颜色金属效果,5种颜色金属机身仅6.7毫米_三星 GALAXY A5_手机Android频道-中关村在线...
  10. 2、Python量化交易-三剑客之pandas