【小程序】小程序学习04

04

页面导航

  1. 声明式导航
    • 在页面上声明一个<navigator>导航组件
    • 通过点击<navigator>组件实现页面跳转
  2. 编程式导航
    • 调用小程序的导航API,实现页面的跳转

声明式导航

导航到tabBar页面

tabBar页面指的是被配置为tabBar的页面。

在使用<navigator>组件跳转到指定的tabBar 页面时,需要指定url属性和open-type属性,其中:

- `url`表示要跳转的**页面的地址**,必须以 `/` 开头
- `open-type` 表示**跳转的方式**,必须为`switchTab`

普通页面中实现点击跳转:

<navigator url="/pages/04buton/04buton">导航到04页面</navigator>

tabBar页面中实现点击跳转:

<navigator url="/pages/11tabUser/11tabUser" open-type="switchTab">点击跳转到User</navigator>
导航到非tabBar页面

非tabBar页面:没有被配置为tabBar的页面

在使用<navigator>组件跳转到普通的非tabBar 页面时,则需要指定url属性和open-type属性,其中:

  • url表示要跳转的页面的地址,必须以/开头
  • open-type 表示跳转的方式,必须为navigate

为了简便,在导航到非tabBar页面时,open-type="navigate"属性可以省略。

<!-- 跳转到非tabBar页面 -->
<navigator url="/pages/05image/05image" open-type="navigate">点击跳转到05image页面</navigator>
后退导航

如果要后退到上一页面或多级页面,则需要指定 open-type属性和delta属性,

  • open-type的值必须是navigateBack,表示要进行后退导航

  • delta的值必须是数字,表示要后退的层级

    不写delta则默认为1

<!--pages/05image/05image.wxml-->
<navigator open-type="navigateBack" delta="1">后退</navigator>

编程式导航

导航到tabBar页面

调用wx.switchTab(Object object)方法,可以跳转到tabBar页面。其中Object参数对象的属性列表如下:

image-20220203105726685

<!-- 编程式导航 -->
<view>编程式导航</view>
<button bindtap="gotoUser" type="default">跳转到tbaUser</button>
// 通过编程式导航跳转到tbaUser页面
gotoUser() {
    wx.switchTab({
        url: '/pages/11tabUser/11tabUser',
    })
},
导航到非tabBar页面

调用wx.navigateTo(Object object)方法,可以跳转到非tabBar的页面。其中Object参数对象的属性与上面基本相同

image-20220203110658960

<button bindtap="gotoImage" type="primary">跳转到05image</button>
// 通过编程式导航跳转到非tabBar页面
gotoImage() {
    wx.navigateTo({
        url: '/pages/05image/05image',
    })
},
后退导航

调用wx.navigateBack()方法

<!--pages/05image/05image.wxml-->
<button bindtap="goBack">点击返回</button>
// 编程式导航
goBack() {
    wx.navigateBack()   // 包含参数delta默认为1
},

页面事件

下拉刷新

全局开启——app.json——window节点中

局部开启——页面的.json文件

'enablePullDownRefresh':true

样式:

backgroundColorbackgroundTextStyle(loading样式—dark/light)

监听下拉刷新事件onPullDownRefresh

<!-- onPullDownRefresh下拉刷新 -->
<view>count值是:{{count}}</view>
<button bindtap="addCount">+1</button>
data: {
    count: 0
},
addCount() {
    this.setData({
        count: this.data.count + 1
    })
},
onPullDownRefresh: function () {
    // 下拉刷新后count重置为0
    console.lo g('onPullDownRefresh')
    this.setData({
        count: 0
    })
    wx.stopPullDownRefresh()	// 停止下拉刷新
},

停止下拉刷新效果wx.stopPullDownRefresh()

上拉触底

在页面的.js文件中,通过onReachBottom()函数即可监听当前页面的上拉触底事件

在页面的.json文件中配置onReachBottomDistance属性配置上拉触底的距离(距离底部多少距离开始调用onReachBottom()函数)

案例 — 本地生活
  1. 随机获取随机颜色的方法

    data: {
        colorList: []
    },
    // 随机颜色
    getColor() {
        wx.request({
            url: 'https://www.escook.cn/api/color',
            method: 'GET',
            success: ({data:res}) => { // data属性并重命名为res
                console.log(res)
                this.setData({
                    colorList: [...this.data.colorList,...res.data]
                })
            }
        })
    },
    
  2. 页面加载时获取初始数据

    // 监听页面加载   
    onLoad: function (options) {
        this.getColor()
    },
    
  3. 渲染UI并美化页面结果

    <view wx:for="{{colorList}}" wx:key="index" class="num-item" style="background-color: rgba({{item}});">{{item}}</view>
    
    .num-item {
        border: 1rpx solid #efefef;
        border-radius: 8rpx;
        line-height: 200rpx;
        text-align: center;
        margin: 15rpx;
        text-shadow: 0rpx 0rpx 5rpx #fff;
        box-shadow: 1rpx 1rpx 6rpx #aaa;
    }
    
  4. 上拉触底获取随机颜色

    // 上拉触底方法
    onReachBottom: function () {
        this.getColor()
    },
    
  5. 添加loading提示效果–wx.showloading()|wx.hideloading()

    image-20220204092836382

  6. 上拉触底节流处理

    1. data中定义isloading节流阀

      • false表示当前没有进行任何数据请求
      • true表示当前正在进 行数据请求
      isloading:fale
      
    2. getColor()方法中修改isloading节流阀的值

      • 在刚调用getColors时将节流阀设置true
      • 在网络请求的complete回调函数中,将节流阀重置为false
      getColor() {
          this.setData({
              isloading: true
          })
          ......
          wx.request({
              ......
              complete: () => {
                  wx.hideLoading()
                  this.setData({
                      isloading: false
                  })
              ......
      
    3. onReachBottom中判断节流阀的值,从而对数据请求进行节流控制

      • 如果节流阀的值为true,则阻止当前请求
      • 如果节流阀的值为false,则发起数据请求
      onReachBottom: function () {
          if(this.data.isloading) return
          this.getColor()
      },
      

生命周期

应用生命周期()

  • 小程序启动->运行->销毁过程

页面生命周期()

  • 小程序中的页面加载->渲染->销毁过程

image-20220204100300950

生命周期强调时间段生命周期函数强调的是时间点

生命周期函数分类:

  1. 应用的生命周期函数 – 在**app.js**中进行声明

    • 小程序从启动->运行->销毁期间依次调用的函数
    // app.js
    App({
      // 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
      onLaunch: function () {},
      // 当小程序启动,或从后台进入前台显示,会触发 onShow
      onShow: function (options) {},
      // 当小程序从前台进入后台,会触发 onHide
      onHide: function () {},
      // 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
      onError: function (msg) {}
    })
    
  2. 页面的生命周期函数 – 在页面的**.js**中进行声明

    • 小程序每个页面加载->渲染->销毁期间依次调用的函数
    // pages/demo/demo.js
    Page({
        // 页面的初始数据
        data: {},
        // 生命周期函数--监听页面加载
        onLoad: function (options) {},
        // 生命周期函数--监听页面初次渲染完成
        onReady: function () {},
        // 生命周期函数--监听页面显示
        onShow: function () {},
        //生命周期函数--监听页面隐藏
        onHide: function () {},
        // 生命周期函数--监听页面卸载
        onUnload: function () {},
        // 页面相关事件处理函数--监听用户下拉动作
        onPullDownRefresh: function () {},
        // 页面上拉触底事件的处理函数
        onReachBottom: function () {},
        // 用户点击右上角分享
        onShareAppMessage: function () {}
    })
    

WXS 脚本

WXS(WeiXin Script)是小程序独有的一套脚本语言,结合WXML,可以构建出页面的结构。

wxml中无法调用在页面的.js中定义的函数,但是,wxml中可以调用WXS中定义的函数。因此,小程序中WXS的典型应用场景就是**“过滤器”**。

wxs和JavaScript的关系

  1. wxs有自己的数据类型

    numberstringbooleanobjectarrayfunctiondateregexp
    数值类型字符串类型布尔类型对象类型数组类型函数类型日期类型正则
  2. wxs不支持类似于ES6以上的语法形式

    • 不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc……
    • 支持:var 定义变量、普通function函数等类似于ES5的语法
  3. wxs遵循CommonJS规范

    • module对象
    • require()函数
    • module.exports对象
内嵌wxs脚本

wxs代码可以编写在wxml文件中的<wxs>标签内,就像Javascript代码可以编写在html文件中的<script>标签内一样。

wxml文件中的每个<wxs></wxs>标签,必须提供module属性,用来指定当前WXS的模块名称,方便在wxml中访问模块中的成员:

原本输出为’zs’,但调用m1后输出为’ZS’。

data: {username:'zs'},	// js
<view>{{m1.toUpper(username)}}</view>

<wxs module="m1">
    module.exports.toUpper = function (str) {
        return str.toUpperCase()
    }
</wxs>

image-20220204144057401

AppData中的数据仍为小写’zs’未改变

定义外联的wxs脚本

wxs代码还可以编写在.wxs为后缀名的文件内,就像 javascript代码可以编写在以.js为后缀名的文件中一样。

示例/utils文件夹下创建tools.wxs

function toLower(str){
    return str.toLowerCase()
}
module.exports = {
    toLower: toLower    // 属性 : 对应的值
}
使用外联的wxs脚本

在wxml中引入外联的wxs脚本时,必须为<wxs>标签添加modulesrc属性,其中:

  • module用来指定模块的名称
  • src用来指定要引入的脚本的路径,且必须是相对路径
data:{country: 'CHINA'}
<view>{{m2.toLower(country)}}</view>
<wxs src="../../utils/tools.wxs" module="m2"></wxs>

image-20220204150909309

特点
  • 为了降低wxs(WeiXin Script)的学习成本、wxs语言在设计时借大量鉴了JavaScript的语法。但是本质上,wxs和JavaScript是完全不同的两种语言!

  • wxs典型的应用场景就是“过滤器”,经常配合Mustache语法进行使用但是,在wxs中定义的函数不能作为组件的事件回调函数。例如:

    <button bindtap="m2.toLower">按钮</button>
    
  • 隔离性:wxs的运行环境和其他JavaScript代码是隔离的。

    1. wxs不能调用js中定义的函数
    2. wxs不能调用小程序提供的API
  • 性能好(IOS设备中比JavaScript代码块2~20倍,但Android设备就无差异)

案例–本地生活

页面导航并传参

  1. 设置页面标题

    <!-- 九宫格区域 -->
    <view class="grid-list">
        <navigator class="grid-item" wx:for="{{gridList}}" wx:key="id" url="/pages/shoplist/shoplist?id={{item.id}}&title={{item.name}}">
            <image src="{{item.icon}}"></image>
            <text>{{item.name}}</text>
        </navigator>
    </view>
    
    data: {
        query: {}
    },
    onLoad: function (options) {
        // 获取页面参数
        this.setData({
            query: options
        })
    },
    onReady: function () {
        wx.setNavigationBarTitle({
            title: this.data.query.title,
        })
    },
    

    image-20220204161313351

    添加编译模式 —— 自定义参数
    image-20220204162149655

  2. 列表页面的API接口

    以分页形式加载分类下商铺列表的数据:

    1. 接口地址

      • https://www.escook.cn/categories/:cate_id/shops

      • URL地址中的:cate_id是动态参数,表示分类的id

    2. 请求方式——GET请求

    3. 请求参数

      • _page:请求第几页的数据
      • _limit:每页请求几条数据
    data: {
    	......
        shopList: [], // 所有商铺的信息
        page: 1,      // 一进入商铺列表就请求第一页的信息
        pageSize: 10, // 每页默认获取10条数据
        total: 0      // 当前总共数据
    },
    // 获取商铺列表
    getShopList() {
        wx.request({
            url: 'https://www.escook.cn/categories/' + this.data.query.id + '/shops',
            method: 'GET',
            data: {
                _page: this.data.page,
                _limit: this.data.pageSize
            },
            success: (res) => {
                console.log(res)
                this.setData({
                    shopList: [...this.data.shopList, ...res.data],
                    total: res.header['X-Total-Count'] - 0
                })
            }
        })
    },
    onLoad: function (options) {
        // 获取页面参数
        this.setData({
            query: options
        })
        this.getShopList()
    },
    

    渲染列表

    <!--pages/shoplist/shoplist.wxml-->
    <view class="shop-item" wx:for="{{shopList}}" wx:key="id">
        <view class="thumb">
            <image src="{{item.imgaes[0]}}"></image>
        </view>
        <view class="info">
            <text>{{item.name}}</text>
            <text>电话:{{item.phone}}</text>
            <text>地址:{{item.address}}</text>
            <text>营业时间:{{item.businessHours}}</text>
        </view>
    </view>
    
    /* pages/shoplist/shoplist.wxss */
    .shop-item {
        display: flex;
        padding: 15rpx;
        border: 1rpx solid #efefef;
        border-radius: 8rpx;
        margin: 15rpx;
        box-shadow: 1rpx 1rpx 15rpx #ddd;
    }
    
    .thumb image {
        width: 250rpx;
        height: 250rpx;
        display: block;
        margin-right: 15rpx;
    }
    
    .info {
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        font-size: 24rpx;
    }
    
    .info text:nth-child(1){
        font-weight: bold;
    }
    
    

上拉触底加载下一页数据

判断是否还有下一页数据

如果下面的公式成立,则证明没有下一页数据:

页码值 * 每页显示多少条数据 >= 总数据条数

page * pageSize >= total

案例1:总共有77条数据,如果每页显示10条数据,则总共分为8页,其中第8页只有7条数据
page(7) * pageSize(10) >= total(77)

page(8) * pageSize(10) >= total(80)

案例2:总共有80条数据,如果每页显示10条数据,则总共分为8页,其中第8页面有10条数据

page(7) * pageSize(10) >= total(80)

page(8) * pageSize(10) >= total(80)

添加节流阀
1. // data添加: isloading: false // 添加节流阀
2. getShopList() {
    // 节流阀
    this.setData({
        isloading: true
    })
    // 展示loading效果
    ......
    complete: () => {
        ......
        // 节流阀
        this.setData({
            isloading: false
        })
   ......
	},
3. onReachBottom: function () {
        console.log('onReachBottom')
        // 节流阀
        if (this.data.isloading) return
        this.setData({
            page: this.data.page + 1
        })
        // 获取列表
        this.getShopList()
    },

下拉刷新列表数据

下拉刷新基本配置

"onReachBottomDistance": 200,
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark",
"backgroundColor": "#efefef"

数据获取成功关闭下拉刷新的动画wx.stopPullDownRefresh()

仅下拉刷新的时候调用wx.stopPullDownRefresh(),但直接在getShopList()获取数据后直接调用就成为下滑加载也会调用wx.stopPullDownRefresh(),显然不合适。

getShopList(cb) cb && cb() cb回调

getShopList(cb) {
    ......
    	complete: () => {
                ......
                // 隐藏下拉刷新效果 
                // wx.stopPullDownRefresh()
                cb && cb()
                // 节流阀
                ......
            }
        ......
},
onPullDownRefresh: function () {
    ......
    // 重新发起数据请求
    this.getShopList(() => {
        wx.stopPullDownRefresh()
    })
},

处理文本(手机号)

效果:12345678900 ==> 123-4567-8900

手机号字符串长度为11位

tools.wxs

function splitPhone(str) {
    if (str.length != 11) return str
    var arr = str.split('')
    console.log('phone',arr)
}

module.exports = {
    splitPhone: splitPhone
}

打印输出

image-20220206162822112

**arr.splice()**在指定位置删除元素或加入元素

arr.splice(3,0,'-')第3个位置插入-

arr.splice(8,0,'-')第8个位置插入-

image-20220206163330128

return arr.join('') 将数组合并

function splitPhone(str) {
    if (str.length != 11) return str
    var arr = str.split('')
    arr.splice(3,0,'-')
    arr.splice(8,0,'-')
    return arr.join('')
}

image-20220206163704363

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值