View —— 页面HTML
ViewModel 用于数据双向绑定 —— 核心调度协调器
Model —— 单页面静态数据
注意:三者之间是双向箭头
应用生命周期:
onLaunch —— 初始化完成时触发(全局只触发一次)
onShow —— uni-app启动触发,或从后台进入前台(会多次触发)
onHide —— uni-app从前台进入后台(会多次触发)
onError —— uni-app报错时触发
页面生命周期:
onLoad —— 不会多次触发
onShow —— 多次触发
onReady —— 页面初次渲染完成时触发,不会多次触发
onHide —— 多次触发
onUnload —— 监听页面卸载
注意:tabBar页面展现过一次就保留在内存中,再次切换tabbar页面,只会触发每一个页面的onShow方法,不会再触发onLoad方法。
tabBar至多展示5个,至少展示2个。
"tabBar": {
"color": "文字默认颜色",
"selectedColor": "文字选中颜色",
"list": [{ "text": "标题", "pagePath": "页面路径" }, { ... }]
}
公用样式在globalStyle中配置。
"globalStyle": {
"navigationBarTextStyle": "导航栏标题颜色及状态栏前景颜色,仅支持black/white",
"navigationBarTitleText": "导航栏标题文字内容",
"navigationBarBackgroundColor": "导航栏背景颜色(同状态栏背景色)",
"backgroundColor": "下拉显示出来的窗口的背景色"
}
所有页面需要在pages中配置。
"pages": [
{ "path": "页面路径", "style": { "enablePullDownRefresh": true },
{ ... }
]
// html代码
// js代码
e.currentTarget.dataset.userid // 这里的userid每个字母均为小写
注意:无论XXX是否大小写,在js获取时均为小写。
@import url("css文件相对路径");
注意:不能使用*选择器;字体引用推荐使用以~@开头的绝对路径。
// pages.json部分配置项
"path": "...",
"style": {
"app-plus": {
"titleNView": {
"type": "transparent",
"buttons": [{ "type": "share" }]
}
}
}
// js部分代码
uni.setNavigationBarColor({ // 通过代码设置导航栏
frontColor: '#FFF',
backgroundColor: '#000'
})
onPullDownRefresh () { ... }
// 该方法与data(){}等方法同级
// 当数据更新完成后,使用uni-stopPullDownRefresh()方法结束刷新
// 也可以使用uni-startPullDownRefresh()方法手动下拉刷新
onReachBottom () { ... }
// 该方法与data(){}等方法同级
// 可以使用onReachBottomDistance来设置距离页面底部还剩多少间距时触发该方法
uni.chooseImage()
uni.previewImage()
// 1、HTML在标签上新增longpress事件
// 2、JS主要代码
uni.showActionSheet({
itemList: ['保存图片', '分享到微信'],
success: (res) => {
if (res.tapIndex == 0) {
uni.downLoadFile({
url: '图片地址',
success: (result) => {
const tempFilePath = result.tempFilePath // 图片临时路径
uni.saveImageToPhotosAlbum({ // 保存图片至本地相册
filePath: tempFilePath,
success: () => {
uni.showToast({ title: '保存成功' })
}
})
}
})
}
}
})
小程序中用户点击分享后,在JS中定义onShareAppMessage处理函数,设置该页面的分享信息。
onShareAppMessage (res) { // 此函数与onLoad()函数同级
return {
title: '标题',
path: '/pages/xxx/xxx?id=' + id //这里的参数根据需要添加即可
}
}
注意:此函数在微信小程序、百度小程序、字节跳动小程序和QQ小程序中生效。
// 首先需要设置appid和appsecret
mainfest.json -> App SDK配置 -> 分享微信消息及朋友圈 -> 填写appid和appsecret
// 监听导航栏的按钮
onNavigationBarButtonTap (e) { // 与onLoad()同级
const index = e.index
if (index == 0) { // index为0则分享
uni.share({
provider: 'weixin',
scene: 'WXSenceTimeline',
type: 0,
href: '完整的url',
title: '这里填写标题',
summary: '简介',
imageUrl: '封面/图片url',
success: (res) => {}
})
}
}
// #ifdef MP
console.log('这里的JS代码只在小程序中生效')
// #endif
/* #ifdef H5 */
.content { 这里的CSS代码只在H5中生效 }
/* #endif */
这里的HTML代码只在小程序中生效
这里的HTML代码不在H5中生效
// html代码
// js代码
onReady () {
this.videoContext = uni.createVideoContext('mymovie')
}
onShow () {
if (this.videoContext) this.videoContext.play() // 当页面展示时,播放视频(也可手动控制视频播放,就无需此行代码)
}
onHide () {
this.videoContext.pause()
}
// html代码
// js代码(播放一个视频,需暂停其他视频)
meIsPlaying (e) {
let trailerId = ''
if (e) {
trailerId = e.currentTarget.dataset.playingindex
this.videoContext = uni.createVideoContext(trailerId)
}
for (let i = 0; i < this.hotTrailerArr.length; i++) {
const temp = this.hotTrailerArr[i].id
if (temp != trailerId) uni.createVideoContext(temp).pause()
}
}
// html代码
// js代码
data () {
animationData: {}
},
onLoad () {
this.animation = uni.createAnimation()
},
onUnload () {
this.animationData = {}
},
methods: {
// 创建点赞动画
praiseMe () {
// 构建动画数据,并通过step表示这组动画的完成
this.animation.translateY(-60).opacity(1).step({ duration: 400 })
// 导出动画数据到view数据,实现组件动画效果
this.animationData = this.animation.export()
// 还原动画
setTimeout(() => {
this.animation.translateY(0).opacity(0).step({ duration: 0 })
this.animationData = this.animation.export()
}, 500)
}
}
情景:
this.audioObj = uni.createInnerAudioContext()
this.audioObj.src = '视频路径'
this.audioObj.play() // 自动开始播放,Android端有声音,但iOS端无声音
解决:建议在onReady中添加以下代码
wx.setInnerAudioOption({ obeyMuteSwitch: false }) // 是否遵循静音开关,设置为false之后,即使是在静音模式下,也能播放声音(仅在iOS生效)
原因:uni-popup组件阻止了默认事件的冒泡
解决:直接修改uni-popup.vue组件源码,去掉@touchmove.stop.prevent="clear"
请参考案例
原因:code获取错误,导致后台的解密key与code不对应
解决:
小程序获取手机号之前,需要先wx.login()
需要在进入小程序前就wx.login(),而不是在getphonenumber里面wx.login()
wx.showLoading({ title: '加载中...' })
wx.hideLoading()
注意:在数据循环时,小程序内部已经封装好了item和index,可以直接使用。若需要更换名称,则需要使用wx:for-item="新变量"和wx:for-index="新变量"。
wx.setNavigationBarTitle({ title: '标题名称' })
// 首先需要配置json文件
"enablePullDownRefresh": true
"backgroundTextStyle": "dark" // 可选项,用于设置刷新时三个点的颜色
// 其次需要在js中编写如下代码
onPullDownRefresh () { // 下拉刷新
wx.showNavigationBarLoading() // 可选项,开启头部刷新状态
wx.stopPullDownRefresh() // 数据加载完毕,隐藏下拉刷新状态
wx.hideNavigationBarLoading() // 可选项,隐藏头部刷新状态
}
onReachBottom () { ... } // 上滑刷新
// 子组件child
this.triggerEvent('updateData', { data: 10 })
// 父组件
// 设置角标
wx.setTabBarBadge({
index: 2, // 第几个tab
text: String(shoppingCartArr.length)
})
// 移除角标
wx.removeTabBarBadge({
index: 2
})
// 定义变量
data: {
startX: 0,
startY: 0
},
// 定义方法
touchstart (e) { // 开始触摸时
this.data.shoppingCartArr.forEach(item => {
if (item.isTouchMove) item.isTouchMove = false
// 开始触摸时将所有商品的删除按钮重置
this.setData({
startX: e.changedTouches[0].clientX,
startY: e.changedTouches[0].clientY
})
})
},
touchmove (e) { // 手指滑动时
const index = e.currentTarget.dataset.index
// 开始的x和y坐标
const startX = this.data.startX
const startY = this.data.startY
// 移动的x和y坐标
const touchMoveX = e.changedTouches[0].clientX
const touchMoveY = e.changedTouches[0].clientY
// 调用计算角度方法
const angel = this.angel({ x: startX, y: startY }, { x: touchMoveX, y: touchMoveY })
// 遍历数组中的所有对象
this.data.shoppingCartArr.forEach((item, i) => {
item.isTouchMove = false
// 滑动角度>30°则直接return
if (Math.abs(angel) > 30) return false
// 匹配
if (i == index) {
if (touchMoveX > startX) item.isTouchMove = false // 右滑
else item.isTouchMove = true // 左滑
}
})
},
angel (start, end) {
const _x = end.x - start.x
const _y = end.y - start.y
// 返回角度Math.atan()返回数字的反正切值
return 360 * (Math.atan(_y / _x) / (2 * Math.PI))
}
uni-app实现左滑删除功能:https://blog.csdn.net/qq_36864210/article/details/109047092
// 步骤一:获取openid
wx.login({
success: (res) => {
const appid = '这是你的appid'
const secret = '这是你的secret'
wx.request({
url: '这里是你的请求地址',
success (res) {
const openid = res.data.openid
this.wechatPay(openid)
}
})
}
})
// 步骤二:调用支付接口
wechatPay (openid) {
wx.request({ // 发起后端接口请求
url: '这里是你的请求地址',
methods: 'POST',
data: {
openid: openid // 这里填写后端需要的参数
},
success (res) {
wx.requestPayment({
appId: res.data.appId,
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.package,
signType: res.data.signType,
paySign: res.data.paySign,
success (res) {
wx.showToast({ title: '支付成功' })
},
fail () {
wx.showToast({ title: '支付失败' })
}
})
}
})
}