5、小程序进阶二
本地存储
在小程序的开发当中,我们可能需要将某些数据存储在本地,比如Token数据、用户数据,所以小程序给我们专门提供了一个Storage来进行本地存储,主要提供了两类Storage的API,一种同步APi,一种异步API,同步可能存在阻塞的行为;
# 同步API
wx.setStorageSync(key,value):将数据存储到本地存储,value可以是任何JavaScript的合法类型;
wx.getStorageSync(key):从本地存储中获取指定key的值;
wx.removeStorageSync(key):从本地存储中移除指定key;
wx.clearStorageSync():清空本地存储;
# 异步API
wx.setStorage(object):将数据存储到本地存储;
wx.getStorage(object):从本地存储中获取指定key的值;
wx.removeStorage(object):从本地存储中移除指定key;
wx.clearStorage(object):清空本地存储;
同步API没什么好演示的,主要是异步这块,它们都接收一个对象,不同的API对象内都需要提供不通的属性,具体的请查看官方文档,同时,因为这些API都是一些异步API,所以它们也提供回调机制,内部可以通过success、fail和complete来实现回调通知,如下示例;
// pages/index/index.js
Page({
onReady() {
// 存储数据
wx.setStorage({
key: "name",
data: "cce",
success: (res) => console.log(res)
})
// 获取数据
wx.getStorage({
key: "name",
success: (res) => console.log(res)
})
// 删除数据
wx.removeStorage({
key: "name",
success: (res) => console.log(res)
})
// 清空数据
wx.clearStorage({
key: "name",
success: (res) => console.log(res)
})
}
})
网络请求
在小程序内,有一个专门的API用来实现网络请求,即wx.request,该API和Axios差不多,专门用来做网络请求,但是这里需要注意一个问题,小程序想要和后端服务器进行通信,那么必须先在微信公众平台中,设置通讯域名,且该域名必须支持HTTPS协议,在小程序后台的开发管理中,进入开发设置,填入相应的服务器域名即可;
当然,在开发过程中,我们对微信开发工具进行相应的设置,也是可以无需在微信公众平台中设置对应的域名,就能直接与后端接口通信,但是一旦小程序上线,对应同通讯域名的设置是必须的;
那么对于wx.request这个API来讲,它接收一个对象,该对象内,就是我们要发送请求的主体信息,如请求地址、请求头、请求参数等,如下表格;
属性
|
类型
|
默认值
|
说明
|
url
|
string
|
后端接口地址
|
|
data
|
string/object/arraybuffer
|
请求的参数
|
|
header
|
object
|
请求头,不能设置Referer,且content-type 默认为application/json
|
|
timeout
|
number
|
60000毫秒
|
超时时间,单位为毫秒
|
method
|
string
|
GET
|
HTTP请求方法
|
dataType
|
string
|
json
|
返回的数据格式
|
responseType
|
string
|
text
|
响应的数据类型
|
success
|
function
|
接口调用成功的回调函数
|
|
fail
|
function
|
接口调用失败的回调函数
|
|
complete
|
function
|
接口调用结束的回调函数(调用成功、失败都会执行)
|
对于wx.request API的使用其实没什么好说的,在学习过Axios之后,再看wx.request其实非常的简单,但是这里唯一需要注意的一点就是,在Axios中,request的query参数有专门的属性可以指定,但是在wx.request中,并没有提供query这个属性,那么在wx.request API中,如果希望使用query查询参数,可以直接把参数放在data属性内即可,如下示例;
// pages/index/index.js
Page({
data: {},
onLoad() {
wx.request({
url: 'http://127.0.0.1:8000/get_data/',
data: {
page: 1
}
})
}
})
成功回调
那么对于wx.request而言,它不支持Promise,它的回调方式是,通过参数对象内的success回调函数来实现的,那么对于这个success来讲,它是一个函数,该函数接收一个参数,这个参数里面就包含了后端服务器返回的数据,小程序在收到后端返回响应报文之后会封装一个对象,然后将这个对象作为参数传递给success函数,该对象内默认有以下属性;
属性
|
类型
|
说明
|
statusCode
|
number
|
服务器返回的 HTTP 状态码
|
data
|
string/object/arraybuffer
|
服务器返回的数据
|
header
|
object
|
服务器返回的 HTTP Response Header
|
cookies
|
Array.<string>
|
服务器返回的 cookies,格式为字符串数组
|
errMsg
|
string
|
错误信息
|
失败回调
同样的,对于fail回调函数来讲,它也接收一个对象,且该对象一般只有两个属性,如下示例;
属性
|
类型
|
说明
|
errMsg
|
string
|
错误信息
|
errno
|
number
|
errno错误码
|
请求参数
data是请求的参数,该请求参数,最终会以String的形式发送给服务端,如果传入的data不是String类型,会被转换成String,对于GET方法的数据,会将数据转换成query string,即encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...,对于POST方法且header['content-type']为application/json的数据,会对数据进行JSON序列化,对于POST方法且header['content-type']为application/x-www-form-urlencoded的数据,会将数据转换成query string encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...;
接口封装一
可以看到,小程序提供的网络请求的并不支持Promise,无法利用Promise给我们带来的各种高级特性,然而利用wx.request API依旧可能存在代码过于臃肿,无法解偶,甚至也可能存在回调地狱等各种问题,所以我们也可以对其进行进一步的封装使其支持Promise,如下示例;
[cce@doorta ~]# cat /usr/local/Project/wechat/uilts/axios.js
export function function_request(options) {
return new Promise((resolve, reject) => {
wx.request({
...options,
success: resolve,
fail: reject
})
})
}
[cce@doorta ~]# cat /usr/local/Project/wechat/pages/index/index.js
// pages/index/index.js
import function_request from "../../uilts/axios.js"
Page({
onLoad() {
function_request({
url: "http://127.0.0.1:8000/get_data"
}).then((res) => console.log(res.data))
}
})
接口封装二
可以看到,虽然我们使用了函数封装,但是依旧并不是非常的方便,比如,我们无法定义baseURL、content-type等信息,所以在这个时候,其实更加推荐使用面向对象的方式来封装接口,我们可以在构造器当中预先定义一些默认的配置,如下示例;
[cce@doorta ~]# cat /usr/local/Project/wechat/uilts/axios.js
class class_request {
constructor(baseURL) {
this.baseURL = baseURL;
}
request(options) {
const { url } = options;
const full_url = this.baseURL + url;
return new Promise((resolve, reject) => {
wx.request({
...options,
url: full_url,
success: resolve,
fail: reject
})
})
}
get(options) {
return this.request({ ...options, method: "get" })
}
post(options) {
return this.request({ ...options, method: "post" })
}
}
export default new class_request("http://127.0.0.1:8000")
[cce@doorta ~]# cat /usr/local/Project/wechat/pages/index/index.js
// pages/index/index.js
import request from "../../uilts/axios.js"
Page({
data: {},
onLoad() {
request.get({
url: "/get_data"
}).then((res) => console.log(res.data))
}
})
路由跳转
在真实的开发中,我们的小程序肯定不止一个页面,那么存在多个页面时,我们如何进行页面跳转,小程序也给我们的提供了相应的组件和API,两种方式实现,对于组件的方式,其实它就类似于Vue中的router-link,但是这个组件使用相对较少,一般进行页面跳转,大多数都是使用API的方式进行的;
组件跳转
在小程序内,提供了一个navigate组件,它不仅可以实现页面的跳转,也可以实现小程序间的跳转,所以该组件提供的参数也非常多,常用参数如下;
target:字符串类型,表示在哪个目标上发生跳转,默认为当前小程序;
url:字符串类型,指定要跳转到当前小程序内的哪个页面地址;
open-type:字符串类型,指明跳转的方式,是跳转页面,还是返回页面;
delta:数字类型,当open-type为navigateBack时,表示退回的层数;
app-id:字符串类型,当target为miniProgram时有效,表示要打开的小程序的app-id;
path:字符串类型,当target为miniProgram时有效,表示要打开的小程序的URL;
API跳转
对于API的方式实现跳转,小程序主要提供了五种跳转方式,分别适用不同的应用场景,同时,这些API都提供了success、fail和complete三个回调函数,这里唯一需要注意的是,以下所有的API,它们跳转的页面需要以"/"开头,如下;
wx.switchTab:跳转到tabBar页面,并关闭其他所有非tabBar页面,它要求跳转的url必须为tabBar;
wx.reLaunch:关闭所有页面,打开小程序内的某个页面;
wx.redirectTo:关闭当前页面,跳转到某个页面;
wx.navigateTo:保留当前页面,跳转到应用内的某个页面,可以返回到上一个页面;
wx.navigateBack:关闭当前页面,返回上一页面或多级页面;
对于它们的使用非常简单,这里唯一需要说明的就是参数传递,因为这些API都没有提供一个类似query的参数,所以在小程序内,如果想要实现页面跳转时进行参数传递,那么可以直接在URL中拼接query string即可,然后在跳转的页面,可以在onLoad钩子函数中拿到这个传递过来的数据,因为onLoad默认就接收一个参数,这个参数,就是进入本页面时URL上面的Query String参数,那么对于返回页面的参数传递,可以通过页面栈来实现,应用场景不多,不在此做过多的赘述,具体的请查看官方文档;