Skip to content
文章目录

根据以往经验预解决问题

UI 稿还原与响应式

WX 官方 rpx 介绍

px 与 rpx 转换

UI 稿宽高和字体大小还原

普通移动端项目通常使用 px 转 rem 来实现,不同屏幕分辨率设备的宽高兼容,开发时将浏览器调成设计稿的大小,在 css 中直接按照设计稿的尺寸写 px 即可,最终通过插件自动将 px 转换为 rem

WX 小程序使用 rpx 来实现不同硬件的宽高兼容,将设备屏幕宽度等分为 750 份,每份就是 1rpx。Iphone 6 的物理像素是 750, 和 WX 的 rpx 刚好是 1:1 关系,因此只要 UI 涉及稿的宽度是 750px,那前端就可以直接按照设计稿的 px 进行宽高以及字体大小的设置,如:设计稿中某个元素宽高是105px * 36px,那前端开发直接写105rpx * 36rpx即可,完全不需要换算

rpx -> px 之间的转换

rpx px 转换问题

sass-rpx WX 小程序开发 px -> rpx 转换

如果设计稿宽度不是 750 宽度的呢?

scss 中写一个处理 px 转化 rpx 的函数

_functions.scss

scss
// 1px对应多少个rpx, 下面设置的标识1px对应2个rpx.
$multiple: 2rpx;
// 转换函数 (15) ==> 30rpx (15,30) ==> 30rpx 60rpx
// 转换函数 params 可传参数 无上限
@function cover($t...) {
  $i: 1;
  $result: 0;
  @while $i <= length($t) {
    @if ($i == 1) {
      $result: (nth($t, $i) * $multiple);
    } @else {
      $result: append($result, (nth($t, $i) * $multiple));
    }
    $i: $i + 1;
  }
  @return $result;
}
scss
@use '../../scss/functions' as *;

// 使用 后面是编译结果
.title {
  width: cover(375); // width:750rpx;
  height: cover(10); // height:20rpx;
  padding: cover(10, 20, 30, 40); // padding:20rpx 40rpx 60rpx 80rpx;
  box-shadow: cover(0, 1, 16) rgba(56, 56, 71, 0.2); // box-shadow: 0 2rpx 16rpx rgba(56, 56, 71, 0.2);
}

scss 中写一个处理 px 转化 rpx 的函数

人工 rpx 和 px 互换

WX 小程序 - rpx 和 px 互转,以及系统给的 pixelRatio 值比例不对

WX 小程序——获取到 px 转化为 rpx(根据设备宽高动态设置元素宽高)

WX 小程序踩坑之旅(三):不同机型布局适配问题(rpx,px,vh,vw)

js
var pixelRatio1 = 750 / wx.getSystemInfoSync().windowWidth // 推荐

// rpx 转 px:
var px1 = rpx / pixelRatio1 // 推荐

// px 转 rpx:
var rpx1 = px * pixelRatio1 // 推荐

响应式

css 的 media query 在小程序中依旧是可用的

ajax 相关

跨域

如果使用的是wx.useRequest的话,不存在跨域问题,因为这相当于使用 WX 客户端进行请求转发,已经不是浏览器直接发起请求了,所以不存在跨域问题

如果使用的是第三方 ajax 请求插件,那就有可能存在跨域问题。跨域问题汇总与解决

第三方 ajax 请求插件跨域解决方案,简言之就是要么后端接口配置允许跨域,要么让 nginx 这类工具进行请求转发

超时

这里只针对使用wx.useRequest的情况

全局超时配置

app.json配置networkTimeout中的request

networkTimeout

特定接口超时配置

设置 timeout 参数

wx.request(Object object)

取消请求

RequestTask.abort()

WX 小程序中断请求的处理,中断 wx.request() 请求

缓存请求

文件上传,下载

文件上传:wx.uploadFile(Object object)

文件下载:wx.downloadFile(Object object)

兼容相关

wx api 与内置组件兼容

基础库:低版本兼容

获取客户端 SDK 版本, 并进行版本比较

js
const version = wx.getAppBaseInfo().SDKVersion

function compareVersion(v1, v2) {
  v1 = v1.split('.')
  v2 = v2.split('.')
  const len = Math.max(v1.length, v2.length)

  while (v1.length < len) {
    v1.push('0')
  }
  while (v2.length < len) {
    v2.push('0')
  }

  for (let i = 0; i < len; i++) {
    const num1 = parseInt(v1[i])
    const num2 = parseInt(v2[i])

    if (num1 > num2) {
      return 1
    } else if (num1 < num2) {
      return -1
    }
  }

  return 0
}

if (compareVersion(version, '1.1.0') >= 0) {
  wx.openBluetoothAdapter()
} else {
  // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
  wx.showModal({
    title: '提示',
    content: '当前WX版本过低,无法使用该功能,请升级到最新WX版本后重试。',
  })
}

判断新 API 在客户端的基础库中是否存在

方式一:canIUse 方式 (推荐)

wx.canIUse 用法

判断是否可使用某个 API

js
wx.showModal({
  success: function (res) {
    if (wx.canIUse('showModal.success.cancel')) {
      console.log(res.cancel)
    }
  },
})

判断是否可使用某个内置组件

js
Page({
  data: {
    canIUse: wx.canIUse('cover-view'),
  },
})
xml
<video controls="{{!canIUse}}">
  <cover-view wx:if="{{canIUse}}">play</cover-view>
</video>
方式二:直接判断方式
js
if (wx.openBluetoothAdapter) {
  wx.openBluetoothAdapter()
} else {
  // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
  wx.showModal({
    title: '提示',
    content: '当前WX版本过低,无法使用该功能,请升级到最新WX版本后重试。',
  })
}

特定品牌的机型

有时候就是在特定品牌的特定机型下有问题,那如何处理这种兼容问题?

wx.getSystemInfoSync 返回结果详解

app.scss编写指定品牌型号的全局样式或page.scss编写特定界面中指定品牌型号的局部样式

然后获取品牌brand和型号model,构建成品牌型号的 class 名称,再设置到对应元素上

设置小程序的最低基础版本

不到万不得已,不要限制最低版本

基础库:设置最低基础库版本

双向数据绑定

简易双向绑定

表单组件双向绑定

xml
<input model:value="{{value}}" />

自定义组件双向绑定

js
// custom-component.js
Component({
  properties: {
    myValue: String,
  },
})
xml
<!-- custom-component.wxml -->
<input model:value="{{myValue}}" />
xml
<custom-component model:my-value="{{pageValue}}" />

在自定义组件中触发双向绑定更新

js
// custom-component.js
Component({
  properties: {
    myValue: String,
  },
  methods: {
    update: function () {
      // 更新 myValue
      this.setData({
        myValue: 'leaf',
      })
    },
  },
})

事件处理

小程序:事件

常用的点击事件是bindtap

自定义事件传参

xml
<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>

通过data-xx="参数值"方式进行传参,如果有多个参数就写多个data-x1="x1值", data-x2="x2值"

js
Page({
  tapName: function (event) {
    console.log(event)
    const index = e.currentTarget.dataset['hi']
  },
})
json
{
  "type": "tap",
  "timeStamp": 895,
  "target": {
    "id": "tapTest",
    "dataset": {
      "hi": "Weixin"
    }
  },
  "currentTarget": {
    "id": "tapTest",
    "dataset": {
      "hi": "Weixin"
    }
  },
  "detail": {
    "x": 53,
    "y": 14
  },
  "touches": [
    {
      "identifier": 0,
      "pageX": 53,
      "pageY": 14,
      "clientX": 53,
      "clientY": 14
    }
  ],
  "changedTouches": [
    {
      "identifier": 0,
      "pageX": 53,
      "pageY": 14,
      "clientX": 53,
      "clientY": 14
    }
  ]
}

禁止事件冒泡

除 bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。

xml
<view id="middle" catchtap="handleTap2"></view>

顶部导航

动态修改标题 navigationBarTitleText

js
wx.setNavigationBarTitle({
  title: '新标题',
})

去掉自带的顶部导航

app.json

json
{
  "window": {
    "navigationStyle": "custom"
  }
}

自定义顶部导航栏

WX 小程序自定义 navigationBar 顶部导航栏,兼容适配所有机型

tabbar

配置 tabbar

小程序 tabar

小程序(三)配置 tabbar 及自定义 tabbar 样式

自定义 tabbar

小程序官方:自定义 tabBar

WX 小程序自定 tabbar(解决图标闪、解决任何界面都会出现 tabbar 的问题)

解决 WX 小程序 自定义 tabBar 切换时候闪烁问题

WX 小程序底部 tabbar 自定义 实现凸起+透明底部效果

其他杂项

es6 语法转 es5

WX 小程序开发 ES6 转 ES5 的深坑

选择指定元素

wx.createSelectorQuery

数据缓存

设置缓存:wx.setStorageSync(string key, any data)

获取缓存:wx.getStorageSync(string key)

删除缓存:wx.removeStorageSync(string key)

使用 npm 和第三方依赖(如: vantUI)

使用 npm 包

wechat vantUI 快速上手

小程序使用 vant-weapp(带 px 转 rpx 方法) :该文章最后有介绍最新版本通过定制主题的方式将 px 修改为 rpx

WX 小程序 引入 Vant Weapp 组件库,并将 px 转化成 rpx

WX 小程序 Vant 组件 px 转 rpx