uniapp常用知识总结

1,364 阅读8分钟

一、页面生命周期

1、onShow 和 onHide

  • onShow 用于监听页面显示,页面每次显示时都会触发(包括从后台切换到前台或者从其他页面返回)

  • onHide 用于监听页面隐藏,页面每次隐藏都会触发

onShow(() => {
    // 页面显示时执行的操作
    console.log('页面显示~')
})

onHide(() => {
    // 页面隐藏时执行的操作
    console.log('页面隐藏~')
})

注意:
① 页面显示和隐藏,是一个会重复触发的事件:比如进入A页面时,A会触发 onShow,从A页面跳转到B页面,A会触发 onHide,B会触发 onShow,点击返回,A又会触发 onShow,B会触发 onHide

② onShow在ios和安卓h5的表现不同,比如唤起相机后拍照或取消在ios中也会触发onShow,而在安卓中不会,建议可编辑页面或有拍照上传功能时尽量不要在onShow中初始化数据

2、onLoad

  • onLoad 用于监听页面加载,当它被调用时,说明响应式数据、计算属性、方法、侦听器、props、slots已经执行完成

  • onLoad 可以接收页面跳转时传递的参数,参数类型为Object

onLoad((options) => {
    // options是跳转时传递的参数对象
    console.log('页面加载~',options)
    
    // 可以在这里初始化数据或执行其他逻辑
    // ...
})

3、onReady

  • onReady 用于监听页面初次渲染完成,此时页面 DOM 已经构建完成且页面组件也已经初始化完毕

  • 不建议在 onReady 触发之前进行跳转操作,因为 onReady 触发前页面可能还未完全渲染,进行跳转操作可能会有影响

onReady(() => {
    console.log('页面初次渲染完成~')
    
    // 可以在onReady触发后进行跳转,此时 DOM 已经构建好,跳转不会影响页面渲染
    uni.navigateTo({
        url:'url'
    })
})

4、onUnload

  • onUnload 用于监听页面卸载,比如用户点击返回按钮 ⬅ 、关闭页面时

  • uni.navigateTo 跳转时不会触发 onUnload,因为当前页面并未卸载,而是压入了页面栈中

  • uni.redirectTouni.reLaunchuni.navigateBack 跳转时会触发 onUnload

onUnload(() => {
    console.log('页面卸载~')
})

5、onLoad、onReady、onshow区别

  • 执行次数: onLoad (页面加载) 和 onReady (页面初次渲染) 只触发一次,onShow (页面显示) 可触发多次

  • 执行顺序:
    ① onLoad:页面加载时首先触发,此时页面还未开始渲染
    ② onReady:页面初次渲染完成后触发,此时 DOM 元素已经构建好,组件已经初始化完成
    ③ onShow:页面每次显示时都会触发,首次进入应用时在 onReady 之后触发

二、本地存储

1、localStorage / sessionStorage

适用于浏览器环境下的数据存储,localStorage 适用于长期存储,sessionStorage 适用于会话期间的存储。

  • localStorage: 使用浏览器提供的 localStorage API 进行本地存储,可以存储字符串类型的数据,并且在同一域名下的所有页面共享。数据持久化,除非手动清除,否则一直存在。
//  将数据存储到 localStorage 中,键为key,值为value
localStorage.setItem("key", "value")

//  从 localStorage 中获取指定键的值
localStorage.getItem("key")
  • sessionStorage: 与 localStorage 类似,但是数据只会在 当前会话期间 有效,一旦会话结束就会被清除
//  将数据存储到 sessionStorage 中,键为key,值为value
sessionStorage.setItem("key", "value")

//  从 sessionStorage 中获取指定键的值
sessionStorage.getItem("key")

2、uni.setStorage / uni.getStorage

适用于需要异步处理的数据存储,适合处理大量数据或需要在数据存取完成后执行额外逻辑的场景。

  • uni.setStorage: uniapp所提供的,将数据 异步 存储到本地缓存中,可以提供成功、失败和完成时的回调函数。不会阻塞 后续代码的执行,而是通过回调函数来处理操作结果。
// 异步存储
uni.setStorage({
  key: "key",
  data: "value",
  success: () => {
    console.log("存储成功");
  },
  fail: (err) => {
    console.log("存储失败",err);
  }
})
  • uni.getStorage: uniapp所提供的,从本地 异步 获取数据的方法,可以提供成功、失败和完成时的回调函数。不会阻塞 后续代码的执行,而是通过回调函数来处理操作结果。
// 异步获取
uni.getStorage({
  key: "key",
  success: (res) => {
    console.log("获取成功",res.data);
  },
  fail: (err) => {
    console.log("获取失败",err);
  }
})

3、uni.setStorageSync / uni.getStorageSync

适用于简单的数据存取,不涉及复杂的异步处理,适合快速存取少量数据的场景。

  • uni.setStorageSync: uniapp所提供的,将数据 同步 存储到本地缓存中,即时执行,没有回调函数。会阻塞 后续代码的执行,直到操作完成。
// 同步存储
uni.setStorageSync("key", "value")
  • uni.getStorageSync: uniapp所提供的,从本地 同步 获取数据的方法,即时执行,没有回调函数。 会阻塞 后续代码的执行,直到操作完成。
// 同步获取
uni.getStorageSync("key")

三、页面跳转

1、uni.navigateTo

  • 保留当前页面,跳转到应用内的某个页面 (只能打开非tabBar页面),使用uni.navigateBack可以返回到原页面。

  • 如果从当前页面跳转到当前页面,可以实现强制刷新当前页面的效果。

uni.navigateTo({
  url: 'url',
})

EventChannel

  1. 从当前页面发送事件到目标页面,使用 events 参数定义事件监听器
// 当前页面
uni.navigateTo({
  url: '/pages/targetPage',
  events: {
    // 定义事件监听器
    someEvent: (data) => {
      console.log('Received data:', data);
    }
  },
  success: (res) => {
    // 向目标页面发送事件
    res.eventChannel.emit('someEvent', { message: 'Hello from current page' });
  }
});
  1. 在目标页面中接收事件,使用 getOpenerEventChannel 获取EventChannel对象,监听来自上一个页面的事件
// 目标页面(/pages/targetPage)
onLoad(options) {
  const eventChannel = proxy.getOpenerEventChannel();

  // 监听事件
  eventChannel.on('someEvent', (data) => {
    console.log('Received data in target page:', data);
  });
}
  1. EventChannel支持 双向通信,可以在目标页面中发送事件给上一个页面,在上一个页面中监听来自目标页面的事件
// 目标页面(/pages/targetPage)
onLoad(options) {
  const eventChannel = proxy.getOpenerEventChannel();

  // 监听事件
  eventChannel.on('someEvent', (data) => {
  console.log('Received data in target page:', data);
  });
  
  // 向上一页面发送事件
  eventChannel.emit('responseEvent', { message: 'Hello from target page' });
}

=========================================分割线=================================================

// 当前页面
uni.navigateTo({
  url: '/pages/targetPage',
  events: {
    someEvent: (data) => {
      console.log('Received data:', data);
    },
    responseEvent: (data) => {
      console.log('Response from target page:', data);
    }
  },
  success: (res) => {
    res.eventChannel.emit('someEvent', { message: 'Hello from current page' });
  }
});

使用场景: 点击位于列表中间或底部位置的项,进入详情操作后跳转回列表,滚动位置需要保持

2、uni.navigateBack

  • 关闭当前页面,返回上一页面或多级页面,使用getCurrentPages()可以获取当前的页面栈。

  • H5端调用 uni.reLaunch 之后页面栈会销毁 ,但是无法清空浏览器之前的历史记录,此时navigateBack不能返回

uni.navigateBack({
// 返回的页面数,默认为 1,如果 delta 大于现有页面数,则返回到首页。
    delta: 2 
})

3、uni.redirectTo

  • 关闭 当前 页面,跳转到应用内的某个页面 (只能打开非tabBar页面)。

  • 如果从当前页面重定向到当前页面,可以实现强制刷新当前页面的效果。

uni.redirectTo({
    url:'url'
})

4、uni.reLaunch

  • 关闭 所有 页面,跳转到应用内的某个页面
  • 如果从当前页面relaunch到当前页面,可以实现强制刷新当前页面的效果。
uni.reLaunch({
    url:'url'
})

除了可以使用 uni.navigateTo( )uni.redirectTo( )uni.relaunch( ) 方法实现 页面刷新 外,还可以使用window方法

// h5页面适用
window.location.reload()

上面的跳转方法都有 可选参数 success( )fail( )complete( ) ,分别为调用成功的回调、调用失败的回调和调用结束的回调(成功或者失败都会执行)

uni.navigateTo({
  url:'url',
  success: (res) => {
    console.log('跳转成功~', res)
  },
  fail: (err) => {
    console.log('跳转失败~', err)
  },
  complete: () => {
    console.log('跳转完成~')
  }
})

注意: uni.navigateTo 跳转时,对页面栈做了限制,最大 10 层,超过10层时跳转会报错,所以要根据场景,选择 uni.redirectTo(如从详情跳转回列表时) 或者 uni.reLaunch(如返回首页) 进行跳转。

四、页面传值

1.传递一个或多个参数

在跳转到目标页面的路由添加 ? 后添加需要传递的参数名,如id,多个参数之间使用 &连接

// 字符串拼接
uni.navigateTo({
  url:'/pages/entry/detail?id=12345&type=1'
})

// 动态参数
uni.navigateTo({
  url:`/pages/entry/detail?id=${entryId}&type=${entryType}`
})

在目标页面的 onLoad() 方法中添加 形参options 来接收传递过来的参数

onLoad(options){
  // 方式一:使用对象获取
  const { entryId, entryType } = options;
  // 方式二:一个一个接收
  this.entryId = options.entryId
  this.entryType = options.entryType
}

2.传递数组或对象

由于 url 的长度限制,需要使用 JSON.stringfy( ) 将数组或对象转为JSON字符串,使用encodeURIComponent 编码之后再进行传递

uni.navigateTo({
  url:'/pages/entry/detail?itemList=encodeURIComponent(JSON.parse(itemList))'
})

在目标页面的 onLoad() 方法中使用 decodeURIComponent 解码后,再使用 JSON.parse 获取数据

onLoad(options){
  this.itemList = JSON.parse(decodeURIComponent(options.itemList))
}

四、启用、禁用滚动

1. 禁用滚动:适用于打开popup弹窗时,禁用滚动

// 禁用滚动
const handleDisableScroll = () => {
  document.body.style.overflow = 'hidden'
  return true
}

2. 启用滚动:关闭popup弹窗时,重新启用滚动

// 启用滚动
const handleEnableScroll = () =>{
  document.body.style.overflow = 'auto'
  return true
}

五、监听返回,阻止默认事件

  • 使用 JavaScript 监听浏览器(企业微信浏览器也可)的 popstate 事件,popstate会在浏览器历史记录发生变化时触发(包括点击浏览器的返回按钮 ⬅ )

  • 在事件处理中函数中,可以自定义处理逻辑、执行特定操作,如阻止浏览器默认返回行为

// 监听浏览器返回,可以放在页面显示中 (onShow)
onShow(() => {
    window.addEventListener('popstate',preventDefault)
})

// 移除监听浏览器返回,可以放在页面卸载中 (onUnload)
onUnload(() =>{
    window.removeEventListener('popstate',preventDefault)
})

// 事件处理函数
const preventDefault = (event) => {
    // 阻止浏览器默认行为
    event.preventDefault()
}

六、适配ios底部安全距离

因为部分的ios机型最下面会有条黑色等线,导致靠近底部的元素被遮住部分,所以设置安全区边距会往上提,如果不是刘海屏则保持原来样式。

.safeAreaInsetBottom {  
    // 写在需要添加底部边距的盒子上
    padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
    padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
}

七、禁用原生导航栏

在启用原生导航栏时,uniapp打包到线上会出现 双标题 问题,因为访问时,除 uniapp 的标题外,浏览器还会有一个标题。此时可以通过 禁用原生导航栏 的方法来进行解决,在项目的 page.json 文件 app-plus 选项中添加 titleNview:false;

"pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "",
        "app-plus": {
          "titleNView": false //禁用原生导航栏
        }
      }
    },
 ]