西瓜音乐小程序开发第二天

222 阅读2分钟
  • ✅引入第三方UI库vant
  • ✅封装banner请求
  • ✅实时获取组件高度解决不同屏幕中的swiper样式问题
  • ✅使用节流函数优化性能
  • 今日完成效果

\

引入vantUI库

步骤如下

  1. 第一步进入微信开发工具,点开详情,勾选使用npm模块,并调低基础库,由于当前测试基础库2.22.0无法正常显示vant中的van-search标签,遂调低基础库至2.21.2

  1. 打开终端,初始化package.json并且安装vant依赖 npm i @vant/weapp

\

  1. 点击工具菜单中的构建npm,等待构建完成,自动产生miniprogram_npm这就是小程序依赖的包

  1. 最后删除app.json中的style:v2防止样式冲突

使用第三方UI库

  1. pages/home-music/index.json中导入需要的search组件
{
  "usingComponents": {
    "van-search": "@vant/weapp/search/index"
  }
}
  1. pages/home-music/index.wxml中使用search组件
<!--pages/home-music/index.wxml-->
<!-- 搜索框 -->
<van-search disabled  placeholder="搜索您喜欢的歌曲" background="#fafafa" shape="round" bind:click-input="handleSearchClick" />
  • 这里使搜索框无法输入,绑定了点击方法,使用户点击搜索框跳转到搜索页面,index.js中实现方法即可,shape属性可以设置为圆角或者方角
 /**
   * 事件处理
   */
  handleSearchClick: function () {
    wx.navigateTo({
      url: "/pages/detail-search/index",
    });
  },
  • 效果如图

\

封装banner请求

新建service/api_music.js

import hyRequest from "./index";
export function getBanners() {
  return hyRequest.get("/banner", {
    type: 2,
  });
}
  • type的值有四种:0 代表PC 1代表Android 2代表Iphone 3代表pad

\

请求数据并渲染到页面

  1. 根据官方文档可知,可以通过以下示例获得每次渲染完成的组件的rect

  1. 新建utils/query-rect.js用以获取组件高度
export default function (selector) {
  return new Promise((resolve) => {
    // 获取图片的高度(如何获取组件高度)
    const query = wx.createSelectorQuery();
    query.select(selector).boundingClientRect();
    query.exec((res) => {
      resolve(res);
    });
  });
}
  1. pages/home-music/index.js中定义数据和方法,并调用
// pages/home-music/index.js
import { getBanners } from "../../service/api_music";
import queryRect from "../../utils/query-rect";
import throttle from "../../utils/throttle";

const throttleQueryRect = throttle(queryRect);

Page({
  /**
   * 页面的初始数据
   */
  data: {
    swiperHeight: 0,
    banners: {},
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.getPageData();
  },

  /**
   * 事件处理
   */
  handleSearchClick: function () {
    wx.navigateTo({
      url: "/pages/detail-search/index",
    });
  },
  /**
   * 网络请求
   */
  getPageData: function () {
    getBanners().then((res) => {
      this.setData({ banners: res.banners });
    });
  },

  handleSwiperImageLoaded: function () {
    // 获取图片的高度
    throttleQueryRect("#swiper-img").then((res) => {
      const rect = res[0];
      this.setData({
        swiperHeight: rect.height,
      });
    });
  },
})
  1. pages/home-music/index.wxml中调用数据,并绑定image加载完成的方法bindonload
<!--pages/home-music/index.wxml-->
<!-- 搜索框 -->
<van-search disabled  placeholder="搜索您喜欢的歌曲" background="#fafafa" shape="round" bind:click-input="handleSearchClick" />

<!-- 轮播图 -->
<swiper class="swiper" style="height:{{swiperHeight}}" indicator-dots autoplay circular>
  <block wx:for="{{banners}}" wx:key="bannerId">
    <swiper-item class="swiper-item" >
      <image id="swiper-img" class="image" mode="heightFix" src="{{item.pic}}"  bindload="handleSwiperImageLoaded" />
    </swiper-item>
  </block>
</swiper>

参数说明:

  • circular无限滑动
  • mode高度自适应
  • bindloadimage标签加载完成时执行
  • indicator-dots显示小圆点

上面用到的节流函数

utils/throttle.js

export default function throttle(
  fn,
  interval = 1000,
  options = { leading: true, trailing: false }
) {
  // 1.记录上一次的开始时间
  const { leading, trailing, resultCallback } = options;
  let lastTime = 0;
  let timer = null;

  // 2.事件触发时, 真正执行的函数
  const _throttle = function (...args) {
    return new Promise((resolve, reject) => {
      // 2.1.获取当前事件触发时的时间
      const nowTime = new Date().getTime();
      if (!lastTime && !leading) lastTime = nowTime;

      // 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数
      const remainTime = interval - (nowTime - lastTime);
      if (remainTime <= 0) {
        if (timer) {
          clearTimeout(timer);
          timer = null;
        }

        // 2.3.真正触发函数
        const result = fn.apply(this, args);
        if (resultCallback) resultCallback(result);
        resolve(result);
        // 2.4.保留上次触发的时间
        lastTime = nowTime;
        return;
      }

      if (trailing && !timer) {
        timer = setTimeout(() => {
          timer = null;
          lastTime = !leading ? 0 : new Date().getTime();
          const result = fn.apply(this, args);
          if (resultCallback) resultCallback(result);
          resolve(result);
        }, remainTime);
      }
    });
  };

  _throttle.cancel = function () {
    if (timer) clearTimeout(timer);
    timer = null;
    lastTime = 0;
  };

  return _throttle;
}

\

其他: