小程序导航,上拉,下拉,案例

  • wx:if: 控制显示和隐藏,true是显示,false隐藏,它跟vue里的v-if是一样的效果
  • hidden:控制显示和隐藏,true是隐藏,false是显示。它是通过操作display来控制显示和隐藏
  • wx:for:循环渲染、类似于vue的v-for
  • 上面的指令,都要注意,不加插值语法永远都是字符串,加了插值语法才代表用js的表达式
  • rpx单位:小程序创造出来的单位
    • 它的标准是把屏幕分为750份,每份是1rpx。在2倍屏的375下,1rpx就是0.5px
      • 因为2倍屏,屏幕总共才375分辨率,但是因为是2倍屏,所以一个点占2像素,对应的就是1px = 2rpx
      • 3倍屏414分辨率,那应该这么算,一个像素点占3像素,对应的就是1px = 3rpx,反过来1rpx=0.333px
      • 请问假如说美工出的图是750宽,标注的px我们就可以直接写多少rpx
      • 假如说美工出的图是1242宽,标准的px,应该用 1242 / 750 = 1.656 标注的是 100px 那么,就要用 100 / 1.656 = 60.38左右
  • 微信里什么文件代表样式 .wxss
    • 什么是全局样式app.wxss
    • 什么是局部样式当前文件名.wxss
    • 全局和局部都有,用局部的。如果不冲突就结合到一起(类似于css的层叠性)
  • 小程序里如何发请求?
    • wx.request({ url: '接口地址' })
    • 发请求有如下特点
      • 没有跨域问题,因为跨域是浏览器的同源策略弄出来
      • 发请求的接口服务器域名,要在微信开发者后台配置了才能发出去

发送get请求

// wx:是小程序里的顶级对象
 // 相当于浏览器中的window
 // 顶级对象里有个request就是专门用来发请求的
 wx.request({
   // 请求路径
   url: 'https://applet-base-api-t.itheima.net/api/get',
   // 请求方式
   method: 'get',
   // 请求参数,不管是什么请求传递参数都是用data
   data: {
     name: 'jack',
     age: 16
   },
   // success请求成功会调用的回调函数
   // res就是服务器返回的结果
   success: res => {
     console.log('请求完成', res)
   },
   // 失败调用
   fail: err => {

     console.log('请求失败', err)
   },
 // 不管成功还是失败,最终都会调用
   complete: () => {
     console.log('不管成功还是失败,最终都会调用')
   }
 })

发送post请求

wx.request({
  // 请求路径
  url: 'https://applet-base-api-t.itheima.net/api/post',
  // 请求方式
  method: 'post',
  // 请求参数,不管是什么请求传递参数都是用data
  data: {
    name: 'jack',
    age: 16
  },
  // success请求成功会调用的回调函数
  // res就是服务器返回的结果
  success: res => {
    console.log('请求完成', res)
  },
  fail: err => {

    console.log('请求失败', err)
  },

  complete: () => {
    console.log('不管成功还是失败,最终都会调用')
  }
})

开发阶段临时关闭校验

image-20221124093808312

  • 用以上的设置可以保证你自己这台电脑开发阶段,可以发任意请求,都不用添加到后台
  • 但是这种方法只能在开发阶段用,正式上线,你发的请求域名都得加到小程序后台允许请求的列表里

全局配置之window属性

{
  // 是相当于写路由的地方,描述有哪些页面
  // 放在最上面的一定是默认显示的第一个页面
  "pages": [
    "pages/request/request"
  ],
  // window是用来配置跟窗口有关的信息
  // 窗口就包含:导航栏、下拉栏(后面学到时讲)
  "window": {
     // 是配置下拉栏
    "backgroundTextStyle": "light",
     // navigationBar开头的都是导航栏
     // 导航栏背景颜色
    "navigationBarBackgroundColor": "#fff",
     // 导航栏标题
    "navigationBarTitleText": "Weixin",
     // 导航栏标题颜色:只有两个值:black、white
    "navigationBarTextStyle": "black"
  },
  // 小程序内部组件默认的样式版本
  "style": "v2",
   // 指定描述文件
  "sitemapLocation": "sitemap.json"
}
  • 全局的配置顾名思义,所有页面都能用
  • 但是页面自己也有自己的页面配置,如果跟全局冲突了,会用页面自己的
  • 并且页面配置里不用加 window,直接写
  • 注意:配置文件里不允许写注释,上面笔记里写注释只是为了方便复习

全局配置之tabbar详解

  • tabbar用来做栏目切换的,一般是在底部。小程序里也可以设置到顶部

    img

  • tabbar只能写到全局配置,也就是 app.json

  • tabbar的所有属性

属性 类型 必填 默认值 描述 最低版本
color HexColor tab 上的文字默认颜色,仅支持十六进制颜色
selectedColor HexColor tab 上的文字选中时的颜色,仅支持十六进制颜色
backgroundColor HexColor tab 的背景色,仅支持十六进制颜色
borderStyle string black tabbar 上边框的颜色, 仅支持 black / white
list Array tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab
position string bottom tabBar 的位置,仅支持 bottom / top
custom boolean false 自定义 tabBar,见详情 2.5.0
其中 list 接受一个数组,**只能配置最少 2 个、最多 5 个 tab**。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:
属性 类型 必填 说明
pagePath string 页面路径,必须在 pages 中先定义
text string tab 上按钮文字
iconPath string 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。positiontop 时,不显示 icon。
selectedIconPath string 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。positiontop 时,不显示 icon。
  • 如果tabbar在上,仅仅只能显示文字,在下既可以文字又可以有图标
"tabBar": {
  "backgroundColor": "#fff",
  "color": "#ddd",
  "selectedColor": "#f00",
  "borderStyle": "black",
  "position": "bottom",
  "list": [{
      "text": "请求",
      "pagePath": "pages/request/request",
      "iconPath": "tabs/contact.png",
      "selectedIconPath": "tabs/contact-active.png"
    },
    {
      "text": "案例",
      "pagePath": "pages/demo/demo",
      "iconPath": "tabs/home.png",
      "selectedIconPath": "tabs/home-active.png"
    }
  ]
},

导航到tabbar页面

  • 如果用声明式导航navigator,要区分是去tabbar页面还是非tabbar页面
    • 如果是去非tabbar页面,直接写url即可,例如
<!-- 只能跳转非tabbar页 -->
<navigator url="/pages/detail/detail">
  去详情页
</navigator>
- 如果是去`tabbar页面`,那么要加`open-type="switchTab"`属性,例如
<navigator url="/pages/request/request" open-type="switchTab">
  去请求页
</navigator>
  • 如果用编程式导航
    • 如果是去非tabbar页面,用 wx.navigateTo
wx.navigateTo({
  url: '/pages/detail/detail',
})
- 如果是去`tabbar页面`,用 `wx.switchTab`
wx.switchTab({
  url: '/pages/request/request',
})
  • 注意:tabbar页面,无法通过路径直接传参,非tabbar页面可以直接通过路径传参(通过onLoad钩子里的形参可以拿到)

配置下拉刷新

  • 在全局配置文件 app.json里,它要写在 window 一栏
"window":{
  // 设置下拉加载状态的样式,只有dark和light两个值
  "backgroundTextStyle":"dark",
  // 设置下拉框的背景颜色
  "backgroundColor": "#ddd",
// 开启下拉刷新
  "enablePullDownRefresh": true
},
  • 因为配置文件里不能写注释:不要直接复制粘贴就不管了
  • 因为是全局配置,所以所有页面都会具备下拉刷新!

下拉配置说明与局部配置优先级

  • 一般情况下,不会全局设置下拉刷新,因为这样会让所有页面都有下拉刷新
  • 因此,要开启下拉刷新,一般都是设置的局部
  • 局部配置文件:就是pages里某个页面的同名.json文件
  • 写到局部时,不需要加 window,直接写配置,如果全局有,局部也有,根据就近原则,用局部自己的
{
  "usingComponents": {},
   // 开启当前页面下拉刷新
  "enablePullDownRefresh": true,
   // 设置当前页面下拉刷新背景
  "backgroundColor": "#090909"
}

监听下拉刷新以及停止刷新

  • 用到的是js里的一个钩子 onPullDownRefresh
/**
 * 页面相关事件处理函数--监听用户下拉动作
 */
onPullDownRefresh() {
  console.log('下拉触发')
  // 写加载数据代码,可能很快加载完了
  // 如何用代码关闭下拉
  setTimeout(() => {
    // 停止下拉
    wx.stopPullDownRefresh()
  }, 400);
},
  • 停止下拉?
    • wx.stopPullDownRefresh()

上拉触底

  • 微信小程序里自带上拉触底的功能
  • 要满足:内容一屏不够放,有页面滚动条才会触发
  • 当下拉到底会自动触发onReachBottom函数

设置上拉触底距离

  • 默认情况下,上拉距离底部50px的高度情况下就会触发(预留了tabbar的距离)
  • 可以改,通过配置文件来改
"onReachBottomDistance": 200
- 全局写到 `window` 里
  • 一般不改。

微信弹出加载框和关闭它

  • 弹出
wx.showLoading({
    title: '提示的文字'
})
  • 注意:它不会自动关
  • 要关闭就调用如下代码
wx.hideLoading()

上拉案例:加载随机颜色

screenshots1

data: {
   list: []   
},
    
onLoad (option) {
    this.loadData()
},
    
// 加载随机颜色的方法
loadData() {
    wx.request({
      url: 'https://applet-base-api-t.itheima.net/api/color',
      success: res => {
        this.setData({
          list: [...this.data.list, ...res.data.data]
        })
      },
      complete: () => {
        // 不管请求成功还是失败都调用
        wx.hideLoading()
      }
    })
},
  • wxml页面,做wx:for页面渲染
<view class="container">
  <view wx:for="{{ list }}" wx:key="index" class="color-item" style="background-color: rgb({{ item }});">
    {{ item }}
  </view>
</view>
  • 样式如下
.color-item {
  width: 420rpx;
  height: 220rpx;
  background-color: #f00;
  margin-bottom: 50rpx;
  box-shadow: 0 0 10px 5px gold;
  border-radius: 10px;
  text-align: center;
  line-height: 220rpx;
}
  • 然后完成上拉触发的事件,在里面也调用获取数据的方法
/**
 * 页面上拉触底事件的处理函数
 */
onReachBottom() {
  // 开启加载动画
  wx.showLoading({
    title: '加载中',
  })
  // 下拉到底,要再次发个请求
  this.loadData()
},
  • 整体思路总结:
    • 因为需要页面一打开就加载数据,所以写到onLoad里发请求,把请求到的数据加到data中的数组里
    • 然后来到 wxml写好结构,并用wx:for进行循环渲染
    • 然后写好对应的布局样式
    • 最后动态渲染style和文字内容
    • 然后在上拉到底的监听函数里,再次调用请求数据的方法加载数据
      • 但是在这个方法里要开启加载动画,并在请求结束(不管成功还是失败)都要结束加载动画

案例- 随机颜色使用节流阀优化

  • 为什么要优化?
    • 如果网速慢,可能请求过程中用户来回滚动,会导致发多个请求,会造成服务器压力
  • 优化思路是:
    • 如果正在发请求,不能开启新的请求。一定要等上一个请求完了,才能发新的请求
  • 步骤
    • 准备一个变量用来标记当前是否正在处于发请求的状态
data: {
    // 默认值为false,代表默认没有发请求
    isLoading: false
}
- 来到 `onReachBottom`函数里,做判断,如果这个标记为true,代表当前正有请求,就要直接return,代表不往下执行
onReachBottom() {
  // 如果正在发请求,就不往下执行
  if (this.data.isLoading) return
  // 开启加载动画
  wx.showLoading({
    title: '加载中',
  })
  // 下拉到底,要再次发个请求
  this.loadData()
},
- 再来到发请求的方法叫 `loadData`里,发请求前立即把`isLoading`改成true,并且在请求完成时一定要改为`false`
// 加载随机颜色的方法
loadData() {
  // 修改为true
  this.setData({
    isLoading: true
  })
  ........
  ........
    complete: () => {
      // 把标记给关掉,代表可以发新的请求
      this.setData({
        isLoading: false
      })
     .......
    }
  })
},

纯数据字段

官网文档-纯数据字段

  • 就是有些数据可能只是为了js里做运算或者逻辑判断,并不需要渲染到页面上,那么这种数据就可以作为纯数据字段,例如上面的 isLoading
  • 如何把某些数据标记为纯数据呢?
    • 在data平级的位置写
options: {
    // 这段正则的意思是:所有以 下划线 开头的数据,都将会变成纯数据字段
    // 作用:可以提升界面的性能
    pureDataPattern: /^_/
  },
}
- 这么写了后,下面的数据
data: {
    // 不是纯数据,界面上可以渲染
    list: [],
    // 这就是纯数据,界面上不能渲染
    _isLoading: false
}
- 如果是纯数据字段,可以不用 `setData`来赋值,可以直接赋值,例:
this.data._isLoading = true
    - 为什么可以直接赋值?因为以前说要用`setData`是因为,不用`setData`它数据能改,但是界面不会更新
    - 而现在纯数据压根就不需要进行页面渲染,所以可以直接对它进行赋值

案例 - 本地生活首页

tabbar和导航栏布局

  • 设置全局配置即可
"window": {
  "backgroundTextStyle": "light",
  "navigationBarBackgroundColor": "#2b4b6b",
  "navigationBarTitleText": "本地生活",
  "navigationBarTextStyle": "white"
},
"tabBar": {
  "list": [{
      "text": "首页",
      "pagePath": "pages/home/home",
      "iconPath": "images/tabs/home.png",
      "selectedIconPath": "images/tabs/home-active.png"
    },
    {
      "text": "消息",
      "pagePath": "pages/message/message",
      "iconPath": "images/tabs/message.png",
      "selectedIconPath": "images/tabs/message-active.png"
    },
    {
      "text": "联系我们",
      "pagePath": "pages/contact/contact",
      "iconPath": "images/tabs/contact.png",
      "selectedIconPath": "images/tabs/contact-active.png"
    }
  ]
},

轮播图

  • 页面一打开就要发请求,所以要用一到生命周期函数(钩子)onLoad,一旦加载页面就会调用
  • 封装一个方法专门用来获取轮播图数据,来到 onLoad 做调用,以及在 data中声明一个数组用来保存得到的轮播图数组
/**
 * 页面的初始数据
 */
data: {
  // 保存轮播图的数组
  sliderList: [],
},

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

// 加载轮播图的方法
loadSlider() {
  wx.request({
    url: 'https://applet-base-api-t.itheima.net/slides',
    success: res => {
      // 把值存到data
      this.setData({
        sliderList: res.data
      })
    }
  })
},
  • 来到home.wxml做轮播图布局
<swiper indicator-dots autoplay interval="1500" circular>
  <swiper-item class="pic-item" wx:for="{{ sliderList }}" wx:key="id">
    <image src="{{ item.image }}"></image>
  </swiper-item>
</swiper>
  • 样式只要给image加宽100%即可
.pic-item image {
  width: 100%;
}

九宫格

  • 像轮播图一样,封装方法,在onload里调用,在data中声明数据保存
data: {
   sliderList: [],
   gridList: []
 },
 

onLoad(options) {
   // 调用
   this.getSliders()
   this.loadGrid()
},
   
loadGrid () {

   wx.request({
     url: 'https://applet-base-api-t.itheima.net/categories',
     success: res => {
       this.setData({
         gridList: res.data
       })
     }
   })
 },
  • 渲染页面
    • 整体思想一个大盒子包着九宫格的小盒子,用弹性布局,并且要允许换行,每个小盒子占用宽度为33.33%
<view class="grid-box">
  <view wx:for="{{ gridList }}" wx:key="id" class="grid-item">
    <image mode="widthFix" src="{{ item.icon }}"></image>
    <view>{{ item.name }}</view>
  </view>
</view>
- 小盒子里面放图片和text,并且小盒子也要用弹性布局来管理内容,并且小盒子给高度,和改弹性布局放心,以及让他们居中
- 因为要加边框,可能会撑大盒子,所以要改盒子模型,整体样式如下
.grid-box {
  display: flex;
  flex-wrap: wrap;
}

.grid-item {
  width: 33.33%;
  height: 200rpx;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  border: 1px solid #ddd;
  box-sizing: border-box;
}

.grid-item image {
  width: 80rpx;
  margin-bottom: 10rpx;
}
- 细节样式:改字体大小、图片大小
  • 最后放一个盒子,盒子里放两张图片即可
<view class="ad-box">
  <image mode="widthFix" src="../../images/link-01.png"></image>
  <image mode="widthFix" src="../../images/link-02.png"></image>
</view>
.ad-box {
  display: flex;
  justify-content: space-around;
  margin-top: 20rpx;
}

.ad-box image {
  width: 300rpx;
}

案例:本地生活-详情页与跳转

screenshots

案例:本地生活-详情页与跳转

posted @ 2023-01-31 10:56  Cherishe  阅读(113)  评论(0)    收藏  举报