# 微信小程序基础

# uniapp 中的生命周期

在移动端项目中,生命周期分为,页面级生命周期组件级生命周期

# 页面级生命周期

  • onInit 监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad

    `onInit`使用注意

    仅百度小程序基础库 3.260 以上支持 onInit 生命周期

  • onLoad监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参)
  • onShow监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
  • onReady监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
  • onHide监听页面隐藏
  • onUnload监听页面卸载
  • onResize监听窗口尺寸变化 (适用于App、微信小程序、快手小程序)
  • onPullDownRefresh监听用户下拉动作,一般用于下拉刷新
  • onReachBottom页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。

    `onReachBottom`使用注意

    可在pages.json里定义具体页面底部的触发距离onReachBottomDistance,比如设为50,那么滚动页面到距离底部50px时,就会触发onReachBottom事件。

  • 更多 参考文档 (opens new window)

# 组件级生命周期

uni-app 组件支持的生命周期,与vue标准组件的生命周期相同。这里没有页面级的onLoad等生命周期: 在组件中,不能使用页面级生命周期

  • beforeCreate 在实例初始化之前被调用
  • created在实例创建完成后被立即调用 -beforeMount在挂载开始之前被调用
  • mounted挂载到实例上去之后调用。注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick
  • beforeUpdate数据更新时调用,发生在虚拟 DOM 打补丁之前
  • updated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子
  • beforeDestroy实例销毁之前调用。在这一步,实例仍然完全可用。
  • destroyedVue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

# uniapp 获取右上角胶囊位置

uni.getMenuButtonBoundingClientRect()函数
在小程序平台,如果原生导航栏被隐藏,仍然在右上角会有一个悬浮按钮,微信下也被称为胶囊按钮。本API用于获取小程序下该菜单按钮的布局位置信息,方便开发者布局顶部内容时避开该按钮。

onBeforeMount(() => {
    const res = uni.getMenuButtonBoundingClientRect()
    btnStyles.value = res
    if (props.isBlack) classNames.value = 'custom-btn black'
    if (props.showHome) btnStyles.value = `top:${res.top}px;width:${res.width}px;`
    else btnStyles.value = `top:${res.top}px;`
})

# uniapp 获取底部安全距离和状态栏高度

uniapp提供了预置的css变量

  • 获取上安全距离: env(safe-area-inset-top)
  • 获取左安全距离:env(safe-area-inset-left)
  • 获取右安全距离:env(safe-area-inset-right)
  • 获取下安全距离:env(safe-area-inset-bottom) 可以在固定底部的盒子加下内下边距 padding-bottom: env(safe-area-inset-bottom) 避免元素被遮挡
.bottom {
    padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
}

# 自定义顶部导航栏

自定义导航栏需要注意的是:顶部存在状态栏,也就是显示信号、时间等信息的状态栏;

  • 获取状态栏高度:var(–status-bar-height)
  • 可以在页面的最外层的盒子加内上边距 padding-top: var(–status-bar-height)避免顶部导航栏与状态栏重叠.
  • 并且需要给最外层盒子设置背景色与页面背景色一致,不然会出现状态栏的背景色和页面背景色不一致的情况;

# 另外uniapp 还有一些其他的css 变量

  • 内容区域距离顶部的距离:var(–window-top);
  • 内容区域距离底部的距离:var(–window-bottom);

# 获取设备信息

uni.getSystemInfo()用于获取用户手机信息 状态栏高度、可视区域等

    //获取用户设备信息
uni.getSystemInfo().then((res) => {
    console.log('用户设备信息', res)
    systeminfo.getsysteminfo(res)
})

# 获取当前地理位置

uni.getLocation() 用于获取当前经纬度信息

//获取当前经纬度
uni.getLocation().then((res) => {
    console.log('当前经纬度信息', res);
})

# 通过经纬度信息计算距离

// 经纬度转换成三角函数中度分表形式。
function rad(d: number): number {
    return (d * Math.PI) / 180.0
}

//lat1 当前定位经度
//lng1  当前定位纬度
//lat2 当前距离地点经度
//lng2 当前距离地点纬度
export const getDistance = function (lat1: number, lng1: number, lat2: number, lng2: number): any {
    const radLat1: number = rad(lat1)
    const radLat2: number = rad(lat2)
    const a: number = radLat1 - radLat2
    const b: number = rad(lng1) - rad(lng2)
    let s: number =
        2 *
        Math.asin(
            Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))
        )
    s = s * 6378.137 // EARTH_RADIUS;
    s = Math.round(s * 10000) / 10000 //输出为公里

    const distance: number = s
    let distance_str: string = ''

    if (distance >= 1) {
        distance_str = distance.toFixed(1) + 'km'
    } else {
        distance_str = distance * 1000 + 'm'
    }

    //s=s.toFixed(4);

    return {
        distance_str: distance_str,
        distance: distance_str
    }
}

# uniapp拦截器

uni.addInterceptor(STRING, OBJECT)

# STRING 参数说明

需要拦截的api名称,如:uni.addInterceptor('request', OBJECT) ,将拦截 uni.request()

注意

  • 仅支持异步接口,如:uni.setStorage(OBJECT),暂不支持同步接口如:uni.setStorageSync(KEY,DATA)
  • uniCloud请求云端接口时(callFunctionuploadFile等)也会使用uni.request发送请求,请确保拦截器内不错误的处理此类请求
参数名 类型 必填 默认值 说明
invoke Function 拦截前触发
returnValue Function 方法调用后触发,处理返回值
success Function 成功回调拦截
fail Function 失败回调拦截
complete Function 完成回调拦截

# 示例

uni.request({
    url: 'request/login', //仅为示例,并非真实接口地址。
    success: (res) => {
        console.log(res.data);
        // 打印: {code:1,...}
    }
});


uni.addInterceptor('request', {
    invoke(args) {
        // request 触发前拼接 url 
        args.url = 'https://www.example.com/' + args.url
    },
    success(args) {
        // 请求成功后,修改code值为1
        args.data.code = 1
    },
    fail(err) {
        console.log('interceptor-fail', err)
    },
    complete(res) {
        console.log('interceptor-complete', res)
    }
})

uni.addInterceptor({
    returnValue(args) {
        // 只返回 data 字段
        return args.data
    }
})

# uni.removeInterceptor(STRING)

删除拦截器

# STRING 参数说明

需要删除拦截器的api名称

# 示例


uni.removeInterceptor('request')

注意

拦截uni.switchTab本身没有问题。但是在微信小程序端点击tabbar的底层逻辑并不是触发uni.switchTab。所以误认为拦截无效,此类场景的解决方案是在tabbar页面的页面生命周期onShow中处理。

上次更新: 5/20/2023, 1:50:07 PM