原生小程序第三方插件和api

157 阅读6分钟

头像昵称填写

当小程序需要让用户完善个人资料时,可以通过微信提供的头像昵称填写能力快速完善。

昵称填写

需要将 input 组件 type 的值设置为 nickname,当用户在此input进行输入时,键盘上方会展示微信昵称。

头像选择

需要将 button 组件 open-type 的值设置为 chooseAvatar,当用户选择需要使用的头像之后,可以通过 bindchooseavatar 事件回调获取到头像信息的临时路径。

然后调用

wx.uploadFile(文件上传)

 wx.uploadFile({
      url: wx.http.baseURL + '/upload',  // 文档约定的文件上传的地址
      filePath: avatar,      // 回调中本地文件的位置地址(临时的http打头的地址)
      name: 'file',  // wx.uploadFile 要求必传。
      header: {      // 文档约定。 上传头像要携带token
        Authorization: 'Bearer ' + token // 用户登录状态
      },
      formData: { 												// 接口文档的要求。可以不传
        type: 'avatar'
      },
      success: (result) => { 
          //上传成功后打印
        console.log(result)
          // 传回JSON格式进行转换
        const res = JSON.parse(result.data)
          // 将转换后的地址存入本地头像的变量中即可
      }
    })

token无感刷新

token会过期,为啥?

简单两个字:安全

token过期了怎么办?

  1. 让用户重新登录。后台管理系统会这么做。
  2. 使用refreshToken做无感刷新

如何使用 refreshToken 做无感刷新

在响应拦截器中,判断请求A错误是否 401 ?

  1. 用refreshToken去请求某个接口(后端约定的),得到新的token和refreshToken 保存下来

  2. 用新token重新发 请求A 此时用户没有感知到错误。network面板中可以看到三个请求

请求A 401 → 2. refreshToken → 3. 请求A 正常

改进: 用refreshToken去请求某个接口也可能会报401!!!

在响应拦截器中,判断请求A错误是否 401 ?

是,

请求A是refreshToken?

回到login(同时携带当前页面路径),让用户重新登录,可以回到原来的位置

用refreshToken去请求某个接口(后端约定的),得到新的token和refreshToken 1. 保存下来 1. 用新token重新 发请求A 此时用户没有感知到错误。network面板中可以看到三个请求

请求A 401 → 2. refreshToken → 3. 请求A 正常

表单校验

自己写校验比较麻烦我们可以利用第三方插件 wechat-validate 来完成:

安装

npm install wechat-validate

使用说明:wechat-validate

// 在页面或组件中导入
import validate from 'wechat-validate'

Page({
  // 通过 behaviors 注入 validate 方法
  behaviors: [validate],
  data: {
    username: '张三',
    password: '666666'
  },
  // 定义表单数据的验证规则
  rules: {
    mobile: [
      { required: true, message: '请填写手机号码!' },
      { pattern: /^1[3-8]\d{9}$/, message: '请检查手机号码是否正确!' },
    ],
    code: [
      { required: true, message: '请填写短信验证码!' },
      { pattern: /^\d{6}$/, message: '请检查短信验证码是否正确!' }
    ]
  },

  getCode() {
    // 单独只验证 mobile 这个数据
    const { valid, dataKey, message } = this.validate('mobile')
    if(!valid) wx.showToast({title: message, icon: 'none'})

    // else do something
  },

  sendForm() {
    // 验证码 rules 中定义的全部数据
    const isAllValid = this.validate()
    if(!isAllValid) return

    // else request api
  }
})

发送请求

wx.request用着不习惯? 可以试试第三方插件: wechat-http

安装

npm install wechat-http

使用说明

import http from 'wechat-http'

// 接口基础地址
http.baseURL = 'https://your.host.com'

// 请求拦截器
http.intercept.request = (options) => {
  // 指定默认的头信息
  const defaultHeader: AnyObject = {} //二挑一
  const defaultHeader = {} //二挑一
  // 权限认证
  defaultHeader.Authorization = 'Bearer token'
  // 合并头信息
  options.header = Object.assign({}, defaultHeader, options.header)
  // 拦截器处理后的请求参数
  return options
}

// 响应拦截器
http.intercept.response = ({ statusCode, data, config }) => {
  console.log(statusCode) // http 响应状态码
  console.log(config) // 发起请求时的参数
  // 拦截器处理后的响应结果
  return data
}

// 挂载到 wx 全局命名空间
wx.http = http

// 也可作为模块导出
export default http

快捷方法

// GET 方法请求
http.get(url, data?)

// POST 方法请求
http.post(url, data?)

// PUT 方法请求
http.put(url, data?)

// DELETE 方法请求
http.delete(url, data?)

示例

Page({
  async onLoad() {
    await wx.http({url: '/path', methods: 'POST'})
    // 或快捷方法
    await wx.http.get('/path')
  }
})

TypeScript 支持

import type { Http } from 'wechat-http'

// 扩展到全局对象 wx 中调用
declare global {
  namespace WechatMiniprogram {
    interface Wx {
      http: Http
    }
  }
}

// 自定义业务接口返回数据的类型
declare module 'wechat-http' {
  export interface ResponseResultData<T = any> {
    code: number
    message: string
    data: T
  }
}

wx.chooseMedia (拍摄或从手机相册中选择图片或视频)

const res = await wx.chooseMedia({ // 拍摄或从手机相册中选择图片或视频。
      count: 1,  // 图片上传数量 取值为1-9
      mediaType: ['Image'],   
// 上传文件类型 image 只能拍摄图片或从相册选择图片
// video 只能拍摄视频或从相册选择视频
// mix 可同时选择图片和视频
      sizeType: ['compressed']
      // 是否压缩所选文件 // compressed 压缩文件 //original 原始文件
    })

使用腾讯位置服务

  1. 申请开发者密钥(key):申请密钥

  2. 开通webserviceAPI服务:控制台 ->应用管理 -> 我的应用 ->添加key-> 勾选WebServiceAPI -> 保存

    (小程序SDK需要用到webserviceAPI的部分服务,所以使用该功能的KEY需要具备相应的权限)

  3. 下载微信小程序JavaScriptSDK,微信小程序JavaScriptSDK v1.1   JavaScriptSDK v1.2

  4. 安全域名设置,在小程序管理后台 -> 开发 -> 开发管理 -> 开发设置 -> “服务器域名” 中设置request合法域名,添加apis.map.qq.com

  5. 可以选择单独创建文件导入导出

import QQMAP from '../libs/qqmap-wx-jssdk' // 下载的JavaScriptSDK路径

export default new QQMAP({
  key: 'RCJBZ-EZACV-HE4P7-5P6J2-SCZIK-IVFDU', // 创建文件是就把KEY值填写好 这样复用是不用来回寻找KEY值
})
// 导入位置服务实例
import QQMap from '../../../utils/qqmap'

Page({
  onLoad() {
    // 获取用户经纬度
    this.getLocation()
  },

  // 获取用户的位置
  async getLocation() {
    // 调用小和序 API 获取用户位置
    const { latitude, longitude } = await wx.getLocation()
    this.getPoint(latitude, longitude)
    console.log('终点位置:', latitude, longitude)
  },

  getPoint(latitude, longitude) {
    // 逆地址解析(根据经纬度来获取地址)
    QQMap.reverseGeocoder({ //提供由坐标到坐标所在位置的文字描述的转换。输入坐标返回地理位置信息和附近poi列表
      keyword: '', //搜索关键词
      location: [latitude, longitude].join(','),
      success: result => {
        // console.log(result)
        // 过滤掉多余的数据
        const points = result.data.map(({ id, title, _distance }) => {
          return { id, title, _distance }
        })
        // 渲染数据
        this.setData({ points })
      },
    })
  }
})

wx.getLocation (获取当前的地理位置、速度)

示例代码

wx.getLocation({
 type: 'wgs84',
 success (res) {
   const latitude = res.latitude
   const longitude = res.longitude
   const speed = res.speed
   const accuracy = res.accuracy
 }
})

或 (解构赋值)

async getLocation() {
    const {latitude, longitude} = await wx.getLocation()
    console.log(latitude, longitude)
}

wx.chooseLocation (打开地图选择位置)

使用方法直接调用即可(同上)

腾讯位置路线规划

 onLoad({id}) {
    console.log('保修id', id)
    
    // const QQMAP = new QQMAP({
    //    key: 'RCJBZ-EZACV-HE4P7-5P6J2-SCZIK-IVFDU' // 必填
    //  })
    
     QQMAP.direction({
      mode: 'driving',
      
      //路线规划选择,可选值:'driving'(驾车)、'walking'(步行)、'bicycling'(骑行),不填默认:'driving',可不填
    
      from: '30.59982,114.3096',
       //from参数不填默认 当前地址
        
      to: '30.69982,114.2096', 
      // to 位置坐标,去哪
      
      success: (res) => {
(官网为 function 则这里改动为箭头函数 需注意this的填写)
        console.log(res, '地图回调');
        // console.log(res.result.routes[0].polyline, '地图回调');
        var ret = res;
        var coors = ret.result.routes[0].polyline, pl = [];
        //坐标解压(返回的点串坐标,通过前向差分进行压缩)
        var kr = 1000000;
        for (var i = 2; i < coors.length; i++) {
          coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
        }
        //将解压后的坐标放入点串数组pl中
        for (var i = 0; i < coors.length; i += 2) {
          pl.push({ latitude: coors[i], longitude: coors[i + 1] })
        }
        console.log(pl, '地图成功回调')
        //设置polyline属性,将路线显示出来,将解压坐标第一个数据作为起点
        this.setData({
          latitude:pl[0].latitude,
          longitude:pl[0].longitude,
          polyline: [{
            points: pl,
            color: '#FF0000DD',
            width: 4
          }]
        })
      },