微信小程序的学习(微信开发者工具)
缓存优化
如果我们返回的数据量过于大了,可以使用微信的缓存来优化
首先在我们定义请求的函数getList,在函数内部调用wx.setStorageSync
来将数据存储本地,存储的数据要携带时间信息:
//把接口的数据存起来
wx.setStorageSync(<要存储的数据名称>, { time: Date.now(), data: <需要存储的数据> })
//例如:
wx.setStorageSync('listData', { time: Date.now(), data: this.list })
在页面的onLoad
函数中需要提出存储的数据,对时间进行判断:
onLoad: function (options) {
// 提取存储的数据
const listData = wx.getStorageSync('listData')
// 判断
if (!listData) {
this.getList() // 没有存储的数据,就需要定义一个发送请求的函数去获取数据
} else {
if (Date.now() - listData.time > 1000 * 10) {
// 过期,重新发送请求
this.getList() // 数据过期,再次发送请求
} else {
// 数据获取成功,可以直接读取之前存储的数据
this.listData = listData.data
this.setData({
listData
})
}
}
},
接口封装
使用传统的wx.request
来请求接口,难免会遇到回调地狱的问题,在请求回来一个接口的时候去请求另一个接口,所以需要对请求进行一个封装,在项目新建一个request
的文件夹用于封装,在该文件夹下创建index.js
文件,书写下列代码:
// 同时发送异步代码的次数
let ajaxTimes = 0
export const request = (params) => {
// 如果需要添加一些需要验证token的请求接口,可以补充下列几行的代码
let header={...params.header}
// 如果接口携带含有home的字样就是需要验证token的
if(params.url.includes("/home/")){
// 在请求头添加Authorization,value的值为wx.setStorageSync保存好的token,需要与后端联系
header["Authorization"]=wx.getStorageSync("token");
}
ajaxTimes++
// 显示一个加载中的效果
wx.showToast({
title: '加载中',
icon: 'loading',
duration: 2000
})
// 定义公共的url
const baseUrl = <这里书写你需要请求的url的地址>
return new Promise((res, rej) => {
wx.request({
...params,
header,
url: baseUrl + params.url,
success: (result) => {
res(result.data.message)
},
fail: (err) => {
rej(err)
},
complete: () => {
ajaxTimes--
if (ajaxTimes === 0) {
wx.hideLoading()
}
}
})
})
}
使用方法
定义好请求的方法之后,需要引入刚刚写好的函数,调用即可:
// 例如
//引入封装异步请求的js代码
import { request } from '../../request/index.js'
getLists() {
request({
url: '/list' // 这里书写的是请求的地址
}).then((res) => {
this.setData({
list = res.data.message // 保存数据
})
})
}
如果希望使用async
,await
的话,我们需要勾选小程序的es6转es5,同时需要下载一个代码,代码地址:<regenerator/runtime.js at main · facebook/regenerator (github.com)>,复制js代码,在项目创建lib文件夹,在该文件夹创建runtime文件夹,在改文件夹下创建runtime.js
文件,将代码地址的代码复制粘贴到该文件夹下即可,有的版本会自己es7转es5,即可以不需要该js文件,使用方法:
//引入封装异步请求的js代码
import { request } from '../../request/index.js'
import regeneratorRuntime from '../../lib/runtime/runtime'
async getLists() {
const res = await request({
url: '/list' // 这里书写的是请求的地址
})
// 这里可以判断返回的code,这里就直接获取返回的数据了
this.setData({
list = res // 保存数据
})
}
自定义组件Tabs
在项目中往往会遇到类似于底部tabbar
的效果,只不过位于顶部区域,使用自定义的Tabs
配合插槽实现,该模块可以学习到插槽,自定义事件,我们需要在项目的components
文件夹下创建Tabs
自定义组件
在Tabs.js
文件夹下书写接收的数据信息:
// components/Tabs/Tabs.js
Component({
properties: {
tabs: {
type: Array,
value: []
}
},
methods: {
handItemTap(e) {
const { index } = e.currentTarget.dataset
this.triggerEvent('tabsItemChange', { index })
}
}
})
Tabs.wxml
的文件代码:
<view class="tabs">
<view class="tabs_title">
<view
class="title_item {{item.isActive?'active':''}}"
wx:for="{{tabs}}"
wx:key="id"
bindtap='handItemTap'
data-index="{{index}}"
>
{{item.value}}</view>
</view>
<view class="tabs_content">
<slot></slot>
</view>
</view>
Tabs.wxss
样式参考代码:
.tabs_title {
display: flex;
}
.title_item {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
padding: 15rpx 0;
}
.active {
color: var(--themeColor);
border-bottom: 5rpx solid currentColor;
}
这样我们的自定义组件就做好了,我们只需要在使用他的地方,引入,导入数据,绑定自定义事件即可
引入自定义组件,我们需要在使用到该自定义组件的index.json
文件下加入代码:
"usingComponents": {
"Tabs":"../../components/Tabs/Tabs"
}
我们需要创建好数据进行导入,在使用该组件的index.js
文件下的data创建数据:
data: {
tabs: [
{
id: 0,
value: '综合',
isActive: true
},
{
id: 1,
value: '销量',
isActive: false
},
{
id: 2,
value: '价格',
isActive: false
}
]
},
在使用该组件的index.wxml
文件下使用自定义组件:
<Tabs tabs="{{tabs}}" bindtabsItemChange="tabsItemChange">
<block wx:if="{{tabs[0].isActive}}">1</block>
<block wx:elif="{{tabs[1].isActive}}">2</block>
<block wx:else>3</block>
</Tabs>
绑定自定义事件,由自定义组件传递事件需要接收执行,所以还需要在index.js
文件添加需要执行的函数:
tabsItemChange(e) {
const { index } = e.detail
let { tabs } = this.data
tabs.forEach((v, i) => {
if (i === index) {
v.isActive = true
} else {
v.isActive = false
}
}),
this.setData({
tabs
})
},
只需要在不同的block标签书写响应的代码即可
页面滚动条触底
当我们在做列表的时候,肯定会遇到页面滚动条触底的事件,我们需要知道服务器返回的总条数通过计算,再结合周期函数处理:
// 定义默认数据
QueryParams: {
query: '', // 参数
id: '', // id
pagenum: 1, // 页码
pagesize: 10 // 每页展示的数据
},
// 总页数
totalPages: 1,
// 在我们获取列表的数据的时候需要保存好total
getList(){
... // 这里省略获取数据,详情见上方的接口封装和使用方法
const total = res.total
// 计算总页数
this.totalPages = Math.ceil(total / this.QueryParams.pagesize)
// 保存好数据
this.setData({
list: [...this.data.list, ...res.lists] // this.data.list是原有的数组,我们需要解构添加数据,res.lists是接口返回的数据,同样需要解构
})
// 关闭下拉刷新的窗口,如果没有调佣下拉刷新的窗口直接关闭也不会报错
wx.stopPullDownRefresh()
}
// 页面滚动条触底事件
onReachBottom() {
if (this.QueryParams.pagenum >= this.totalPages) {
wx.showToast({
title: '没有下一页数据了'
})
} else {
this.QueryParams.pagenum++ // 页码数++
this.getList() // 重新发送请求
}
},
下拉刷新
需要开启下拉刷新,我们需要在组件的index.json
文件添加开启下拉刷新的代码:
"enablePullDownRefresh":true,
"backgroundTextStyle": "dark" // 这里是选择刷新的样式,两种:dark/light
在页面的生命周期函数进行下拉刷新的逻辑书写:
// 下拉刷新事件
onPullDownRefresh() {
//重置数组
this.setData({
list: []
})
//重置页码
this.QueryParams.pagenum = 1
//发送请求
this.getList()
}
点击轮播图预览
在需要点击轮播图进行预览的时候就需要调用wx.previewImage
的Api,需要给遍历循环的轮播添加点击事件:
// 在index.wxml中给轮播添加点击事假
<swiper autoplay circular indicator-dots>
<swiper-item wx:for="{{goodsPics}}" wx:key="picsId" bindtap='handlePrevewImage' data-url='{{item.pics}}'>
<image mode="widthFix" src="{{item.pics}}"></image>
</swiper-item>
</swiper>
在index.js
书写代码:
//全局对象
GoodsInfo: [],
// 在我们获取到的数据的同时,将数据写入全局的对象
//点击轮播图预览
handlePrevewImage(e) {
//构建要预览的图片数组
const urls = this.GoodsInfo.map((v) => v.pics) // 遍历得到的数据,将图片的地址筛选出来
//接收传递传递过来的图片url
const current = e.currentTarget.dataset.url
wx.previewImage({
current,
urls
})
}
页面参数的获取
onShow
不同于onLoad
无法在形参上接收options
参数,如果我们需要参数,我们可以获取页面栈,该长度最长为10个页面,在onShow
调用函数:
onShow() {
let pages = getCurrentPages() //页面栈
// 数组中索引最大的就是当前页面,里面包含了传入过来的数据
let currentPages = pages[pages.length - 1]
const { type } = currentPages.options
},