小程序开发

1.小程序的结构

1.1应用程序的结构

  • 小程序结构划分:最上层App -> 多个page -> 多个组件在这里插入图片描述

1.2.应用目录的结构

  • 在这里插入图片描述

2.小程序的MVVM

  • vue的MVVM和小程序MVVM对比在这里插入图片描述
  • MVVM为什么好用:
    DOM Listeners:ViewModel层可以将DOM的监听绑定到Model层
    Data Bindings:ViewModel层可以将数据的变量、响应式的反应到View层
  • MVVM架构将我们从命令式编程转移到声明式编程

3.小程序架构和配置

3.1.project和sitemap

  • 小程序的很多开发需求被规定在了配置文件
  • 可以更有利于我们的开发效率,并且保证开发出来的小程序的某些风格是比较一致的,比如导航栏,顶部tabbar等等
  • 常见的配置文件:
    project.config.json:项目配置文件,比如项目名称、appid等
    sitemap.json:小程序搜索相关的
    app.json:全局配置,小程序的入口
    page.json:页面配置(eg.如果需要下拉刷新,则需要在对应的page.json中将设置打开:enablePullDownRefresh:true)

3.2.全局配置app.json

3.2.1.pages
  • pages:页面路径列表,用于指定小程序由哪些页面组成,每一项都对应一个页面的路径信息
  • 小程序中所有的页面都是必须在pages中进行注册的
  • 类型:string
3.2.2.window
  • 全局的默认窗口展示:用户指定窗口如何展示,其中还包含了很多其他的属性
  • 类型:Object
3.2.3.tabbar
  • 底部tab栏的表现
  • 类型:Object

格式化文档:alt+shift+F

3.3.局部配置page.json

  • 每一个小程序页面也可以使用.json文件来对本页面的窗口表现进行配置
  • 页面中配置项在当前页面会覆盖app.json的window中相同的配置项

3.4.小程序双线程模型

  • 微信客户端是小程序的宿主环境
  • 宿主环境为了执行小程序的各种文件:wxml文件、wxss文件,js文件,提供了小程序的双线程模型
  • 双线程模型:wxml模块和wxss样式运行于渲染层,渲染层使webview线程渲染(一个程序有多个页面,会使用多个webview的线程);
    js脚本运行于逻辑层,逻辑层使用jscore运行js脚本
    这两个线程都会经由微信客户端(Native)进行中转交互在这里插入图片描述
  • 数据发生改变:通过setData改变数据时,产生的js对象对应的节点就会发生改变,此时可以对比前后两个js对象得到变化的部分,然后把这个差异应用到原来的Dom树上,从而达到更新UI的目的,这就是“数据驱动”的原理

3.5.小程序的启动流程

  • 小程序的启动流程在这里插入图片描述

3.6.注册小程序App

3.6.1.注册小程序示例
  • 每个小程序都需要在app.js中调用App方法注册小程序示例
    在注册时,可以绑定对应的生命周期函数,在生命周期函数中,执行对应的代码在这里插入图片描述
  • onLaunch:小程序初始化完成时,会执行的生命周期函数(会在后台存活两个小时,两个小时内关掉再打开不会执行函数)
  • onShow:小程序界面显示出来之后会执行的生命周期函数
  • onHide:界面隐藏时执行 ,监听小程序切后台
  • onError:小程序中发生了一些错误时会执行
  • onPageNotFound:页面不存在时监听函数
3.6.2.注册App时做什么
  • 1.判断小程序的进入场景
    2.监听生命周期函数,在生命周期中执行对应的业务逻辑,比如在某个生命周期函数中获取微信用户的信息
    3.因为App()实例只有一个,并且是全局共享的(单例对象),所以我们可以将一些共享数据放在这里
小程序进入场景
  • 小程序的打开场景较多:会话中打开,小程序列表、微信扫一扫、另一个小程序打开;如何确定场景:在onLaunch和onShow生命周期回调函数中,会有options参数,其中有scene值
onShow(options) {
    switch(options.scene) {
      case 1001:
        break;
      case 1005:
        break;
    }
  }
获取用户信息—保存全局变量
  • 方式1:wx.getUserInfo
//可以在onShow里也可以在onLaunch里,onShow中则会调用的比较频繁
onShow() {
    wx.getUserInfo({
      success: function(res) {
        console.log(res);
      }
    })
  }
  • 方式2:button组件—将open-type改成getUserInfo,并且绑定bindgetuserinfo事件去获取
<button size="mini" open-type="getUserInfo"
bindgetuserinfo="handleGetUserInfo">获取授权</button>

//js文件中
    handleGetUserInfo(event) {
        console.log(event);
    }
  • 方式3:使用open-data组件展示用户信息
//展示用户名称
<open-data type="userNickName"></open-data>
//展示用户头像
<open-data type="userAvatarUrl"></open-data>
定义全局数据
  • app.js的globalData中定义的全局数据,可以在其他地方共享
  • 如何在其他地方使用:
//getApp获取App()产生的示例对象
const app = getApp()
const name = app.globalData.name;

3.7.注册页面Page

3.7.1注册page时做什么
  • 小程序中的每个页面,都有一个对应的js文件,其中调用page方法注册页面示例;
  • 在注册时,可以绑定初始化数据、生命周期回调、事件处理函数等
  • 一般需要做什么:
    生命周期函数中发送网络请求,从服务器获取数据
    初始化一些数据,以方便被wxml引用展示
    监听wxml中的事件,绑定对应的事件函数(点击…)
    其他一些监听(比如页面滚动、上拉刷新、下拉加载)
Page({

    /**
     * 初始化数据
     */
    data: {
      list:[]
    },

    /**
     * 发送网络请求
     */
    onLoad: function (options) {
        wx.request({
          url: 'http://……',
          success:(res) => {
              const data = res.data.data.list
              this.setData({
                  list:data
              })
          }
        })
    },
    //监听页面滚动
   onPageScroll(obj) {
   },
   //监听到页面滚动到顶部
   onReachBottom(obj) {
   }
}
监听页面的生命周期函数
  • onLoad:页面被加载时执行
  • onShow:页面显示出来时
  • onReady:页面初次渲染完成时
  • onHide:页面隐藏起来时
  • onUnload:
  • 打开一个页面,执行顺序为onLoad、onShow、onReady
  • Page实例生命周期在这里插入图片描述

4.内置组件

4.1.Text组件

  • 用于显示文本,类似于span标签,是行内元素
  • 常见属性:
selectable:
  • boolean,默认为false(即text中的文本长按是不能选中)
  • 文本是否可选
  • 示例:<text selectable="{{false}}"></text>(如果为true可简写为<text selectable></text>)要用mustache语法,否则则是把字符串赋值给他;
space:
  • string
  • 决定文本空格的大小
  • 有三个值:
//emsp,中文字符空格一半大小(默认)
<text space="ensp"></text>

//ensp,一个中文字符空格大小
<text space="emsp"></text>

//nbsp,根据字体设置的空格大小
<text space="nbsp"></text>
decode:
  • boolean,默认为false
  • 是否解码
  • 示例
<text>5 &gt; 3</text> //直接显示5 &gt; 3
<text decode="true">5 &gt; 3</text> //显示5 > 3
<text decode>5 &gt; 3</text> //显示5 > 3

4.2.Button组件

  • 用于创建按钮,默认块级元素
  • 常见属性:
    size:可以传入值mini,会将按钮转为行内块元素
    type:按钮的类型样式
    plain:按钮是否镂空,背景色透明
    open-type:用户获取一些特殊性的权限,可以绑定一些特殊的事件

4.3.View组件

  • 块级元素,独占一行,通常用作容器组件
  • 常见属性:
    hover-class:类型string,指定按下去的样式类。当 hover-class="none" 时,没有点击态效果
    hover-stay-time:类型number,手指松开后点击态保留时间,单位毫秒,默认为400毫秒
    hover-start-time:类型number,按住后多久出现点击态,单位毫秒
    hover-stop-propagation:boolean,默认false,指定是否阻止本节点的祖先节点出现点击态
  • 传入number类型如果发现没有效果记得给这个数字包装mustache语法

4.4.Image组件

  • image组件可以写成单标签<image/>,也可以写成双标签

  • image组件默认有自己的大小:320*240

  • image是行内块元素

  • 示例:用户如何在文件中选择图片

// home.wxml
<button bindtap="handleChooseAlbum">选择图片</button>
<image src="{{imagePath}}"></image>

// home.js
Page({
    /**
     * 页面的初始数据
     */
    data: {
        imagePath: ''
    },
    handleChooseAlbum() {
        // 让用户在相册中选择图片(或者拍照)
        wx.chooseImage({
            success: (res) => {
                // 取出路径
                const path = res.tempFilePaths[0];
                // 设置imagePath
                this.setData({
                    imagePath: path
                })
            }
        })
    }
})
常见属性
  • bindload:监听图片加载完成
  • lazy-load:boolean,默认为false,图片懒加载
  • show-menu-by-longpress:boolean,默认为false,开启长按图片显示识别小程序菜单
  • mode:string,默认值为scaleToFill,图片裁剪、缩放的模式

4.5.input组件

  • input组件用于接受用户的输入信息
  • input的基本使用:<input/>
  • value:input中的默认值
  • type:决定键盘类型(英文字母+其他符号/数字/身份证)
    取值有text(文本输入键盘),number(数字输入键盘),idcard(身份证输入键盘),digit(带小数点的数字键盘)
  • password:暗文
  • placeholder:占位文字
  • input绑定事件

4.6.scroll-view组件

  • 可以实现局部滚动
属性:
  • 水平滚动:scroll-x,设置为true
  • 垂直滚动:scroll-y,设置为true
绑定事件:
  • bindscroll:滚动时触发

4.7.组件的共同属性

  • id:组件的唯一标识
  • class:组件的样式类
  • style:组建的内联样式
  • hidden:boolean,组件是否显示
  • data-*:自定义属性,组件上触发的事件时,会发送给事件处理函数
  • bind */ catch*:组件的事件

5.wxss

5.1.样式的三种写法

  • 内联样式
  • 页内样式
  • 全局样式:在app.wxss中写,对所有页面的该属性都生效
  • 优先级:行内样式>页面样式>全局样式

5.2.支持的选择器

在这里插入图片描述

5.3.尺寸单位

  • rpx:可以根据屏幕宽度进行自适应,规定屏幕宽为750rpx
  • 在iPhone6,1rpx = 0.5px = 1物理像素
  • 在iPhone5,1rpx = 0.42px

5.4.样式导入

  • 我们可以在一个wxss中导入另一个wxss文件:
    使用@import进行导入
    @import后跟需要导入的外联样式表的相对路径(绝对路径),用;表示语句结束

5.5.基本样式库

  • https://github.com/Tencent/weui-wxss
  • 导入dist文件夹

6.wxml

6.1.mustache语法

//wxml
<view class='{{isActive ? "active" : ""}}'>{{message}}</view>
<button size="mini" bindtap="changeColor">更换颜色</button>

//js
 data: {
        message: '你好,小程序',
        isActive: false
    },
    changeColor() {
        this.setData({
            isActive : !this.data.isActive
        })
    }

6.2.条件判断

  • wx:if :<view wx:if="{{isShow}}"></view>
  • wx:elif / wx:else
  • wx:if和hidden隐藏组件的区别:
    hidden隐藏组件的时候,组件仍存在,用于切换隐藏频繁时,对于自定义的组件是无效的
    wx:if隐藏组件时,控制组件是否渲染
<view wx:if="{{false}}"></view>
<view hidden='{{true}}'></view>

6.3.列表渲染

  • wx:for的回顾
//遍历字符串
<view wx:for="SLineee" wx:key="index">{{item}}--{{index}}</view>

//遍历数组
<view wx:for="{{['dd','abc','bb']}}" wx:key="index">{{item}}--{{index}}</view>

//遍历数字,写在mustache语法里,则会从遍历九次(从0~8)
<view wx:for="{{9}}">{{item}}</view>
  • item、index起名字,用于多层遍历名字重复时
<view wx:for="{{idols}}" wx:for-item="idol" wx:for-index="i">{{idol}}--{{i}}</view>
  • key作用:提高性能在这里插入图片描述

6.4.block标签

  • 某些情况下,我们需要使用wx:if或wx:for时,可能需要包裹一组组件标签
  • 我们希望对这一组组件标签进行整体的操作
  • 可以使用一个view组件包裹,性能较低
  • 使用block标签包裹,它不是一个组件,只是一个包装元素,不会在页面中做任何渲染,只接受控制属性(wx:if或wx:for)
  • 使用block的好处:将需要进行遍历或判断的内容进行包裹;将遍历和判断的属性放在block便签中,不影响普通属性的阅读,提高代码的可读性;性能高

6.5.wxml导入

  • wxml提供模板(template),可以在模板中定义代码片段,在不同的地方调用
  • 使用name属性,作为模板的名字,然后在<template/>内定义代码片段
<template name="contentItem">
  <button size="mini">{{btnText}}</button>
</template>
  • 使用方法:<template is=" " data="{{key1:value1,key2:value2}}"/>(is后面写name)
  • import导入:<import src=""/>
    可以在该文件中使用目标文件定义的template
    不能递归导入(也就是A引入了B的template,不会引入B中引入C的template)
  • include导入:<include src=""/>
    将目标文件中除了<template/><wxs/>外的整个代码引入,相当于是拷贝到include的位置
    可以递归导入

7.wxs

7.1.作用

  • 在wxml中不能直接调用page/component中定义的函数,但是有时候我们希望可以用函数来处理wxml中的数据(类似过滤器),这个时候就使用wxs
  • wxs的运行环境和其他JavaScript代码是隔离的,wxs中不能调用其他JavaScript文件定义的函数,也不能调用小程序提供的API
  • wxs函数不能作为组件的事件回调

7.2.wxs的两种写法

  • 直接在wxml中定义
<!--pages/wxs/wxs.wxml-->
<wxs module="info">
  var message = "hello world";
  function sum(num1,num2) {
      return num1 + num2;
  }
  module.exports = {
      message : message,
      sum: sum
  }
</wxs>

<view>{{info.message}}</view>
<view>{{info.sum(20,30)}}</view>
  • 定义在单独的wxs文件中,再使用<wxs>标签导入
wxs/info.wxs:
var message = "hello world";
  function sum(num1,num2) {
      return num1 + num2;
  }
  module.exports = {
      message : message,
      sum: sum
  }

wxs.wxml:
必须使用相对路径
<wxs src="" module="info"/>
<view>{{info.message}}</view>
<view>{{info.sum(20,30)}}</view>

8.事件

8.1.常见的事件类型

  • 通过bind/catch这个属性绑定在组件上的
  • 从1.5.0版本开始,可以在bind和catch后加上一个冒号
  • 简单演练:
<button bindtap="handleBtnClick">按钮</button>
<button bind:tap="handleBtnClick">按钮</button>
<button catch:tap="handleBtnClick">按钮</button>
  • 某些组件会有自己特性的事件类型
    比如input有bindinput、bindblur、bindfocus等
    scroll-view有bindscrolltowpper、bindscrolltolower
  • 比较常见的事件类型:
    touchcancle在某些特定场景下才会触发
    tap事件和longpress事件通常只会触发其中一个在这里插入图片描述

8.2.事件对象的解析

  • 当某个事件触发时,会产生一个事件对象,并且这个对象被传入到回调函数中
  • 事件对象常见属性:在这里插入图片描述
  • touches和changedTouches的区别
    touches记录当前有几个手指在小程序中触摸的以及对应的触摸点信息
    changedTouches用来记录变化
    什么情况下可以看到区别:
    在touchend中不同
    多手指触摸时不同
  • currentTarget和target的区别
    currentTarget记录触发事件组件
    target记录产生事件的组件

8.3.事件参数的传递

  • 某些情况需要事件携带一些参数到执行的函数中,这个时候可以通过data-属性完成
  • 格式:data-属性的名称
  • 获取:e.currentTarget.dataset.属性的名称

8.4.事件冒泡和事件捕获

  • 事件捕获:capture-bind:tap
  • 事件冒泡:bindtap
  • capture-catch:tap、catchtap:阻止事件进一步传递

9.组件化开发

9.1.创建自定义组件

  • 类似于页面,自定义组件由json wxml wxss js 4个文件组成
  • 根目录下创建一个components,里面存放我们之后自定义的公共组件
  • 如何注册组件,在需要使用的页面的json文件里:
{
  "usingComponents": {
    "my-cpn" : "../../components/my-cpn/my-cpn"
  }
}
  • wxml中节点标签名只能是小写字母、中划线、下划线的组合,故自定义组件的标签名也只能包含这些字符
  • 自定义组件和页面所在项目根目录名不能以“wx-”为前缀
  • 如果在app.json的usingComponents声明某个组件,那么所有页面和组件可以直接使用该组件

9.2.组件和页面样式细节

  • 组件内的class样式不会对页面产生影响
  • 组件内不能使用id、属性、标签选择器
  • 外部使用class样式对组件内生效
  • 外部使用id选择器、属性选择器对组件内不生效
  • 外部使用标签选择器对组件内产生影响
  • 组件内的class样式和组件外的class样式,默认是有一个隔离的效果;为了防止样式的错乱,官方不推荐使用id、属性、标签选择器
  • 如何让class相互影响:
//自定义组件的js文件里
//styleIsolation有三个值
//1.默认为isolated,不会相互影响
//2.apply-shared:表示页面wxss样式将影响到自定义组件
//          但自定义组件wxss中指定的样式不会影响页面
//3.shared:页面会影响自定义组件,自定义组件也影响页面
Component({
    options: {
        styleIsolation:"isolated"
    }
})

9.3.给组件传递数据和样式

  • 组件和页面通信在这里插入图片描述
  • 给自定义组件传递数据:properties
//组件对应的js文件里
Component({
    properties: {
        title: {
            type: String,
            value: '我是标题',//默认值
            observer: function(newVal,oldVal) {
                console.log(newVal,oldVal);
            }
        }
    }
})

//组件的wxml文件:
<view class="title">{{title}}</view>

//如何传递数据
<my-cpn title="哈哈哈"></my-cpn>
  • 给自定义组件传递样式:externalClasses
//组件对应的js文件里
Component({
    externalClasses: ['titleclass']
})

//组件的wxml文件:
<view class="titleclass">{{title}}</view>

//页面,样式green写在页面的wxss文件里
<my-cpn titleclass="green"></my-cpn>

9.4.组件向外传递事件-自定义事件

  • this.triggerEvent('事件名称',{数据});
  • 页面:<view bind:事件名称=" "></view>

9.5.tab-control的练习

// tab-control.wxml
<view class="outer">
  <block wx:for="{{text}}" wx:key="index">
    <view class="{{currentIndex==index ? 'active' : '' }}"
    bind:tap="click" data-index="{{index}}">{{item}}</view>
  </block>
</view>

// tab-control.js
Component({
    properties: {
        text: {
            type: Array,
            value: []
        }
    },
    data: {
        currentIndex: 0
    },
    methods: {
        click(event) {
            const index = event.currentTarget.dataset.index;
            this.setData({
                currentIndex: index
            })
            //通知页面内部的点击事件
            this.triggerEvent('itemclick',{index})
        }
    }
})

// home.wxml
<tab-control text="{{['流行','新款','精选']}}"
             bind:itemclick="tabControlClick"></tab-control>

9.6.获取组件对象的方式

  • 如何在页面中点击按钮直接修改组件内定义的数据
//拿到组件对象
const obj = this.selectComponent('class/id');
//通过setData修改组件中的数据(不够规范)
obj.setData({
  
})
//规范写法:通过方法对数据进行修改
//该方法是在组件的methods定义的
obj.方法

9.7. 插槽slot

  • 多个插槽的使用:
    需要给每个插槽起个名字name
    使用的时候<button slot="name"></button>
    options中添加multipleSlots:true

9.8.component构造器

  • 构造器在这里插入图片描述在这里插入图片描述
  • 组件中监听生命周期函数:
    1.监听所在页面的生命周期pageLifetimes
    show:监听组件所在页面显示出来时
    hide:监听组件所在页面隐藏起来时
    resize:监听页面尺寸的改变
    2.监听组件本身的生命周期lifetimes
    created:组件被创建出来时
    attached:组件被添加到页面
    ready:组件被渲染出来
    moved:组件被移动到另外一个节点
    detached:组件被移除掉

10.系统API:网络请求

10.1.基本使用过程

  • 在小程序/小游戏中使用网络相关的 API 时,需要事先设置通讯域名,小程序只可以跟指定的域名进行网络通信
  • 配置流程:服务器域名在小程序后台-设置-开发设置-服务器域名中进行配置
  • 如何使用:
onLoad: function (options) {
        wx.request({
          url: 'http://123.207.32.32:8000/recommend',
          method: post,//默认为get
          data:{
            type: 'sell',
            page: 1
          }
          success:function(res) {
              console.log(res);
          }
        })
    }
  • 一些属性:
    在这里插入图片描述

10.2.工具函数封装

  • service/network.js
export default function request(options) {
    return new Promise((resolve,reject) => {
        wx.request({
            url: options.url,
            method: options.method || 'get',
            success: function(res) {
                resolve(res)
            },
            fail: function(err) {
                reject(err)
            }
          })
    })
}
  • 如何调用
import request from ''//相对路径
Page({
  onLoad:function(options){
    request({
      url:''
    })
  }.then(res=>{
  }).catch(err=>{
  })
})

11.系统API:展示弹窗

  • 小程序展示弹窗的四种方式:showToast、showModal、showLoading、showActionSheet
  • 参数查文档即可

11.1.showToast

//wxml文件:
<button size="mini" bind:tap="handleShowToast">showToast</button>

//js文件:
handleShowToast() {
        wx.showToast({
          title: 'nihaoa'
        })
    }

11.2.showModal

handleShowModal() {
        wx.showModal({
            title: '我是标题',
            content:'我是内容',
            success: function(res) {
                if(res.cancel) {
                    console.log('用户点击了取消按钮');
                }
                if(res.confirm) {
                    console.log('用户点击了确认按钮');
                }
            }
        })
    },

11.3.showLoading

  • 不会自动消失
  • 需要手动调用函数才会让loading消失
handleShowLoading() {
  wx.showLoading({
    title: '加载ing'
  })
  setTimeout(() => {
    wx.hideLoading()//手动调用让loading消失
  },1000)
}

12.系统API:页面分享

  • 小程序中有两种分享方式:
    点击右上角的菜单按钮,之后点击转发
    点击某一按钮,直接转发
  • 当我们转发给好友一个小程序时,小程序会显示一些信息,如何决定这些信息的展示,通过onShareAppMessage在这里插入图片描述
  • 分享按钮:open-type=“share”
<button size="mini" open-type="share">分享</button>

13.系统API:登录流程

  • 登录流程图在这里插入图片描述
  • 一般情况下,登录在app.js中实现在这里插入图片描述

14.系统API:界面跳转

  • 界面的跳转有两种方式:通过navigator组件和通过wx的API跳转

14.1.navigator组件

  • 属性:在这里插入图片描述
  • open-type的值:
    取值为navigatorBack时,可以多个属性为delta=“”,返回多少个层级在这里插入图片描述
  • 代码:
<navigator url="../detail/detail" 
open-type="redirect">跳到详情页</navigator>

14.2.跳转过程进行数据传递

  • 传递方式在这里插入图片描述
  • 首页往详情页传递数据用query
    详情页如何获取:在js文件的onLoad函数中的options里
  • 详情页往首页传递数据:
    onUnload的生命周期函数里
//detail.js
Page({
  onUnload() {
    //1、获取首页的页面对象
    const pages = getCurrentPages();
    const home = pages[pages.length-2];
    //2.调用页面对象的setData
    home.setData({
      title: '哈哈哈'
    })
  }
})

14.3.通过代码页面跳转

//home.wxml
<button size="mini" bindtap="handlePushDetail"></button>

//home.js
handlePushDetail(){
  wx.navigateTo({
    url: ''
  })
}

15.项目实战

15.1.底部tabbar

//app.json中
 "tabBar": {
      "selectedColor": "#ff5777",
      "list": [{
        "pagePath": "pages/home/home",
        "text": "首页",
        "iconPath": "/assets/img/tabbar/home.png",
        "selectedIconPath": "/assets/img/tabbar/home-ac.png"
      },
      {
        "pagePath": "pages/category/category",
        "text": "分类",
        "iconPath": "/assets/img/tabbar/tabbar.png",
        "selectedIconPath": "/assets/img/tabbar/tabbar-ac.png"
      }
    }

15.2.轮播图

  • 顶部导航栏如果文字要求不同时可以单独再在对应页面的json文件里设置
  • 数据请求:network/home.js
import request from './network'

const baseURL = "http://152.136.185.210:7878/api/hy66"
export function getMultiData() {
    return request({
      url: baseURL + '/home/multidata',
    })
}
//pages/home/home.js
// pages/home/home.js
import {getMultiData} from '../../service/home.js'
Page({
    data: {
        banners: [],
        recommends: []
    },
    onLoad: function (options) {
        //1.请求轮播图以及推荐数据
        getMultiData().then(res => {
            //取出轮播图和推荐的数据
            const banners = res.data.data.banner.list;
            const recommends = res.data.data.recommend.list;
            this.setData({
                banners,
                recommends
            })
        })
    }
})
  • 轮播图组件封装
//w-swiper.js
<!--components/w-swiper/w-swiper.wxml-->
<swiper class="swiper" 
        circular 
        autoplay 
        interval="3000" 
        duration="300"
        indicator-dots
        indicator-color="#fff"
        indicator-active-color="#ff577"
> 
  <block wx:for="{{list}}" wx:key="index">
    <swiper-item class="swiper-item">
      <image src="{{item.image}}" mode="widthFix"/>
    </swiper-item>
  </block>
</swiper>

在这里插入图片描述

  • 页面展示轮播图
<w-swiper list="{{banners}}"></w-swiper>

15.3.注意

  • 在wxss中不能用本地图片,只能引用网络图片
  • 上拉加载更多onReachBottom()监听
  • 回到顶部功能
handleBackTop() {
  wx.pageScrollTo({
    scrollTop: 0
  })
}

如果有bug则可以用如下方法:在这里插入图片描述

  • 监听页面的滚动:onPageScroll
  • 不要在滚动的函数回调中频繁调用this.setData
  • 获取某个组件距离顶部的距离:
    最好是在对高度影响最大的组件监听载入完毕(bindload)时调用获取距离
wx.createSelectorQuery().select('#id/class').boundingClientRect(rect => {
  console.log(rect)
}).exec()

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值