开发规范
- 页面文件向导Vue单文件组件(SFC)规范
- 页面标签靠近小程序规范
- API靠近微信小程序规范,但是wx需替换为uni
- 数据绑定及时间处理同Vue.js规范
- 为了兼容,建议使用flex布局
uniApp 在VScode中开发(因为uniapp的ts校验差)
- 安装ts类型校验
- 安装:npm i -D @types/wechat-miniprogram @uni-helper/uni-app-types
- 配置tsconfig.json
1
2
3
4
5
6
7
8
9
10"compilerOptions": {
"types": [
"@dcloudio/types",
"@types/wechat-miniprogram",
"@uni-helper/uni-app-types"
]
},
"vueCompilerOptions": {
"experimentalRuntimeMode": "runtime-uni-app"
}
- json文件问题
- 在项目中看是否有manifest.json,没有就创建然后在设置中搜文件关联或者Association
- 然后设置 项为manifest.json 值为jsonc,
- 项为pages.json 值为jsonc
uniApp生命周期
- onLaunch:当
uni-app
初始化完成时触发(全局只触发一次) - onShow:当
uni-app
启动时,或从后台进入前台显示 - onHide:当
uni-app
从前台进入后台 - onError: 当
uni-app
报错时触发 - onUniNViewMessage:当
nvue
页面发送数据进行监听,可参考nvue
向vue
通讯 - onUnhandledRejection:对未处理的
Promise
拒绝事件监听函数 - onPageNotFound:页面不存在监听函数
- onThemeChange:监听系统主题变化
页面生命周期
- onLoad:监听页面加载,其参数为上个页面传递的数据,参数类型为Object
- onShow:监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
- onReady:监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
- onHide:监听页面隐藏
- onUnload: 监听页面卸载
- onResize:监听窗口尺寸变化
- onPullDownRefresh:监听用户下拉动作,一般用于下拉刷新
- onREachBottom:页面滚动到底部的事件,常用于下拉下一页数据
- onTabItemTap:点击tab时触发,参数为Object
- onShareAppMessage:用户点击右上角分享
- onPageScroll:监听页面滚动,参数为Object
- onNavigationBarButtonTap:监听原生标题栏按钮点击事件,参数为Object
- onBackPress:监听页面返回
- onNavigationBarSearchInputChanged:监听原生标题栏搜索输入框输入内容变化事件
- onNavigationBarSearchInputConfirmed:监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发
- onNavigationBarSearchInputClicked:监听原生标题栏搜索输入框点击事件
- onShareTimeline:监听用户点击右上角转发到朋友圈
- onAddToFavorites:监听用户点击右上角收藏
路由跳转
方式一标签式导航:navigator 组件跳转
- 示例:
<navigator url="/pages/404/404">404页面</navigator>
- 示例:
方式二编程式导航:调用API跳转
路由方式 页面栈表现 触发时机 初始化 新页面入栈 uni-app打开的第一个页面 打开新页面 新页面入栈 调用API uni.navigateTo、
使用组件页面重定向 当前页面出栈,新页面入栈 调用API uni.redirectTo、
使用组件页面返回 页面不断出栈,直到目标返回页 调用API uni.navigateBack、
使用组件、
用户按左上角返回按钮、安卓用户点击物理back按键Tab切换 页面全部出栈,只留下新的Tab页面 调用API uni.switchTab、
使用组件、
用户切换Tab重加载 页面全部出栈,只留下新的页面 调用API uni.reLaunch、
使用组件注意:没有配置tabbar(就是类似于微信下面的那个图标状态栏点击可切换的)时,可以使用navigator来跳转任意页面,但是配置tabbar后,只能使用switchTab来跳转到tabbar配置的页面
获取当前页面栈
- getCurrentPages()函数,以数组形式按照栈的顺序。第一个元素为首页,最后一个元素为当前页面
路由传参与接收
- 页面生命周期的onLoad()监听页面加载,其参数为上个页面传递的数据
- 如在上个页面通过url在路径中携带参数,?后为所携带参数,用&连接多个参数,以键=值的形式传递,pagePath为所要跳转的页面
1
2
3uni.navigateTo({
url:"pagePath?name=lily&age=18"
}) - 可以在pagePath页面中使用onLoad获取参数
1
2
3onLoad:function(option) {
conosle.log(option.name)
} - 注意:url有长度限制,所以对于复杂的参数建议使用encodeURI、decodeURI进行处理后传递
小程序路由分包配置
- 在pages.json中在subPackges中配置分包的路径和分包下的页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18"subPackages": [{
"root": "subpages", // 配置分包名
"pages": [{
"path": "news/news", // 分包中的页面路径
"style":
{
"navigationBarTitleText": "新闻中心",
"enablePullDownRefresh": false
}
}],
}],
// 预下载分包设置
"preloadRule": {
"pages/index": { // 进入那个页面才会预下载
"network": "all", // all | wifi 在上面环境下下载
"packages": ["subpages"] // 进入该页面后预下载的分包的root或name,以字符串数组的方式传递。__APP__ 表示主包。
}
},
自定义组件与通信
- 使用的两种方式:全局注册 和 页面引入
- 使用步骤:
- 导入 import xxx from “xxx”
- 注册 Vue.use(‘xx’,xx) 或者在script中添加 components:{xxx}
- 使用
父子组件通信
父 –> 子
- 父组件通过自定义属性向子组件传递数据
- 如子组件
<child />
在父组件中使用了。然后父组件像子组件添加一个自定义属性msg,并通过这个msg传递静/动态数据 - 传递静态数据:
<child msg="父组件定义一个属性向子组件传递信息"/>
- 传递动态数据:
<child :msg="title" />
这个title是在data中定义的变量
- 如子组件
- 子组件通过props接收父组件传递的数据
- 子组件要拿到这个自定义属性放在props中定义,页面即可直接使用
- 子组件在data前面添加props: [‘msg’],然后可以直接使用
<view>{{msg}}</view>
子 –> 父
- 父组件通过自定义事件标签向子组件传递事件
- 父组件在子组件的标签中添加 @childEvent=”sayHello” ,childEvent是子组件要emit的事件,sayHello是点击这个事件要触发的函数。所以父组件中的methods要定义这个sayHello函数
- 父组件可以通过sayHello(value) {},这个value直接获取子组件向父组件传递的参数
- 子组件通过触发父组件定义事件方式修改父组件数据
- 子组件任意绑定一个事件,在methods中写这个事件,该事件要触发this.$emit(‘childEvent’)
- 子组件还可以通过this.$emit(‘childEvent’, ‘要传递的参数’)
slot数据分发与作用域插槽
- 父组件通过调用子组件内部嵌套html内容作为slot分发给子组件
- 子组件通过在slot标签上添加属性,向父组件通信数据,作用域插槽
全局事件定义与通信
- 1.在整个应用的任何地方均可以使用uni.$on创建一个全局事件
1
2
3
4
5在任意页面使用
uni.$on('getInfo', (value) => {
this.anyvar = value // 可以定义一个变量然后改变时可以看见效果
console.log('我的全局事件被触发了')
})- 要先点击我的页面然后在回去按按钮就会有效果,因为放在onLoad事件中要先加载这个页面
- 2.在整个应用的任何地方也均可以使用uni.$emit来触发全局事件,实现多组件间的数据通信
- 在任意要触发的地方使用uni.$emit(‘getInfo’,’全局事件的传参’)
- 这个getInfo为全局事件
Pinia 状态管理(官方推荐使用,钩子与vuex三件套一样,不需要mutation)
- 多个组件间共享数据或状态
- State:存储状态数据
- Getter:从状态数据派生数据,相当于State的计算属性
- Mutation:存储用于同步更改状态数据的方法,默认传入的参数为State
- Action:存储用于异步更改状态数据,但不是直接更改,而是通过触发Mutation方法实现,默认参数为context
- Module:Vuex模块化
在项目中使用Pinia
首先在main.js文件中引入store文件
1
2
3
4
5
6
7
8
9
10
11import { createSSRApp } from 'vue'
import * as Pinia from 'pinia'
export function createApp() {
const app = createSSRApp(App)
app.use(Pinia.createPinia())
return {
app,
Pinia
}
}新建一个store的目录并且在该目录下新建一个js文件,形式大概按照一下形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14import { defineStore } from 'pinia'
export const useUserStore = defineStore('userStore',{
id: 'user',
state: () => ({ userName: '未登录用户' }),
actions: {
login(userName) {
this.userName = userName
},
logout(){
this.userName = "退出登录"
}
},
})
在文件中调用全局事件
1 | <view> |
运行环境判断与跨端兼容
开发环境和生产环境
- 测试时可以通过uniApp上方导航栏的发行来测试二者的效果
1
2
3
4
5if(process.env.NODE_ENV === 'development') {
console.log('开发环境')
}else {
console.log('生产环境')
}
判断平台
- 存在两种场景,一种实在编译器判断,一种是运行期判断
编译器判断:即条件编译,不同平台在编译出包后已经是不同的代码
1 | // #ifdef H5 |
运行期判断:是指代码已经打入包中,仍然需要在运行期判断平台
- 使用 uni.getSystemInfoSync().platform 判断客户端环境是Android、iOS还是小程序开发工具
1
2
3
4
5
6
7
8switch(uni.getSystemInfoSync().platform) {
case 'android':
break;
case 'iOS':
break
default:
break
}
跨端兼容
- 条件编译写法: 以#ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾
- #ifdef: if defined 仅在某平台存在
- #ifndef:if not defined 除了某平台均存在
- %PLATFORM%:平台名称
%PLATFORM%的值 | 平台 |
---|---|
APP-PLUS | App |
APP-PLUS-NVUE | App nvue |
H5 | H5 |
MP-WEIXIN | 微信小程序 |
MP-ALIPAY | 支付宝小程序 |
MP-BAIDU | 百度小程序 |
MP-TOUTIAO | 字节跳动小程序 |
MP-QQ | QQ小程序 |
MP-360 | 360小程序 |
MP | 含以上所有小程序 |
QUICKAPP-WEBVIEW-UNION | 快应用联盟 |
QUICKAPP-WEBVIEW-HUAWEI | 快应用华为 |
QUICKAPP-WEBVIEW | 含以上所有快应用通用 |
vue3中的使用方式
template部分
- 循环:v-for=”(item,index) in list” :key=”index”
- 判断:v-if=”!item.isMe”
- 事件:@click=”sendMsg”
- 组件上的属性需要动态的 :src=”item.img”
- 插入页面的文本:
在 script setup标签中
生命周期按这种方式书写
- 首先引入对应的生命周期: import { onLoad } from "@dcloudio/uni-app";
- 然后使用:onLoad(() => {})
定义一个变量和赋值:
- reactive一般使用场景是数组和对象,ref一般是基本数据类型
- 使用reactive响应的数据,最好是调用数据中的某一项,如果是添加push一整个数组使用ref比较好。不然不实时更新
- 定义const name = ref(''),使用name.value ='123'
- 定义const list = reactive([]),使用list.push()
定义一个方法: const clickfn = () => {}
props:
- 引入 import { defineEmits,defineProps } from ‘vue’
- defineProps({
msg: String
})
emit:
- 将事件定义好const emits = defineEmits([‘childEvent’,’getInfo’])
- 调用:emits(‘childEvent’,’传递的参数’)
全局emit
- 将事件定义好const emits = defineEmits([‘childEvent’,’getInfo’])
- 使用:uni.$emit(‘getInfo’,’全局事件的传参’)
- 调用:uni.$on(‘getInfo’, (value) => { name.value = value })
实时滚动到页面底部
1 | nextTick(() => { |
设置登录缓存后,退出清除缓存
- 使用uni.removeStorageSync(key),只清除这个key的缓存
- 使用uni.clearStorageSync(),清除本地缓存,全部清除