小程序系统API调用

news/2024/7/20 1:31:41 标签: 微信小程序, 小程序, 前端, 学习

目录:

1 网络请求API和封装

2 展示弹窗和页面分享

3 设备信息和位置信息

4 小程序Storage存储

5 页面跳转和数据传递

6 小程序登录流程演练

小程序的网络请求,不管是post还是get的请求的数据都是写在data里面的。

网络请求一般写在onLoad()的页面生命周期里面。

网络请求原生的写法是使用回调函数获取的数据,会有回调地狱,所以我们需要使用promise的写法。

回调地狱就是下图,回调里面有很多回调

注意:小程序>微信小程序在进行网络请求的时候,在测试阶段我们可以在详情的本地设置开启不校验合法域名和web-view。。。的选项就可以直接访问网址内容了。

但是需要上线小程序的时候,我们需要把这个获取data的网址在小程序>微信小程序登录后台-》开发管理-》开发设置-》服务器域名  才能正常使用网络请求。原因是小程序需要验证该网址是否发送的是合法的数据。具体配置方法最下方ppt有

 在使用网络请求之前,我们可以封装好request的代码,步骤是创建个server文件,在index.js里面写入我们需要的代码。

// 封装成函数
export function hyRequest(options) {
  return new Promise((resolve, reject) => {
    wx.request({ 
      ...options, 
      success: (res) => {
        resolve(res.data)
      },
      fail: reject
    })
  })
}

// 封装成类 -> 实例
class HYRequest {
  constructor(baseURL) {
    this.baseURL = baseURL
  }
  request(options) {
    const { url } = options
    return new Promise((resolve, reject) => {
      wx.request({
        ...options,
        url: this.baseURL + url,
        success: (res) => {
          resolve(res.data)
        },
        fail: (err) => {
          console.log("err:", err);
        }
      })
    })
  }
  get(options) {
    return this.request({ ...options, method: "get" })
  }
  post(options) {
    return this.request({ ...options, method: "post" })
  }
}

export const hyReqInstance = new HYRequest("http://codercba.com:1888/api")
export const hyLoginReqInstance = new HYRequest("http://123.207.32.32:3000")

如果使用的是await/acyna的方法来写网络请求,那么在await之后的js代码都不会运行。建议还是使用promise方法写网络请求。就是在生命周期onLoad里面写网络请求。

还可以使用异步函数的方法写请求,即在onLoad生命周期之外写await/acyna的网络请求。在onload生命周期里面直接调用该异步函数不会影响后续代码运行。

网络请求封装成类,扩展性更强。

使用网络请求的页面js逻辑:

// pages/09_learn_api/index.js
import { hyRequest, hyReqInstance } from "../../service/index"

Page({
  data: {
    allCities: {},
    houselist: [],
    currentPage: 1
  },
  async onLoad() {
    // 1.网络请求基本使用
    // wx.request({
    //   url: "http://codercba.com:1888/api/city/all",
    //   success: (res) => {
    //     const data = res.data.data
    //     this.setData({ allCities: data })
    //   },
    //   fail: (err) => {
    //     console.log("err:", err);
    //   }
    // })

    // wx.request({
    //   url: 'http://codercba.com:1888/api/home/houselist',
    //   data: {
    //     page: 1
    //   },
    //   success: (res) => {
    //     const data = res.data.data
    //     this.setData({ houselist: data })
    //   }
    // })

    // 2.使用封装的函数
    // hyRequest({ 
    //   url: "http://codercba.com:1888/api/city/all" 
    // }).then(res => {
    //   this.setData({ allCities: res.data })
    // })

    // hyRequest({
    //   url: "http://codercba.com:1888/api/home/houselist",
    //   data: {
    //     page: 1
    //   }
    // }).then(res => {
    //   this.setData({ houselist: res.data })
    // })

    // 3.await/async
    // const cityRes = await hyRequest({ 
    //   url: "http://codercba.com:1888/api/city/all" 
    // })
    // this.setData({ allCities: cityRes.data })

    // const houseRes = await hyRequest({
    //   url: "http://codercba.com:1888/api/home/houselist",
    //   data: { page: 1 }
    // })
    // this.setData({ houselist: houseRes.data })

    // 4.将请求封装到一个单独函数中(推荐)
    this.getCityData()
    this.getHouselistData()

    // 5.使用类的实例发送请求
    hyReqInstance.get({
      url: "/city/all"
    }).then(res => {
      console.log(res);
    })
  },

  async getCityData() {
    const cityRes = await hyRequest({ 
      url: "http://codercba.com:1888/api/city/all" 
    })
    this.setData({ allCities: cityRes.data })
  },
  // 下面的函数是下拉加载更多。
  async getHouselistData() {
    const houseRes = await hyRequest({
      url: "http://codercba.com:1888/api/home/houselist",
      data: { page: this.data.currentPage }
    })
    const finalHouseList = [...this.data.houselist, ...houseRes.data]
    this.setData({ houselist: finalHouseList })
    // 思考: 为什么这里不需要setData?
    // 因为这里的数据不需要浏览器来响应式更新
    this.data.currentPage++
  },

  //触底时触发函数
  onReachBottom() {
    this.getHouselistData()
  }
})

wxml:

<!--pages/09_learn_api/index.wxml-->
<view class="house-list">
  <block wx:for="{{houselist}}" wx:key="abc">
    <view class="item">
      <image src="{{item.data.image.url}}"></image>
      <view class="title">{{item.data.houseName}}</view>
    </view>
  </block>
</view>

4种常见弹窗,文档最下方PPT有具体的参数配置。

wx.showToast(Object object) | 微信开放文档 (qq.com)https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showToast.htmlwx.showModal(Object object) | 微信开放文档 (qq.com)https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showModal.htmlwx.showActionSheet(Object object) | 微信开放文档 (qq.com)https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showActionSheet.html

关于分享功能的配置:

获取用户设备信息:

设备信息里面有用户屏幕大小信息,

获取用户的位置:

1、先调用api

wx.getLocation(Object object) | 微信开放文档 (qq.com)https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.getLocation.html

这里需要用户授权才能获取。

2、获取用户授权的提示需要在app.json里面配置permission

全局配置 | 微信开放文档 (qq.com)https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#permission

 数据缓存:

分为同步和异步两种,同步的就是必须执行完一行才能在执行下下一行的代码;异步是不会影响后续代码执行,可以先执行后续的内容。

存储数据的时候可以设置加密选项,在取数据的时候也相应的需要使用加密选项才能解密获取具体数据。加密是有基础库最低版本限制,

wx.setStorageSync(string key, any data) | 微信开放文档 (qq.com)https://developers.weixin.qq.com/miniprogram/dev/api/storage/wx.setStorageSync.html上述api的使用示例:

js文件:

// pages/10_learn_api/index.js
Page({
  // 1.弹窗相关的API
  onShowToast() {
    wx.showToast({
      title: '购买失败!',
      icon: "error",
      duration: 5000,
      mask: true,
      success: (res) => {
        console.log("res:", res);
      },
      fail: (err) => {
        console.log("err:", err);
      }
    })

    // wx.showLoading({
    //   title: "加载中ing"
    // })
  },
  onShowModal() {
    wx.showModal({
      title: "确定购买吗?",
      content: "确定购买的话, 请确定您的微信有钱!",
      confirmColor: "#f00",
      cancelColor: "#0f0",
      success: (res) => {
        if (res.cancel) {
          console.log("用户点击取消");
        } else if (res.confirm) {
          console.log("用户点击了确定");
        }
      }
    })
  },
  onShowAction() {
    wx.showActionSheet({
      itemList: ["衣服", "裤子", "鞋子"],
      success: (res) => {
        console.log(res.tapIndex);
      },
      fail: (err) => {
        console.log("err:", err);
      }
    })
  },

  // 2.分享功能
  onShareAppMessage() {
    return {
      title: "旅途的内容",
      path: "/pages/favor/favor",
      imageUrl: "/assets/nhlt.jpg"
    }
  },

  // 3.获取用户的设备信息
  onGetSystemInfo() {
    // 1.获取手机的基本信息
    // wx.getSystemInfo({
    //   success: (res) => {
    //     console.log(res);
    //   }
    // })

    // 2.获取当前的位置信息
    wx.getLocation({
      success: (res) => {
        console.log("res:", res);
      }
    })
  },

  // 4.本地存储方式
  onLocalStorage() {
    // 1.存储一些键值对
    // wx.setStorageSync('name', "why")
    // wx.setStorageSync('age', 18)
    // wx.setStorageSync('friends', ["abc", "cba", "nba"])

    // 2.获取storage中内容
    // const name = wx.getStorageSync('name')
    // const age = wx.getStorageSync('age')
    // const friends = wx.getStorageSync('friends')
    // console.log(name, age, friends);

    // 3.删除storage中内容
    // wx.removeStorageSync('name')

    // 4.清空storage中内容
    // wx.clearStorageSync()

    // 异步操作
    wx.setStorage({
      key: "books",
      data: "哈哈哈",
      // 加密操作
      encrypt: true,
      success: (res) => {
        wx.getStorage({
          key: "books",
          encrypt: true,
          success: (res) => {
            console.log(res);
          }
        })
      }
    })

    console.log("-------");
  }
})

wxml:

<!--pages/10_learn_api/index.wxml-->
<text>pages/10_learn_api/index.wxml</text>

<!-- 1.展示弹窗 -->
<view>
  <button size="mini" bindtap="onShowToast">showToast</button>
  <button size="mini" bindtap="onShowModal">showModal</button>
  <button size="mini" bindtap="onShowAction">showAction</button>
</view>


<!-- 3.设备信息 -->
<button bindtap="onGetSystemInfo">设备信息</button>

<!-- 4.本地存储 -->
<button bindtap="onLocalStorage">本地存储</button>

 页面跳转:

页面跳转需要传递参数和跳转到的页面需要接收数据;返回之前页面的方法,返回之前页面并且传递参数过去。

 难点:返回之前页面并且传递参数过去。

第一种方法是通过页面栈的方法获取上一个页面的实例,然后取修改data里面的参数即可。这个代码是可以写在页面被卸载的时候执行的。因为如果你只通过按钮 返回 才能返回上一个页面和执行传递参数,页面导航的箭头 < 也是返回上一个页面,但是不会执行传递参数的代码。这时候把返回上一个页面并传递参数的方法写在生命周期卸载页面时执行最好。

第二种方法是通过给跳转之前的页面写一个事件频道event,跳转到的页面需要传递参数回跳转之前的页面需要通过获取事件event来传递。具体看下图:

跳转之前的页面js:

// pages/11_learn_nav/index.js
Page({
  data: {
    name: "kobe",
    age: 30,
    message: "哈哈哈"
  },
  onNavTap() {
    const name = this.data.name
    const age = this.data.age

    // 页面导航操作
    wx.navigateTo({
      // 跳转的过程, 传递一些参数过去
      url: `/pages2/detail/detail?name=${name}&age=${age}`,
      events: {
        backEvent(data) {
          console.log("back:", data);
        },
        coderwhy(data) {
          console.log("why:", data);
        }
      }
    })
  }
})

跳转之前的页面wxml:

<!--pages/11_learn_nav/index.wxml-->
<button bindtap="onNavTap">跳转</button>
<navigator class="nav" url="/pages2/detail/detail?name=why&age=18">跳转</navigator>

<view>{{message}}</view>

跳转到的页面js:

// pages2/detail/detail.js
Page({
  data: {
    name: "",
    age: 0
  },

  // 从别的页面跳转过来的数据需要从生命周期onLoad里面获取
  onLoad(options) {
    console.log(options);
    const name = options.name
    const age = options.age
    this.setData({ name, age })

    // const eventChannel = this.getOpenerEventChannel()
  },

  onBackTap() {
    // 1.返回导航
    wx.navigateBack()

    // 2.方式一: 给上一级的页面传递数据
    // 2.1. 获取到上一个页面的实例
    // const pages = getCurrentPages()
    // const prePage = pages[pages.length-2]

    // // 2.2.通过setData给上一个页面设置数据
    // prePage.setData({ message: "呵呵呵" })

    // 3.方式二: 回调events的函数
    // 3.1. 拿到eventChannel
    const eventChannel = this.getOpenerEventChannel()

    // 3.2. 通过eventChannel回调函数
    eventChannel.emit("backEvent", { name: "back", age: 111 })
    eventChannel.emit("coderwhy", { name: "why", age: 10 })
  },
  onUnload() {
    // // 2.1. 获取到上一个页面的实例
    // const pages = getCurrentPages()
    // const prePage = pages[pages.length-2]

    // // 2.2.通过setData给上一个页面设置数据
    // prePage.setData({ message: "呵呵呵" })
  }
})

跳转到的页面wxml:

<!--pages2/detail/detail.wxml-->
<text>pages2/detail/detail.wxml</text>
<view>name: {{name}}, age: {{age}}</view>
<button size="mini" type="primary" bindtap="onBackTap">返回</button>
<navigator open-type="navigateBack">返回</navigator>

小程序的登录解析:

静默登录:

由于小程序是在微信上的,所以没有账号密码的登录过程。

这里是通过openID来知道用户即使是使用不同的手机进行登录小程序也是同一个人。但是现在小程序不提供这个了。

unionID是用来判断不同微信产品之间用户是同一个人。

前端的任务就是通过api login获取code,等后端发token然后保存起来,在之后操作中发送token就好了。

登录页面的js:

import { getCode } from "../../service/login";
import { hyLoginReqInstance } from "../../service/index"

// pages/12_learn_login/index.js
Page({
  // onLoad登录的流程
  async onLoad() {
    // 1.获取token, 判断token是否有值
    const token = wx.getStorageSync('token') || ""

    // 2.判断token是否过期
    const res = await hyLoginReqInstance.post({
      url: "/auth",
      header: {
        token: token
      }
    })
    // console.log(res);

    // 2.如果token有值
    if (token && res.message === "已登录") {
      console.log("请求其他的数据");
    } else {
      this.handleLogin()
    }
  },

  async handleLogin() {
    // 1.获取code
    const code = await getCode()

    // 2.使用code换取token
    const res = await hyLoginReqInstance.post({
      url: "/login",
      data: { code }
    })

    // 3.保存token
    wx.setStorageSync('token', res.token)
  }

  // handleLogin() {
  //   // 1.获取code
  //   wx.login({
  //     success: (res) => {
  //       const code = res.code

  //       // 2.将这个code发送自己的服务器(后端)
  //       wx.request({
  //         url: "http://123.207.32.32:3000/login",
  //         data: {
  //           code
  //         },
  //         method: "post",
  //         success: (res) => {
  //           const token = res.data.token
  //           wx.setStorageSync('token', token)
  //         }
  //       })
  //     }
  //   })
  // }
})

login.js文件内容:


export function getCode() {
  return new Promise((resolve, reject) => {
    wx.login({
      success: (res) => {
        resolve(res.code)
      }
    })
  })
}

server文件夹下的index.js内容:

// 封装成函数
export function hyRequest(options) {
  return new Promise((resolve, reject) => {
    wx.request({ 
      ...options, 
      success: (res) => {
        resolve(res.data)
      },
      fail: reject
    })
  })
}

// 封装成类 -> 实例
class HYRequest {
  constructor(baseURL) {
    this.baseURL = baseURL
  }
  request(options) {
    const { url } = options
    return new Promise((resolve, reject) => {
      wx.request({
        ...options,
        url: this.baseURL + url,
        success: (res) => {
          resolve(res.data)
        },
        fail: (err) => {
          console.log("err:", err);
        }
      })
    })
  }
  get(options) {
    return this.request({ ...options, method: "get" })
  }
  post(options) {
    return this.request({ ...options, method: "post" })
  }
}

export const hyReqInstance = new HYRequest("http://codercba.com:1888/api")
export const hyLoginReqInstance = new HYRequest("http://123.207.32.32:3000")

 

 

 

 

 

 

 

 

 

 

 

 

 


http://www.niftyadmin.cn/n/211074.html

相关文章

数位统计DP

数位统计DP是一种模板性较强的DP套路题&#xff0c;主要用于对数字数位上的统计。在完成一些对数位上数字有明确要求的统计操作时&#xff0c;对区间内数字的暴力逐个枚举会产生大量无效工作&#xff0c;严重超时。 [ZJOI2010] 数字计数 题目描述 给定两个正整数 aaa 和 bbb…

DUET详解草稿

详解VLN动机&#xff1a;流程拓扑图Text EncoderCoarse-scale Cross-modal EncoderNode embeddingGraph-aware cross-modal encodingGlobal action predictionFine-scale Cross-modal EncoderVisual EmbeddingFine-grained cross-modal reasoningLocal action prediction and o…

k8s中部署etcd集群

Etcd是一个高可用的、开源的、分布式的Key/value存储系统&#xff0c;提供共享配置、服务的注册和发现、数据TTL失效、数据改变监视、多值、目录监听、分布式原子锁操作等功能。通常&#xff0c;k8s使用etcd进行数据存储&#xff0c;本文将部署etcd集群用做应用的存储。 一、前…

线下·重庆 | 阿木实验室×NOKOV度量 无人机软硬件开发平台

​第5859届中国高等教育博览会&#xff08;重庆&#xff09;中&#xff0c;阿木实验室将联合NOKOV度量 展示“ 基于NOKOV度量动作捕捉的高精度无人机软硬件开发平台 ”&#xff0c;该开发平台可支持无人机的数值仿真、PX4软件在环仿真、真机实验等多种实验模式。 演示本次展出中…

【vSphere | Python】vSphere Automation SDK for Python Ⅵ—— VM Guest Processes APIs

目录12. VM APIs12.1 VM Guest Processes APIsProcesses 进程Operations 操作&#xff08;1&#xff09;List Guest Processes&#xff08;2&#xff09;Get Guest Processes&#xff08;3&#xff09;Create Guest Processes&#xff08;4&#xff09;Delete Guest Processes参…

chatGPT 又来帮忙了

大家好啊&#xff0c;我是董董灿。 前几天chatGPT大封号&#xff0c;导致很多国内的账号不能登录了。 风口浪尖上&#xff0c;导致我也不太敢随意登录&#xff0c;登过几次&#xff0c;直接Ooooops了。 好几天没登录&#xff0c;今天又试了试&#xff0c;竟然发现出奇的顺畅&…

【linux】常用技巧

26.如何快速切换到用户John的主目录下&#xff1f; A. cd John B. cd #John C. cd &John D. cd ~John 答案&#xff1a;D 27.把一个流中所有字符转换成大写字符&#xff0c;可以使用下面哪个命令&#xff1f; A. tr a-z A-Z B. tac a-z A-Z C.sed /a-z/A-Z D. sed --touppe…

NIO非阻塞式网络通信实例

一、概述 1、NIO有三大核心部分&#xff1a;Channel(通道)&#xff0c;Buufer(缓存区)&#xff0c;Selector(选择器) Buffer缓存区 缓冲区本质上是一块可以写入数据&#xff0c;然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象&#xff0c;并提供了 一组方法&am…