加载中...

微信小程序的学习(微信开发者工具)


微信小程序的学习(微信开发者工具)

缓存优化

如果我们返回的数据量过于大了,可以使用微信的缓存来优化

首先在我们定义请求的函数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 // 保存数据
           })
    })
}

如果希望使用asyncawait的话,我们需要勾选小程序的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
  },

文章作者:
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 !