微信小程序快速开发-基础内容(内容真的又多又干货)

news2024/11/24 2:41:06

目录

实现横向布局效果

实现滚动效果

实现轮播图效果

实现文本长按选中复制效果

渲染 HTML 标签

按钮组件的使用效果

图片组件的使用效果

Mustache 语法

动态绑定内容(定义变量,渲染变量)

动态绑定属性(将属性定义为变量并使用)

使用三元运算

算术运算

事件绑定

触摸事件绑定

触摸事件发生改变 data 中数据的值

为事件处理函数传参

输入事件绑定

实现文本框和 data 之间的数据同步

条件渲染(根据一定条件进行渲染)

使用 block 包装组件(单纯的容器)

使用 hidden 进行条件渲染

列表渲染

导入外联样式表

window 节点常用的配置项

设置导航栏的背景色

设置导航栏的标题内容

设置导航栏的标题颜色

开启下拉刷新效果

设置下拉刷新时窗口的背景色

设置下拉刷新时 loading(加载) 的样式

设置上拉触底的距离(一般默认即可)

下拉刷新

监听用户下拉动作

停止下拉刷新效果(刷新完成,自动停止)

上拉触底

上拉触底案例

tabBar 配置页面跳转标签

配置页面跳转标签 tab

网络数据请求

发起 GET 请求

页面加载时便请求数据

滚动选择器

普通选择器

页面导航

导航到 tabBar 页面

导航到非 tabBar 页面

导航到上一页(后退导航)

页面导航 - 编程式导航

导航到 tabBar 页面

导航到非 tabBar 页面

后退导航

页面导航 - 导航传参

声明式导航传参

编程式导航传参

接收导航参数

生命周期函数

应用生命周期函数

页面生命周期函数

WXS 脚本

内嵌 wxs 脚本

外联 wxs 脚本

通过 wxs 脚本修改电话格式

消息提示框

自定义组件

创建组件文件

局部引入组件

全局引入组件

自定义组件的样式隔离选项

自定义主键的数据和方法定义

自定义组件传参以及参数获取

使用数据监听器

监听对象中指定属性的变化

监听对象中所有属性的变化

纯数据字段

组件的生命周期函数

组件所在页面的生命周期

组件所在页面的生命周期案例

单个插槽

多个插槽

父子组件之间的通信 - 父向子传值

父子组件之间的通信 - 子向父传值

 访问子组件的任意数据和方法

组件间代码共享

创建 behavior

导入并使用 behavior

使用 Vant 组件

定制 Vant 组件样式

小程序 api 的 promise 化

调用 Promise 化后的异步 API

全局数据共享

安装 mobx 相关的包

创建 Store 实例

将 store 中的成员绑定到页面中

在页面上使用 store 中的成员

将 store 中的成员绑定到组件中

在组件中使用 store 中的成员

对小程序进行分包

独立分包

配置分包的预下载

自定义 tabBar

1.配置信息

2.添加 tabBar 代码文件

3.根据 Vant 组件来自定义 tabBar

引入组件

基础用法

4.根据 list 数组中定义的属性内容来批量设置 tabBar 效果

5.在自定义组件中使用 Vant 组件,需要覆盖 Vant 组件原来的样式

6.实现 tabBar 页面的切换效果


实现横向布局效果

wxml

<view class="container1">
  <view>A</view>
  <view>B</view>
  <view>C</view>
</view>

wxss

.container1 view{
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
}

/*选择 .container1 类下的第一个 view*/
.container1 view:nth-child(1){
  background-color: lightgreen;
}
.container1 view:nth-child(2){
  background-color: lightblue;
}
.container1 view:nth-child(3){
  background-color: lightpink;
}

.container1{
  display: flex;
  justify-content: space-around;
}

实现滚动效果

wxml

<!-- scroll-x 属性,允许横向滚动-->
<!-- scroll-y 属性,允许纵向滚动-->
<!-- 注意:使用纵向滚动时,必须给 scroll-view 一个固定高度 -->
<!-- 注意:使用横向滚动时,必须给 scroll-view 一个固定宽度 -->
<scroll-view class="container1" scroll-y>
  <view>A</view>
  <view>B</view>
  <view>C</view>
</scroll-view>

wxss

/*选择 .container1 类下的所有 view*/
.container1 view{
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
}

/*选择 .container1 类下的第一个 view*/
.container1 view:nth-child(1){
  background-color: lightgreen;
}
.container1 view:nth-child(2){
  background-color: lightblue;
}
.container1 view:nth-child(3){
  background-color: lightpink;
}

.container1{
  border:1px solid red;
  /* 给 scroll-view 固定高度 */
  height: 120px;
  width: 100px;
}

实现轮播图效果

wxml

<!--pages/list/list.wxml-->
<!-- 轮播图的结构 -->
<swiper class="swiper-container" indicator-dots autoplay interval="1000" circular>
  <!-- 第一个轮播图 -->
  <swiper-item>
    <view class="item">A</view>
  </swiper-item>
  <!-- 第二个轮播图 -->
  <swiper-item>
    <view class="item">B</view>
  </swiper-item>
  <!-- 第三个轮播图 -->
  <swiper-item>
    <view class="item">C</view>
  </swiper-item>
</swiper>

wxss

/* pages/list/list.wxss */
.swiper-container{
  height: 150px;
}

.item{
  height: 100%;
  line-height: 150px;
  text-align: center;
}

.swiper-container swiper-item:nth-child(1) .item{
  background-color: lightgreen;
}
.swiper-container swiper-item:nth-child(2) .item{
  background-color: lightblue;
}
.swiper-container swiper-item:nth-child(3) .item{
  background-color: lightpink;
}

swiper 组件的常用属性

实现文本长按选中复制效果

wxml

<!-- 实现文本长按选中复制效果 -->
<view>
 手机号支持长按选中复制效果
 <text user-select>110110110110</text>
</view>

渲染 HTML 标签

wxml

<rich-text nodes="<h1 style='color:red;'>标题</h1>"></rich-text>

按钮组件的使用效果

<!-- 按钮组件的基本使用 -->
<!-- 通过 type 属性指定按钮颜色类型 -->
<button>普通按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告按钮</button>
<!-- size="mini" 小尺寸按钮 -->
<button size="mini">普通按钮</button>
<button type="primary" size="mini">主色调按钮</button>
<button type="warn" size="mini">警告按钮</button>
<!-- plain 镂空按钮 -->
<button size="mini" plain>普通按钮</button>
<button type="primary" size="mini" plain>主色调按钮</button>
<button type="warn" size="mini" plain>警告按钮</button>

图片组件的使用效果

wxml

<image></image>
<image src="/image/微信开发者工具.png" mode="heightFix"></image>

wxss

image {
  border: 1px solid red;
}

image 组件 mode 属性的常用选项

Mustache 语法

动态绑定内容(定义变量,渲染变量)

js

/**
   * 页面的初始数据
   */
  data: {
    info:'hello wx'
  },

wxml

<view>{{info}}</view>

动态绑定属性(将属性定义为变量并使用)

js

  /**
   * 页面的初始数据
   */
  data: {
    imgSrc:"/image/微信开发者工具.png"
  },

wxml

<image src="{{imgSrc}}"></image>

使用三元运算

js

  /**
   * 页面的初始数据
   */
  data: {
    //生成 10 以内的随机数
    randomNum:Math.random()*10  
  },

wxml

<view>{{randomNum>5?'随机数字大于5':'随机数字小于5'}}</view>

算术运算

js

  /**
   * 页面的初始数据
   */
  data: {
    //在 0,1 之间生成带两位小数的随机数
    randomNum:Math.random().toFixed(2)
  },

wxml

<view>{{randomNum*100}}</view>

事件绑定

触摸事件绑定

        为按钮绑定触摸事件,当点击按钮(触发事件)后,逻辑层会得到 event 对象(可简写为 e ),包含该事件的详细属性,打印该 event 对象

event 对象的相关属性

js

  /**
   * 按钮的事件处理函数
   */
  tapHandler(e){
    console.log(e);
  },

wxml

<button type="primary" bind:tap="tapHandler">按钮</button>

触摸事件发生改变 data 中数据的值

为按钮绑定触摸事件,当点击按钮 (触发事件)后,data 中定义的数据 count 会加 1

js

  /**
   * 页面的初始数据
   */
  data: {
    count:0
  },

  /**
   * +1 事件处理函数
   */
  addTapHandler(){
    this.setData({
      count:this.data.count+1
    })
  },

wxml

<button type="primary" bind:tap="addTapHandler">+1</button>

为事件处理函数传参

        为按钮绑定触摸事件,当点击按钮 (触发事件)后,data 中定义的数据 count 会加 info ,info 是传给 事件处理函数的参数 

js

  /**
   * 页面的初始数据
   */
  data: {
    count:0
  },

  /**
   * +2 事件处理函数
   */
  addTapHandler(e){
    this.setData({
      //通过 e.target.dataset 获取传给事件处理函数的参数
      count:this.data.count+e.target.dataset.info
    })
  },

wxml

<!-- 通过 data- 传参-->
<!-- data-info="{{2}} 表示参数名称为 info ,值为整数 2 -->
<!-- data-info="2" 表示值为字符 2 -->
<button type="primary" bind:tap="addTapHandler" data-info="{{2}}">+2</button>

输入事件绑定

        为输入框绑定输入事件,向输入框中输入数据时,触发事件,逻辑层打印输入框中最新的信息

js

  /**
   * 输入事件处理函数
   * */ 
  inputHandler(e){
    // e.detail.value 中包含了发生变化后,文本框中最新的值
    console.log(e.detail.value)
  },

wxml

<!-- 通过 bindinput 绑定输入事件 -->
<input bindinput="inputHandler"></input>

实现文本框和 data 之间的数据同步

        为输入框绑定输入事件,向输入框中输入数据时,将数据同步给 data 中定义的变量

js

  /**
   * 页面的初始数据
   */
  data: {
    msg:"你好!"
  },

  /**
   * 输入事件处理函数
   * */ 
  inputHandler(e){
    this.setData({
      msg:e.detail.value
    })
  },

wxml

<!-- 通过 bindinput 绑定输入事件 -->
<!-- 通过 value 设置输入框的初始值 -->
<input value="{{msg}}" bindinput="inputHandler"></input>

wxss

input{
  border: 1px solid red;
  padding: 5px;
  margin: 5px;
  border-radius: 3px;
}

条件渲染(根据一定条件进行渲染)

        男,女,保密只能渲染一个,根据 data 中定义的变量来判断渲染哪个数据

js

  /**
   * 页面的初始数据
   */
  data: {
    type:1
  },

wxml

<!-- === 表示数据,类型均相等 -->
<!-- wx:if wx:elif wx:else 来进行条件渲染-->
<view wx:if="{{type===1}}">男</view>
<view wx:elif="{{type===2}}">女</view>
<view wx:else>保密</view>

使用 block 包装组件(单纯的容器)

        对外层的容器或组件进行条件判断,如果为 true 则所有子元素内容都渲染,如果为 false 则所有子元素内容都不渲染

wxml

<!-- block 不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何的渲染 -->
<block wx:if="{{false}}">
  <view>1</view>
  <view>2</view>
</block>

使用 hidden 进行条件渲染

hidden 表示隐藏,值为 true 隐藏,为 false 显示

wxml

<!-- hidden 表示隐藏,值为 true 隐藏,为 false 显示 -->
<view hidden="{{true}}}">hello</view>

列表渲染

        获取列表中的数据,循环渲染重复的组件结构

js

  /**
   * 页面的初始数据
   */
  data: {
    array:['张三','李四','王五']
  },

wxml

<!-- 通过 wx:for 指定数组,循环渲染重复的组件结构 -->
<!-- 当前遍历到的元素的索引用 index 获取,元素用 item 获取 -->
<!-- 通过 wx:key 为渲染出来的列表项指定唯一的key值,从而提高渲染效率 -->
<view wx:for="{{array}}" wx:key="{{index}}">
  索引是:{{index}},元素是{{item}}
</view>

导入外联样式表

        通过 @import 导入外联样式表

@import "/common/common.wxss";

window 节点常用的配置项

以下配置项在每个页面单独的 .json 配置文件中都可使用,为页面进行特殊配置

设置导航栏的背景色

        在全局配置文件 app.json 中找到 window - navigationBarBackgroundColor ,进行修改

app.json

  "window": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "Weixin",
    //设置导航栏的背景色
    "navigationBarBackgroundColor": "#2b4b6b"
  },

设置导航栏的标题内容

        在全局配置文件 app.json 中找到 window - navigationBarTitleText,进行修改

app.json

  "window": {
    "navigationBarTextStyle": "black",
    //设置导航栏的标题内容
    "navigationBarTitleText": "雨林小程序",
    "navigationBarBackgroundColor": "#2b4b6b"
  },

设置导航栏的标题颜色

         在全局配置文件 app.json 中找到 window - navigationBarTextStyle,进行修改,注意目前只支持黑色 black 和白色 white 

app.json

  "window": {
    //设置导航栏的标题颜色
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "雨林小程序",
    "navigationBarBackgroundColor": "#2b4b6b"
  },

开启下拉刷新效果

        开启该功能我们可以通过下拉页面的方式,刷新(重新获取)小程序中的内容。通过在全局配置文件 app.json 的  window 部分添加 "enablePullDownRefresh" 属性开启

app.json

  "window": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "雨林小程序",
    "navigationBarBackgroundColor": "#2b4b6b",
    //设置导航栏的下拉刷新效果
    "enablePullDownRefresh": true
  },

设置下拉刷新时窗口的背景色

        通过在全局配置文件 app.json 的  window 部分添加 "backgroundColor" 属性开启

app.json

  "window": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "雨林小程序",
    "navigationBarBackgroundColor": "#2b4b6b",
    "enablePullDownRefresh": true,
    //设置导航栏下拉刷新时的背景色
    "backgroundColor": "#efefef"
  },

设置下拉刷新时 loading(加载) 的样式

        通过在全局配置文件 app.json 的  window 部分添加 "backgroundTextStyle" 属性开启,注意目前仅支持 dark 和 light 

app.json

  "window": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "雨林小程序",
    "navigationBarBackgroundColor": "#2b4b6b",
    "enablePullDownRefresh": true,
    "backgroundColor": "#efefef",
    //设置下拉刷新时加载的样式
    "backgroundTextStyle": "dark"
  },

设置上拉触底的距离(一般默认即可)

        设置当用户在进行上拉操作获取数据时,在拉取多少距离后开始自动加载后面的数据,默认是 50 px ,一般没有特殊要求不建议修改,在全局配置文件 app.json 的  window 部分添加 "onReachBottomDistance" 属性开启

app.json

  "window": {
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "雨林小程序",
    "navigationBarBackgroundColor": "#2b4b6b",
    "enablePullDownRefresh": true,
    "backgroundColor": "#efefef",
    "backgroundTextStyle": "dark",
    /*设置上拉触底的距离*/
    "onReachBottomDistance": 100
  },

下拉刷新

监听用户下拉动作

        通过页面相关事件处理函数( onPullDownRefresh() )--监听用户下拉动作

        点击 +1 按钮增加 count 的值

        下拉刷新,将 count 的值改为 0

wxml

<text>首页</text>
<view>count: {{count}}</view>
<button bind:tap="addCount" type="primary">+1</button>

js

  /**
   * 页面的初始数据
   */
  data: {
    count:0
  },

  /**
   * 增加 count 的值
   */
  addCount(){
    this.setData({
      count:this.data.count+1
    })
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    //当用户下拉时,将 count 的值重置为 0 
    this.setData({
      count:0
    })
  },

停止下拉刷新效果(刷新完成,自动停止)

        上面我们制作的下拉刷新效果存在刷新窗口一直存在的问题,我们需要在刷新的处理函数执行好后,停止刷新效果。

        通过 wx.stopPullDownRefresh() 方法停止刷新效果

js

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    //当用户下拉时,将 count 的值重置为 0 
    this.setData({
      count:0
    })
    //停止下拉刷新
    wx.stopPullDownRefresh()
  },

上拉触底

        上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为

上拉触底案例

上拉触底-刷新数据效果

案例步骤:

        1.定义获取随机颜色的方法(主要知识:发送网络请求,接收和利用响应数据)

        2.在页面加载时获取初始数据

        3.渲染 UI 结构并美化页面效果

        4.在上拉触底时调用获取随机颜色的方法、

        5.添加 loading 提示效果(在获取数据时提示用户等待)

        6.对上拉触底进行节流处理(用户可能频繁上下滑动,多次经过上拉触底的临界点,频繁发送请求,对于这个情况要加以限制)

wxml

<text>首页</text>
<!-- style:内联地定义元素的样式,在 css 中获取不到 colorList 中的数据内容-->
<view class="colorPiece" wx:for="{{colorList}}" wx:key="index" style="background-color: rgb({{item}});">
{{item}}</view>

wxss

.colorPiece{
  /* 设置边框 */
  border: 2rpx solid #efefef;
  /* 设置圆角 */
  border-radius: 10rpx;
  /* 设置行高 */
  line-height: 200rpx;
  /* 设置外边距 */
  margin: 20rpx;
  /* 设置文本位置(文本居中) */
  text-align: center;
  /* 设置文本阴影 */
  text-shadow: 0rpx 0rpx 5rpx #fff;
  /* 设置盒子阴影(view 模块) */
  box-shadow: 1rpx 1rpx 6rpx #aaa;
}

js

  /**
   * 页面的初始数据
   */
  data: {
    //存储随机颜色数据的列表
    colorList:[],
    //为了避免多次触碰上拉触底的临界值,导致一瞬间发送多条网络请求这个问题
    //定义一个节流阀,false 表示当前没有发送请求获取数据,true 表示当前正在发送请求获取数据
    isLoading:false
  },

  /**
   * 发起网络请求,从服务器获取颜色数据
   */
  getColors(){
    //发送网络请求,将 isLoading 设为 true 进行标识
    this.setData({
      isLoading:true
    })
    this.data.isLoading
    //发送请求向服务器获取数据需要用户等待一段时间,显示等待标志
    wx.showLoading({
      title: '客官请稍等...',
    })
    wx.request({
      //服务器的 URL
      url: 'https://applet-base-api-t.itheima.net/api/color',
      //https 请求的类型
      method:'GET',
      //成功接收到响应的处理逻辑
      //res 中是所有的响应内容
      success:(res)=>{
        this.setData({
          //res.data 表示获取响应内容,res.data.data 表示获取响应内容中 data 变量里的内容
          //... 是展开语法只能用于数组或可迭代对象,获取数组中的所有数据
          colorList:[...this.data.colorList,...res.data.data]
        })
      },
      //当请求完成以后将等待标志关闭
      complete:()=>{
        wx.hideLoading()
        //请求完成,设置 isLoading 标识为 false
        this.setData({
          isLoading:false
        })
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    //在页面一加载就去获取颜色数据
    this.getColors()
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    //在调用 getColors() 方法发送网络请求前先判断,当前是否已经发送了网络请求
    if(this.data.isLoading) return
    this.getColors()
  },

tabBar 配置页面跳转标签

tabBar 页面跳转标签的组成部分

        tabBar 节点的配置项(标红的配置必须有)

配置页面跳转标签 tab

每个 tab 标签的配置选项(标红的配置必须有)

        在全局配置文件 app.json 中配置 tabBar 

app.json

  "tabBar": {
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页",
        "iconPath": "/image/home.png",
        "selectedIconPath": "/image/home-active.png"
      },{
        "pagePath": "pages/userMessage/userMessage",
        "text": "我的",
        "iconPath": "/image/useMessage.png",
        "selectedIconPath": "/image/useMessage-active.png"
      },{
        "pagePath": "pages/contact/contact",
        "text": "联系我们",
        "iconPath": "/image/contact.png",
        "selectedIconPath": "/image/contact-active.png"
      }     
    ]
  },

网络数据请求

        微信小程序要先在管理后台配置服务器域名,才能给该域名服务器发送请求

1.首先登录微信小程序管理后台,在开发处找到开发管理

2.在开发设置中向下拉

3.找到服务器域名,点击修改,配置服务器域名

4.将域名输入到 request 合法域名即可

发起 GET 请求

wxml

<button bind:tap="getRequest">发起 GET 请求</button>

js

  /**
   * 发送 GET 请求
   */
  getRequest(){
    wx.request({
      url: 'https://applet-base-api-t.itheima.net/api/get',// 请求的地址,必须基于 https 协议
      method:'GET', // 请求的方式
      data:{  // 请求发送给服务器的数据
        name:'zs',
        age:22
      },
      success:(rep)=>{  // 请求成功后得到的响应结果
        console.log(rep.data)
      }
    })
  },

        将类型 GET 改成 POST 即可发送 POST 请求

        关于 GET 和 POST 类型的区别推荐看认识HTTP请求

页面加载时便请求数据

        有很多情况下,我们需要在页面刚加载时,自动请求一些初始化的数据。此时需要在页面的 ,.js 文件的 onLoad 事件中调用获取数据的函数

wxml

<button>发起 GET 请求</button>

js

  /**
   * 发送 GET 请求
   */
  getRequest(){
    wx.request({
      url: 'https://applet-base-api-t.itheima.net/api/get',// 请求的地址,必须基于 https 协议
      method:'GET', // 请求的方式
      data:{  // 请求发送给服务器的数据
        name:'zs',
        age:22
      },
      success:(rep)=>{  // 请求成功后得到的响应结果
        console.log(rep.data)
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getRequest()
  },

滚动选择器

普通选择器

wxml

<view class="section">
  <view class="section__title">普通选择器</view>
  <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
    <view class="picker">
      当前选择:{{array[index]}}
    </view>
  </picker>
</view>

js

  data: {
    array: ['', '中国', '巴西', '日本'],
    objectArray: [
      {
        id: 0,
        name: '美国'
      },
      {
        id: 1,
        name: '中国'
      },
      {
        id: 2,
        name: '巴西'
      },
      {
        id: 3,
        name: '日本'
      }
    ],
    index: 0,
  },

页面导航

导航到 tabBar 页面

        点击 导航到 ”我的“页面

        跳转到 ”我的“ 页面

wxml

<text>首页</text>
<!-- url 是要跳转的页面地址,必须以 / 开头 -->
<!-- open-type 表示跳转的方式,必须为 switchTab -->
<navigator url="/pages/userMessage/userMessage" open-type="switchTab">导航到 ”我的“页面</navigator>

导航到非 tabBar 页面

        点击 导航到 ”练习“页面

        跳转到 ”练习“ 页面

wxml

<text>首页</text>
<!-- url 是要跳转的页面地址,必须以 / 开头 -->
<!-- open-type 表示跳转的方式,为 navigate ,也可以直接不写该属性 -->
<navigator url="/pages/exercise/exercise" open-type="navigate">导航到 ”练习“页面</navigator>

导航到上一页(后退导航)

        从首页导航到练习页,在练习页点击”后退到上一页“

返回到首页

wxml

<text>练习</text>
<!-- open-type 为 navigateBack 表示后退导航 -->
<!-- delta 的值是数字,表示后退的层级,默认为 1 -->
<navigator open-type="navigateBack" delta="1">后退到上一页</navigator>

页面导航 - 编程式导航

导航到 tabBar 页面

wx.switchTab()方法的参数

        点击按钮

        跳转到”我的“页面

wxml

<text>首页</text>
<button bind:tap="gotoMy">跳转到”我的“页面</button>

js

  /**
   * 跳转到”我的“页面
   * 使用 wx.switchTab() 方法可以指定跳转到 tabBar 页面
   */
  gotoMy(){
    wx.switchTab({
      url: '/pages/userMessage/userMessage',
    })
  },

导航到非 tabBar 页面

wx.navigateTo() 方法的相关参数

点击按钮

跳转到练习页面

wxml

<text>首页</text>
<button bind:tap="gotoExercise">跳转到”练习“页面</button>

js

  /**
   * 跳转到练习页面
   * 使用 wx.navigateTo() 方法可以导航到非 tabBar 页面
   */
  gotoExercise(){
    wx.navigateTo({
      url: '/pages/exercise/exercise',
    })
  },

后退导航

wx.navigateBack() 方法相关的参数

从首页跳转到练习页,然后在练习页点击后退到上一页

成功后退回首页

wxml

<text>练习</text>
<button bind:tap="gotoBack">后退到上一页</button>

js

  /**
   * 后退到上一页
   * 使用 wx.navigateBack() 方法可以导航到上一页
   */
  gotoBack(){
    wx.navigateBack({
      delta:1
    })
  },

页面导航 - 导航传参

声明式导航传参

点击跳转到”练习“页面

跳转到练习页面后在左下角的位置能够查看传递的页面参数

wxml

<text>首页</text>
<!-- 跳转到”练习“页面时携带参数 -->
<navigator url="/pages/exercise/exercise?name=zhsangsan&age=20">跳转到”练习“页面</navigator>

编程式导航传参

点击跳转到”练习“页面

跳转到练习页面后在左下角的位置能够查看传递的页面参数

wxml

<text>首页</text>
<button bind:tap="gotoExercise">跳转到”练习“页面</button>

js

  /**
   * 跳转到练习页面
   * 使用 wx.navigateTo() 方法可以导航到非 tabBar 页面
   */
  gotoExercise(){
    wx.navigateTo({
      url: '/pages/exercise/exercise?name=zhangsan&age=20',
    })
  },

接收导航参数

点击跳转到”练习“页面,向练习页面传了参数

将传给练习页面的参数内容放到练习页面 js 文件的 data 中,方便使用

练习页面的 js 文件

  /**
   * 页面的初始数据
   */
  data: {
    name:{},
    age:{}
  },


  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // options 对象中保存了传递给页面的参数,可以从中获取,赋值给 data 中的变量,方便在其他地方使用
    this.setData({
      name:options.name,
      age:options.age
    })
  },

生命周期函数

应用生命周期函数

页面生命周期函数

WXS 脚本

        js 文件中的函数不能在 wxml 文件中使用,我们通过在 wxml 中内嵌 wxs 脚本,可以在 wxml 中使用 wxs 脚本定义的函数(方法),帮助渲染 UI 结构

内嵌 wxs 脚本

        定义一个 wxs 脚本,将小写数据全变为大写再进行渲染

wxml

<text>首页</text>
<view>{{userName}}</view>
<view>{{upper.toUpper(userName)}}</view>

<!-- 每个 wxs 标签必须提供 module 属性 作为当前 wxs 的模块名称 -->
<wxs module="upper">
//通过 module.exports 向外共享成员
// toUpper=function(str) 表示向外共享的成员 toUpper 是一个参数为 str 的 函数
  module.exports.toUpper=function(str){
    return str.toUpperCase()
  }
</wxs>

js

  /**
   * 页面的初始数据
   */
  data: {
    userName:"zhangsan"
  },

外联 wxs 脚本

        定义一个 .wxs 文件,在该文件中定义和共享 toLower 函数,将大写数据全变为小写再进行渲染

wxml

<text>首页</text>
<view>{{userName}}</view>
<view>
  {{lower.toLower(userName)}}
</view>

<!-- 这里要写 .wxs 文件的相对路径 ../ 表示上级目录 -->
<wxs src="../../utils/tools.wxs" module="lower"></wxs>

wxs

//定义了一个将字符串变成小写的方法
function toLower(str){
  return str.toLowerCase()
}
//向外共享 toLower 方法
module.exports={
  toLower:toLower
}

通过 wxs 脚本修改电话格式

没有使用 wxs 脚本的格式

使用了 wxs 脚本的格式

消息提示框

        wx.showToast 是一种轻量级的反馈,常用于展示操作结果或者给用户一些简短的提示信息。

        使用 wx.showToast 时,你可以设置不同的参数来定制 Toast 的外观和行为。以下是一些常用的参数:

  • title:提示的内容
  • icon:显示的图标,有效值包括 "success", "loading", "none"
  • image:自定义图标的本地文件路径,当设置了 image 时,icon 参数会被忽略
  • duration:提示的延迟时间,单位毫秒,默认 1500
  • mask:是否显示透明蒙层,防止触摸穿透,默认 false
  • success:接口调用成功的回调函数
  • fail:接口调用失败的回调函数
  • complete:接口调用结束的回调函数(调用成功、失败都会执行)

js

wx.showToast({  
  title: '操作成功',  
  icon: 'success',  
  duration: 2000  
});

wxml

<text>{{tools.splitPhone(item.phone)}}</text>
<wxs src="../../utils/tools.wxs" module="tools"/>

wxs

function splitPhone(phone){
  if(phone.length!=11){
    return phone
  }

  //将电话号码字符串拆分成一个字符数组
  var phoneArr=phone.split('')

  //数组的 splice 方法用于在数组中添加或删除元素,第一个参数:要改变的位置,第二个参数:要删除的元素个数,第三个参数:要添加的元素
  phoneArr.splice(3,0,'-')
  phoneArr.splice(8,0,'-')

  //将数组的所有元素连接到一个字符串中,参数表示分隔符,会插入到两个元素之间
  return phoneArr.join('')
}

//向外共享方法
module.exports={
  splitPhone:splitPhone
}

自定义组件

创建组件文件

        点击新建文件夹,创建一个 components 文件,用来放置所有的组件文件,在 components 文件下右键新建一个 test 文件作为组件文件右键 test 文件点击新建 Component 创建组件文件应该有的各种.js .json .wxml .wxss 文件

局部引入组件

        局部引入组件后,只有引入组件的页面可以使用组件

        在页面的 .json 配置文件的 "usingComponents" 配置项中输入组件的名称(自定义)和组件的路径,配置好以后便可以在当前页面的 .wxml 文件中使用

wxml

<text>首页</text>
<view></view>
<my-test1></my-test1>

.json

{
  "usingComponents": {
    "my-test1":"/components/test/test"
  }
}

全局引入组件

        全局引入组件后,所有的页面都可以使用组件

        在全局的 app.json 配置文件的 "usingComponents" 配置项中输入组件的名称(自定义)和组件的路径,配置好以后便可以在所有页面的 .wxml 文件中使用

wxml

<text>首页</text>
<view></view>
<my-test1></my-test1>

app.json

  "usingComponents": {
    "my-test1":"/components/test/test"
  },

自定义组件的样式隔离选项

        默认情况下组件的样式隔离能够防止组件内外相互干扰的问题(页面的样式配置无法影响组件,组件的样式配置也无法影响页面),但有时我们也希望在外界能够影响组件内部的样式,或者组件内部的样式能够影响外界,我们就可以通过 styleIsolation 修改组件的样式隔离选项

styleIsolation 的相关选项

在组件的 .js 文件中添加如下配置:

  options:{
    styleIsolation:"isolated"
  }

或在组件的 .json 文件中添加如下配置:

"styleIsolation": "isolated"

自定义主键的数据和方法定义

        定义一个组件,使用该组件就能直接在页面中得到一个 count 数据的展示和 +1 按钮,点击 +1 按钮,count 数据增加,弹出提示

页面的 .wxml 文件

        可以看到只是简单的使用了自定义的 my-test1 组件

<!--pages/home/home.wxml-->
<text>首页</text>
<view></view>
<my-test1></my-test1>

组件的 .wxml 文件

<view>count:{{count}}</view>
<button bind:tap="addCount" type="primary">+1</button>

组件的 .js 文件

  /**
   * 组件的初始数据
   */
  data: {
    count:0
  },

  /**
   * 组件的方法列表
   */
  methods: {
    addCount(){
      this.setData({
        count:this.data.count+1
      })
      this._showHint()
    },
    //自定义方法推荐以 _ 开头,方便区别事件处理函数和自定义方法的区别
    _showHint(){
      wx.showToast({
        title: 'count:'+this.data.count,
        icon:"none"
      })
    }
  }

自定义组件传参以及参数获取

        设置参数 max 为 6,在 count 为 6 时点击 +1 count 值不再改变

        在组件的 .js 文件中通过 properties 选项来创建属性,用于接收外界传给组件的参数。

        在使用自定义组件时向组件传入一个 max 参数,限制 count 的最大值

 页面的 .wxml 文件

<text>首页</text>
<view></view>
<!-- 使用自定义组件 my-test1 传入 max 参数,表示 count 的最大值 -->
<my-test1 max="6"></my-test1>

组件的 .wxml 文件

<view>count:{{count}}</view>
<button bind:tap="addCount" type="primary">+1</button>

组件的 .js 文件

Component({
  /**
   * 组件的属性列表
   */
  //通过 properties 选项来创建属性,用于接收外界传给组件的参数
  properties: {
    //完整定义属性的方式,type 表示类型,value 表示默认值
    max:{
      type:Number,
      value:10
    },
    //简化定义属性的方式,age 是属性名,Number 是属性类型
    max:Number
  },

  /**
   * 组件的初始数据
   */
  data: {
    count:0
  },

  /**
   * 组件的方法列表
   */
  methods: {
    addCount(){
      //判断 count 值是否已经达到最大值(用户传入的参数)
      if(this.data.count>=this.properties.max){
        return
      }
      this.setData({
        count:this.data.count+1
      })
      this._showHint()
    },
    //自定义方法推荐以 _ 开头,方便区别事件处理函数和自定义方法的区别
    _showHint(){
      wx.showToast({
        title: 'count:'+this.data.count,
        icon:"none"
      })
    }
  }
})

使用数据监听器

        通过在 .js 文件中使用 observers 选项来使用数据监听器,监听哪些数据项发生变化,并获得变化后的数据,进行相应的处理

        如下视频,监听变量一 n1 和变量二 n2 的值,监听 n1 和 n2 值发生改变后,计算 n1 + n2 的结果,赋值给 sum

数据监听器

 页面的 .wxml 文件

<text>首页</text>
<view></view>
<!-- 使用自定义组件 my-test1 -->
<my-test1></my-test1>

组件的 .wxml 文件

<view>{{n1}}+{{n2}}={{sum}}</view>
<button type="primary" bind:tap="addN1">变量一 + 1</button>
<button type="primary" bind:tap="addN2">变量二 + 1</button>

组件的 .js 文件

Component({
  /**
   * 组件的属性列表
   */
  //通过 properties 选项来创建属性,用于接收外界传给组件的参数
  properties: {
  
  },

  /**
   * 组件的初始数据
   */
  data: {
    n1:0,
    n2:0,
    sum:0
  },

  /**
   * 组件的方法列表
   */
  methods: {
    //增加 n1 数据
    addN1(){
      this.setData({
        n1:this.data.n1+1
      })
    },
    //增加 n2 数据
    addN2(){
      this.setData({
        n2:this.data.n2+1
      })
    }
  },
  //数据监听器
  observers:{
    //监听 n1 和 n2 数据的变化
    'n1,n2':function(n1,n2){
      //当 n1 和 n2 的数据发生变化后,修改 sum 的数据
      this.setData({
        sum:this.data.n1+this.data.n2
      })
    }
  }
})

监听对象中指定属性的变化

        如下代码,监听了 rgb 对象中 r,g,b 属性的变化,并进行相应的操作

监听对象中所有属性的变化

        去一个个监听对象中的属性比较麻烦,可以通过 .** 监听对象中的所有属性,属性改变后的值放到 obj 对象中,通过参数对象 . 属性名得到改变的值

纯数据字段

        如果自定义组件的 data 中某些字段不用于界面渲染,也不传递给其他组件,这些字段就适合被定义为纯数据字段,纯数据字段有助于提高页面更新的性能

        在组件 .js 文件与 data 同级写一个 option 选项,option 选项的 pureDataPattern 属性可以通过正则表达式指定纯数据字段的格式,data 中满足这个格式的字段就是纯数据字段

组件的生命周期函数

        自定义组件有如下生命周期函数

        通过在组件的 .js 文件中与 data 同级别的 lifetimes 选项中使用

组件的 .js 文件

 lifetimes:{
    created(){
      console.log('组件创建')
    },
    attached(){
      console.log('组件进入页面,但还没渲染')
    },
    ready(){
      console.log('组件在页面上渲染完毕')
    }
  },

组件所在页面的生命周期

        有时候自定义组件需要监听所在页面的状态,当页面状态发生变化时组件需要进行一定的操作,比如当页面刚被展示时,组件的颜色便随机刷新。

        通过在组件的 .js 文件与 data 平级的 pageLifetimes 中使用

        组件监听所在页面的生命周期函数有以下三个:

  /**
   * 组件所在页面的生命周期函数
   */
  pageLifetimes:{
    //在页面被展示时,组件执行的操作
    show:function(){
      
    },
    //在页面被隐藏时,组件执行的操作
    hide:function(){
      
    },
    //在页面的尺寸发生变化时,组件执行的操作
    resize:function(size){
      
    }
  },

组件所在页面的生命周期案例

        现在我们有一个组件是一个色块,我们这个组件需要监听组件所在的页面是否被展示,当页面被展示时,随机更改组件的颜色

组件的 .wxml 文件

<view style="background-color: rgb({{color.r}}, {{color.g}}, {{color.b}});" class="colorLump">({{color.r}},{{color.g}},{{color.b}})</view>

组件的 .wxss 文件

.colorLump{
  color: white;
  line-height: 200rpx;
  text-align: center;
}

组件的 .js 文件

  /**
   * 组件所在页面的生命周期函数
   */
  pageLifetimes:{
    //在页面被展示时,组件执行的操作
    show:function(){
      //在页面展示时改变 data 中的 color 对象
      this.chageColor()
    },
    //在页面被隐藏时,组件执行的操作
    hide:function(){
      
    },
    //在页面的尺寸发生变化时,组件执行的操作
    resize:function(size){
      
    }
  },
  /**
   * 组件的初始数据
   */
  data: {
    // color 对象的 r,g,b 属性表示色块的颜色
    color:{
      r:0,
      g:0,
      b:0
    }
  },

  /**
   * 组件的方法列表
   */
  methods: {
    chageColor(){
      //在页面展示时改变 data 中的 color 对象
      this.setData({
        color:{
          r:Math.floor((Math.random()*256)),
          g:Math.floor((Math.random()*256)),
          b:Math.floor((Math.random()*256))
        }
      })
    }
  },

单个插槽

        插槽的意思就是,在组件中的某些地方,并不知道使用者要放的内容是什么,所以使用一个 slot 标签来进行占位,让用户可以随意在该处放置内容

        在小程序中,默认每个自定义组件只允许使用一个 <slot>  进行占位,这种个数上的限制叫做单个插槽

组件的 .wxml 文件

<view>
  <view>这是组件内部</view>
  <!-- 对于不确定的内容,可以用 slot 标签进行占位,具体内容由组件的使用者来确定 -->
  <slot></slot>
</view>

页面的 .wxml 文件

<text>首页</text>
<view></view>
<!-- 使用自定义组件 test -->
<my-test>
  <view>用户自定义占位符处的内容</view>
</my-test>

多个插槽

        默认情况下我们在组件中只能定义一个插槽,但如果我们需要定义多个插槽,也可以通过在组件的 .js 文件中配置 options 选项的属性 multipleSlots 为 true 

        在定义多个插槽时,要通过 name 属性来进行区分,在页面中使用插槽时,通过 slot 属性来指定该内容放置的插槽

组件的 .js

  options:{
    //开启多个插槽
    multipleSlots:true
  },

组件的 .wxml 文件

<view>
  <!-- 对于不确定的内容,可以用 slot 标签进行占位,具体内容由组件的使用者来确定 -->
  <!-- 定义多个插槽时,使用 name 来进行区分 -->
  <!-- 定义 name 为 before 的插槽 -->
  <slot name="before"></slot>
  <view>这是组件内部</view>

  <!-- 定义 name 为 after 的插槽 -->
  <slot name="after"></slot>
</view>

页面的 .wxml 文件

<text>首页</text>
<view></view>
<!-- 使用自定义组件 test -->
<my-test>
<!-- 在向插槽中放置内容时,使用 slot 属性指定该内容要放置的插槽 name -->
  <view slot="before">before 占位符处的内容</view>
  <view slot="after">after 占位符处的内容</view>
</my-test>

父子组件之间的通信 - 父向子传值

        通过属性绑定来实现父向子传值,但只能传输数据,不能传输方法

        页面为父组件,我们自定义的组件 my-test 为子组件,通过向子组件传参的方式,将页面 data 中定义的变量的值传给子组件

组件的 .js 文件

  //通过 properties 选项来创建属性,用于接收外界传给组件的参数
  properties: {
    userName:String
  },

组件的 .wxml 文件

<view>
  <view>这是组件内部</view>
  <view>组件内部得到 userName 为 {{userName}}</view>
</view>

页面的 .wxml 文件

<text>首页</text>
<view></view>
<!-- 使用自定义组件 test -->
<!-- 向自定义组件中传一个参数 userName -->
<view>
  页面中 userName 定义为 {{userName}}
</view>
<my-test userName="{{userName}}"></my-test>

父子组件之间的通信 - 子向父传值

同步数据

通过事件绑定实现子向父传值,可以传递任何类型的数据

        核心就是通过自定义事件绑定,使在子组件中可以调用父组件中自定义事件绑定的事件处理函数,也可以为该事件处理函数传递参数,就可以利用传递函数参数来向父组件传递数据

        下面通过一个同步父子组件数据的例子来介绍过程,我们要在改变子组件中 count 数据时同步修改父组件中的 count 数据

首先在父组件中使用子组件时,为子组件绑定一个自定义事件

<text>首页</text>
<view></view>
<view>页面中的 count 值:{{count}}</view>
<!-- 使用自定义组件 my-test -->
<!-- 通过 bind:事件名称 为子组件绑定一个自定义事件 -->
<my-test bind:sync="syncCount"></my-test>

        在子组件的 .js 文件中,在子组件的 count 值增加以后调用自定义事件 sync ,来执行父组件中定义的事件处理函数 syncCount ,并且为该事件处理函数传参

  /**
   * 组件的初始数据
   */
  data: {
    count:0
  },

  /**
   * 组件的方法列表
   */
  methods: {
    addCount(){
      this.setData({
        count:this.data.count+1
      })
      //通过 this.triggerEvent('自定义事件名称',{参数对象}) 的方式调用父组件中绑定自定义事件的函数并且给函数传参
      this.triggerEvent('sync',{value:this.data.count})
    }
  },

        在父组件的 .js 文件中定义事件处理函数 syncCount ,在子组件调用时,用子组件传来的参数 value 值来更新 data 中的 count 值

  /**
   * 页面的初始数据
   */
  data: {
    count:0
  },

  /**
   * 自定义事件处理函数
   * 用于同步 count 值
   */
  //子组件传来的参数用 e 形参接收,在 e.detail 中
  syncCount(e){
    console.log(e)
    this.setData({
      count:e.detail.value
    })
  },

 访问子组件的任意数据和方法

        通过定义在主页中的按钮,可以修改组件中的 count 值

        在父组件里调用 this.selectComponent(" id 或 class 选择器"),获取子组件的实例对象,从而直接访问子组件的任意数据和方法

主页的 .wxml 文件

<!-- 使用自定义组件 my-test -->
<my-test class="my-test"></my-test>
<button type="primary" bind:tap="addCount">count+1(位于主页)</button>

主页的 .js 文件

 //增加子组件中的 count 值
  addCount(){
    //获取类名为 my-test 的子组件实例
    const child= this.selectComponent('.my-test')
    //通过子组件实例 child 可以调用子组件中的数据和方法
    child.setData({
      count:child.data.count+1
    })
  },

组件的 .wxml 代码

<view>
  <view>组件中的 count 值:{{count}}</view>
</view>

组件间代码共享

        通过 behaviors ,可以实现组件间代码共享,每个 behaviors  可以包含一组属性,数据,生命周期函数和方法。组件引用它时,它的属性,数据,生命周期函数和方法会被合并到组件中、

        在 .js 文件中,调用 Behavior( Object object ) 方法即可创建一个共享的 behavior 实例对象,供所有的组件使用

behavior 中可用的节点(组件间可用共享的节点)

创建 behavior

        创建一个 behaviors 文件夹,在文件夹下创建一个 .js 文件用于定义 behaviors

.js 文件

//通过在 .js 文件中调用 Behavior 方法来创建 behavior 对象,用于共享组件的通用代码
//通过 module.exports 将 behavior 共享出去
module.exports=Behavior({
  //公共数据
  data:{
    name:"zhangsan"
  },
  //公共属性
  properties:{

  },
  公共方法
  methods:{

  }
})

导入并使用 behavior

        在组件中,使用 require() 方法导入需要的 behavior ,通过在组件的 .js 文件中通过 behaviors 选项挂载后即可访问 behavior 中的数据和方法

组件的 .js 文件 

//导入需要的 behavior
const myBehavior=require("../../behaviors/my-behaviors")
Component({
  //将导入的 behavior 实例对象,挂载到 behaviors 数组中,即可生效
  behaviors:[myBehavior]
})

组件的 .wxml 文件

<view>
  <view>myBehavior 中的 name 属性为{{name}}</view>
</view>

使用 Vant 组件

        Vant 是一个轻量、可靠的移动端组件库,里面提供了许多小程序开发组件,能够提高小程序的开发效率

        关于  Vant 组件库的安装和使用推荐看在微信小程序项目中安装和使用 Vant 组件库

定制 Vant 组件样式

        通过设置 css 变量可以定制 Vant 组件的样式

        我们可以在小程序的 app.wxss 文件下的 page 标签选择器中设置 css 变量,这样设置的 css 变量是作用于小程序所有页面的(因为小程序每个页面的根标签都是 page)

        现在我们已经在 .wxml 中使用了两个按钮组件

<van-button type="default">默认按钮</van-button>
<van-button type="primary">主要按钮</van-button>

        我们想自定制“主要按钮“的颜色,在 app.wxss 中设置 css 变量

/* page 是每个页面的根标签,在这个标签中设置 CSS 变量可以作用于所有的页面 */
page{
  --button-primary-background-color:#dc9f46;
  --button-primary-border-color: #dc9f46;
}

        我们如何知道 Vant 组件有哪些 css 变量呢?在官网就能找到

        在 Vant 组件的官网,我们选择定制主题,点击配置文件链接

        就能看到所有 Vant 组件可定制的 CSS 变量(注意在 css 变量名前要加 --

小程序 api 的 promise 化

        让基于回调函数的 api 进行 promise 化可以使代码可读性增强,避免回调地狱,代码复用性提高等好处,Promise 和 async/await 已经成为现代 JavaScript 开发中的标准做法

首先安装  miniprogram-api-promise 第三方 npm 包,实现 API Promise 化主要依赖于这个包

        1.在微信开发者工具文件目录的空白处右键,点击在外部终端窗口中打开,在命令行窗口输入以下指令

npm i --s miniprogram-api-promise@1.0.4

       2.构建 npm ,在右上角点击工具,选择构建 npm

        在 miniprogram_npm 文件下我们可以看到,这个包已经安装好了

        3.API Promise 化

        在 app.js 文件中,与 App() 选项同级的位置输入如下代码

import{promisifyAll}from 'miniprogram-api-promise'
const wxp=wx.p={}
promisifyAll(wx,wxp)


App({...})

调用 Promise 化后的异步 API

将发起网络请求获取数据的方法进行 Promise 化

.js 文件

        通过回调函数的方法发生网络请求使用 wx.request() 方法,Promise 化后通过 wx.p.request 发送网络请求,并且在方法前和发起请求前用 async 和 await 修饰

  async getInfo(){
    const res=await wx.p.request({
      method:'GET',
      url:'https://applet-base-api-t.itheima.net/api/get',
      data:{
        name:'zs',
        age:18
      }
    })

    console.log(res)
  },

全局数据共享

        有一些数据可能小程序的很多组件和页面都需要用到,传递起来就很麻烦,所以可以用 mobx 相关的包来实现全局数据共享

        mobx-miniprogram 用来创建 Store 实例对象( Store 实例对象用于存储全局的数据或方法)

        mobx-miniprogram-bindings 用来将 Store 中存储的数据和方法,绑定到组件或页面中使用

安装 mobx 相关的包

        1.在项目文件目录的空白处右键选择 “在外部终端窗口中打开” ,在命令行中输入以下命令,安装 mobx 相关的两个包

npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1

        2.构建 npm ,在右上角点击工具,选择构建 npm,在 miniprogram_npm 文件下找到我们刚才安装的两个 mobx 相关的包就说明构建成功

创建 Store 实例

        全局的数据和方法要放到 Store 实例中

        首先创建一个 store 文件夹,在文件夹中创建一个 store.js 文件

// 在这个 .js 文件中,专门创建 store 的实例对象
//导入创建 store 实例对象的包
//{...} 中是要在包中导出的方法
// observable 是创建 store 实例对象需要用到的方法
// action 用于修改 store 中的数据
import {observable,action} from 'mobx-miniprogram'
// 通过 observable 方法创建实例对象,通过 export 导出实例对象
// 外界需要的时候可以导入这个 store 实例,使用里面的数据和方法
export const store= observable({
  // 在 observable 方法中传入的参数对象中设置全局的属性和方法
  //数据字段
  num1:10,
  num2:18,
  //计算属性
  // get 表示这个计算属性是只读的,只能通过 sum 方法获取数据,不能设置数据
  get sum(){
    return this.num1+this.num2
  },
  //修改 store 中的数据
  updateNum1:action(function(step){
    this.num1+=step
  }),
  updateNum2:action(function(step){
    this.num2+=step
  })
})

将 store 中的成员绑定到页面中

页面的 .js 文件

// 从 mobx-miniprogram-bindings 包中获取 createStoreBindings 方法
import {createStoreBindings} from 'mobx-miniprogram-bindings'
//在相对路径为'../../store/store'的文件中导出 store 实例对象
import{store}from '../../store/store'
Page({
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    //在页面加载时绑定 store 实例对象到页面上
    //this.storeBindings 接收 createStoreBindings 方法的返回值,在后面用于释放绑定时所用的资源
    this.storeBindings=createStoreBindings(this,{
      //数据源
      store,
      //属性
      fields:['num1','num2','sum'],
      //方法
      actions:['updateNum1','updateNum2']
    })
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    //当关闭页面后,要释放绑定 store 实例对象所用的资源
    this.storeBindings.detroyStoreBindings()
  }
})

在页面上使用 store 中的成员

使用store中的成员

    store 中的成员绑定到页面上以后,直接按照正常 data 中的数据和正常定义的方法使用即可

页面的 .wxml 文件

<text>首页</text>
<!-- num1,num2,sum 是 store 中的属性 -->
<view>{{num1}}+{{num2}}={{sum}}</view>
<van-button type="primary" bind:tap="changeNum" data-step="{{1}}">
  num1+1
</van-button>
<van-button type="danger" bind:tap="changeNum" data-step="{{-1}}">
  num1-1
</van-button>

页面的 .js 文件

  changeNum(e){
    // updateNum1 是 store 中的方法
    this.updateNum1(e.target.dataset.step);
  },

将 store 中的成员绑定到组件中

组件的 .js 文件

//在 mobx-miniprogram-bindings 包中导入 storeBindingsBehavior 方法,用于映射 store 中的成员
import{storeBindingsBehavior} from 'mobx-miniprogram-bindings'
// 在相对路径'../../store/store'中导入 store 数据源
import{store} from '../../store/store'

Component({
  //将 storeBindingsBehavior 方法放入 behaviors 数组中来实现自动绑定 store 中的成员
  behaviors:[storeBindingsBehavior],
  //设置 storeBindings 对象,指明要导入 store 中的哪些成员
  storeBindings:{
    //数据源
    store,
    //属性
    fields:{
      //前面是在组件中使用的名字,后面是 store 中的成员名字
      num1:'num1',
      num2:'num2',
      sum:'sum'
    },
    //方法
    actions:{
      updateNum1:'updateNum1',
      updateNum2:'updateNum2'
    }
  }
})

在组件中使用 store 中的成员

使用store中的成员

         store 中的成员绑定到组件上以后,直接按照正常 data 中的数据和正常定义的方法使用即可

组件的 .wxml 文件

<view>
  <view>{{num1}}+{{num2}}={{sum}}</view>
  <van-button type="primary" bind:tap="changeNum" data-step="{{1}}">
    num1+1
  </van-button>
  <van-button type="danger" bind:tap="changeNum"
  data-step="{{-1}}">
    num1-1
  </van-button>
</view>

组件的 .js 文件

Component({
  /**
   * 组件的方法列表
   */
  methods: {
    changeNum(e){
      this.updateNum1(e.target.dataset.step)
    }
  }
})

对小程序进行分包

        在开发小程序时由一个主包+多个分包组成

  • 主包:一般只包含项目的启动页面 TabBar 页面,以及所有分包都需要用到的公共资源
  • 分包:只包含和当前分包有关的页面和私有资源

        在小程序启动时下载主包中的内容并启动主包内页面,而分包中的内容和页面在访问时才会下载,进行分包以后减少了主包中的数据内容可以优化小程序首次启动的下载时间

app.json 文件

        “pages” 数组中放置的是主包中的页面,"subPackages" 数组中放置的是分包的页面

        "subPackages" 数组对象的属性:

        root:表示分包的根目录

        name:表示分包的别名

        pages:表示分包页面的路径

{
  "pages": [  
    "pages/home/home",
    "pages/userMessage/userMessage",
    "pages/contact/contact"
  ],
  "subPackages": [
    {
      "root": "pkgA",
      "name": "animal",
      "pages": [
        "pages/cat/cat",
        "pages/dog/dog"
      ]
    },{
      "root": "pkgB",
      "name": "fruits",
      "pages": [
        "pages/apple/apple",
        "pages/bananer/bananer"
      ]
    }
  ]
}

        创建出的分包目录

独立分包

        独立分包和普通分包的区别:独立分包不依赖主包即可运行,可以很大程度上提高分包页面的启动速度,一个小程序中可以有多个独立分包

        设置方法:在普通分包中添加 “independent” 属性即可将其设置为独立分包

        如下代码,将别名为 animal 的分包设置为独立分包,而别名为 fruits 的分包依然是普通分包

  "subPackages": [
    {
      "root": "pkgA",
      "name": "animal",
      "pages": [
        "pages/cat/cat",
        "pages/dog/dog"
      ],
      "independent": true
    },{
      "root": "pkgB",
      "name": "fruits",
      "pages": [
        "pages/apple/apple",
        "pages/bananer/bananer"
      ]
    }
  ]

配置分包的预下载

        如果在进入某个页面后,有很大的概率需要加载某些分包,我们可以配置这些分包预下载。

        预下载分包的行为,会在进入指定的页面时触发。在 app.json 中,使用 preloadRule 节点定义分包的预下载规则:

        如下代码定义了在进入 contact 页面时自动下载分包 pkgA

        根据日志可以看出在进入 contact 页面时成功预下载分包 pkgA

        

自定义 tabBar

官方文档https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html

1.配置信息

        在 app.json 中的 tabBar 项指定 custom 字段,同时其余 tabBar 相关配置也补充完整。比如 list 数组以及其中的配置都不能省略,因为如果用户版本较低无法显示自定义的 tabBar 就会用 list 数组中的设置进行显示。而且要通过 list 数组中的设置来知道哪些是 tabBar 页面

  "tabBar": {
    "custom": true,
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页",
        "iconPath": "/image/home.png",
        "selectedIconPath": "/image/home-active.png"
      },{
        "pagePath": "pages/userMessage/userMessage",
        "text": "我的",
        "iconPath": "/image/useMessage.png",
        "selectedIconPath": "/image/useMessage-active.png"
      },{
        "pagePath": "pages/contact/contact",
        "text": "联系我们",
        "iconPath": "/image/contact.png",
        "selectedIconPath": "/image/contact-active.png"
      }     
    ]
  }

2.添加 tabBar 代码文件

        在代码根目录下添加文件夹 custom-tab-bar ,在该文件夹下创建 index 组件,注意名称必须正确

3.根据 Vant 组件来自定义 tabBar

        Vant 中的 Tabbar 标签栏组件官网介绍https://vant-ui.github.io/vant-weapp/#/tabbar

引入组件

        在 app.json 或 index.json 中引入组件

"usingComponents": {
  "van-tabbar": "@vant/weapp/tabbar/index",
  "van-tabbar-item": "@vant/weapp/tabbar-item/index"
}

基础用法

        在 index 组件的 .wxml 中使用

<van-tabbar active="{{ active }}" bind:change="onChange">
  <van-tabbar-item icon="home-o">标签</van-tabbar-item>
  <van-tabbar-item icon="search">标签</van-tabbar-item>
  <van-tabbar-item icon="friends-o">标签</van-tabbar-item>
  <van-tabbar-item icon="setting-o">标签</van-tabbar-item>
</van-tabbar>

        由于需要 active 变量,和 onChange() 方法,需要在 index 组件的 .js 文件中定义

Component({
   /**
   * 组件的初始数据
   */
  data: {
    active: 0
  },
  /**
   * 组件的方法列表
   */
  methods: {
    onChange(event) {
      // event.detail 的值为当前选中项的索引
      this.setData({ active: event.detail });
    }
  }
})

        可以看到页面上已经出现了 tabBar 效果

4.根据 list 数组中定义的属性内容来批量设置 tabBar 效果

        在 index 组件的 .js 文件中的 data 节点下创建一个 list 数组,包含 tabBar 的相关属性设置

  data: {
    "list": [
      {
        "pagePath": "pages/home/home",
        "text": "首页",
        "iconPath": "/image/home.png",
        "selectedIconPath": "/image/home-active.png"
      },{
        "pagePath": "pages/userMessage/userMessage",
        "text": "我的",
        "iconPath": "/image/useMessage.png",
        "selectedIconPath": "/image/useMessage-active.png",
        "info":1
      },{
        "pagePath": "pages/contact/contact",
        "text": "联系我们",
        "iconPath": "/image/contact.png",
        "selectedIconPath": "/image/contact-active.png"
      }     
    ]
  }

        在组件的 .wxml 文件中通过 van-tabbar-item 组件循环设置 tabBar 效果

<van-tabbar active="{{ active }}" 
bind:change="onChange">
<van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info?item.info:''}}">
    <image
      slot="icon"
      src="{{item.iconPath}}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    <image
      slot="icon-active"
      src="{{item.selectedIconPath}}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    {{item.text}}
  </van-tabbar-item>
</van-tabbar>

5.在自定义组件中使用 Vant 组件,需要覆盖 Vant 组件原来的样式

        要在组件的 .js 文件中的 options 节点下设置 styleIsolation 属性,这样才能覆盖 Vant 组件原来的样式

Component({
  options: {
    styleIsolation: 'shared',
  }
});

6.实现 tabBar 页面的切换效果

        核心: tabBar 部分绑定了一个事件处理函数 onChange(),当我们选择 tabBar 标签后通过event.detail 可以获取该标签的下标,根据该标签的下标可以在 list 数组中得到对应页面的路径,通过 wx.switchTab()方法进行页面跳转, active 属性表示该标签的下标,要对 active 属性进行设置

        要注意 active 属性不能定义在 index 组件的 .js 文件中,会有 bug,要将其定义在 store 中,再将定义在 store 中的属性 active 和 改变 active 的方法 updateActive 绑定到组件中

store.js 文件

// 在这个 .js 文件中,专门创建 store 的实例对象
//导入创建 store 实例对象的包
//{...} 中是要在包中导出的方法
// observable 是创建 store 实例对象需要用到的方法
// action 用于修改 store 中的数据
import {observable,action} from 'mobx-miniprogram'
// 通过 observable 方法创建实例对象,通过 export 导出实例对象
// 外界需要的时候可以导入这个 store 实例,使用里面的数据和方法
export const store= observable({
  // 在 observable 方法中传入的参数对象中设置全局的属性和方法
  //数据字段
  active:0,
  //计算属性

  //方法
  //通过 updateActive 方法修改 active 中的数据
  updateActive:action(function(index){
    this.active=index
  })
})

组件的 .wxml 文件

<van-tabbar active="{{ active }}" 
bind:change="onChange" active-color="#13A7A0">
<van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info?item.info:''}}">
    <image
      slot="icon"
      src="{{item.iconPath}}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    <image
      slot="icon-active"
      src="{{item.selectedIconPath}}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    {{item.text}}
  </van-tabbar-item>
</van-tabbar>

组件的 .js 文件

//映射 store 中的全局数据到组件中
//在 mobx-miniprogram-bindings 包中导入 storeBindingsBehavior 方法,用于映射 store 中的成员
import{storeBindingsBehavior} from 'mobx-miniprogram-bindings'
// 在相对路径'../../store/store'中导入 store 数据源
import{store} from '../store/store'
Component({
   //将 storeBindingsBehavior 方法放入 behaviors 数组中来实现自动绑定 store 中的成员
   behaviors:[storeBindingsBehavior],
   //设置 storeBindings 对象,指明要导入 store 中的哪些成员
   storeBindings:{
     //数据源
     store,
     //属性
     fields:{
       //前面是在组件中使用的名字,后面是 store 中的成员名字
       active:'active'
     },
     //方法
     actions:{
      updateActive:'updateActive'
     }
   },
  options:{
    styleIsolation:'shared'
  },
  /**
   * 组件的属性列表
   */
  properties: {

  },

  /**
   * 组件的初始数据
   */
  data: {
    "list": [
      {
        "pagePath": "/pages/home/home",
        "text": "首页",
        "iconPath": "/image/home.png",
        "selectedIconPath": "/image/home-active.png"
      },{
        "pagePath": "/pages/userMessage/userMessage",
        "text": "我的",
        "iconPath": "/image/useMessage.png",
        "selectedIconPath": "/image/useMessage-active.png",
        "info":1
      },{
        "pagePath": "/pages/contact/contact",
        "text": "联系我们",
        "iconPath": "/image/contact.png",
        "selectedIconPath": "/image/contact-active.png"
      }     
    ]
  },

  /**
   * 组件的方法列表
   */
  methods: {
    onChange(event) {
      //设置 store 中的 active 值
      this.updateActive(event.detail)
      // event.detail 的值为当前选中项的索引
      //根据当前项的索引值就知道页面信息在 list 数组的哪个位置,从 list 数组中获取页面路径,通过 wx.switchTab() 进行跳转
      wx.switchTab({
        url: this.data.list[event.detail].pagePath
      })
    }
  }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1679184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年中国国际厨卫家居展览会(上海KIB厨卫展)

中国国际厨卫家居博览会&#xff08;KIB&#xff09;由中国五金制品协会、中国国际贸易促进委员会轻工行业分会、北京奥维云网大数据科技股份有限公司主办。从最初的“中国国际橱柜、厨房卫浴产品与技术博览会(CIKB&#xff09;”&#xff0c;到2001年与中国国际五金展&#xf…

LSTM与GAN创新结合!模型性能起飞,准确率超98%

今天来聊一个深度学习领域非常具有创新性的研究方向&#xff1a;LSTM结合GAN。 LSTM擅长处理和记忆长期的时间依赖关系&#xff0c;而GAN可以学习复杂的数据分布并生成逼真的数据样本。通过充分结合两者的优势&#xff0c;我们可以增强模型对复杂数据的处理能力&#xff0c;提…

scanf读取标准输入

内容 scanf函数的原理 多种数据类型混合输入 常用的数据输入/输出函数 程序员可以给程序输入数据&#xff0c;程序处理后会返回一个输出。C语言通过函数库读取标准输入&#xff0c;然后通过对应函数处理将结果打印到屏幕上&#xff0c;printf函数可以将结果打印到屏幕上。下…

英语学习笔记14——What color‘s your ... ?

What color’s your … ? 你的 …… 是什么颜色的&#xff1f; 词汇 Vocabulary case n. 箱子【封闭的】 相关&#xff1a;box n. 箱子【开口的】    bookcase n. 书架 补充&#xff1a;case n. 案件&#xff0c;案例 口语&#xff1a;It’s a small case.    小意思&…

稚晖君独家撰文:具身智能即将为通用机器人补全最后一块拼图

具身智能新纪元。 *本文为稚晖君独家供稿,「甲子光年」经智元机器人授权发布。稚晖君本名彭志辉,先后任职OPPO、华为,现为智元机器人CTO、首席架构师。 在ChatGPT之后,又一个大模型概念火了——具身智能(Embodied AI)。 在学术界,图灵奖得主、上海期智研究院院长姚期…

【数据结构】堆(超详细)

文章目录 前言堆的概念及结构堆的实现堆的向下调整算法&#xff08;建小堆为例&#xff09;堆的向上调整算法&#xff08;建小堆为例&#xff09;堆的初始化销毁堆堆的插入堆的删除(规定删堆顶的数据)取堆顶元素判断堆是否为空获取堆的个数 完整代码&#xff08;包括测试代码&a…

解决kali Linux2024无法获取动态IPv4地址(DHCP)解决方案

用root用户启动终端 进入根目录&#xff0c;选择配置文件 cd到根目录下/../etc/network找到interfaces文件 编辑interfaces文件 vi interfaces&#xff0c;编辑interfaces文件 输入如下命令 打开虚拟网络编辑器 选择虚拟机选项卡&#xff0c;编辑&#xff0c;打开虚拟网络编…

【Linux 网络】网络基础(二)(应用层协议:HTTP、HTTPS)-- 详解

我们程序员写的一个个解决我们实际问题&#xff0c;满足我们日常需求的网络程序&#xff0c;都是在应用层。 前面写的套接字接口都是传输层经过对 UDP 和 TCP 数据发送能力的包装&#xff0c;以文件的形式呈现给我们&#xff0c;让我们可以进行应用层编程。换而言之&#xff0c…

50.乐理基础-拍号的类型-混合拍子

混合拍子的定义&#xff1a; 1.由不同的单拍子组合起来的&#xff0c;如图1。 2.因为组合顺序有多种可能&#xff0c;所以次强拍的位置也有多种可能&#xff0c;如图3。 图1&#xff1a;四二拍是单拍子&#xff0c;四三拍也是单拍子&#xff0c;四二拍 与 四三拍就是 不同的单拍…

网络游戏同步技术六:若干问题探讨

本文探讨网络同步的几个问题。 王者荣耀使用帧同步明智吗&#xff1f; 这个很难评&#xff0c;成王败寇&#xff0c;它成功了&#xff0c;它就是明智的。但是帧同步带来的心智负担还是很重的&#xff0c;他们的分享里面也提到他们花了很大的功夫去解决不一致问题。 个人更喜欢…

Sketch总结

sketch禁用了lineGap https://www.sketch.com/docs/designing/text/ http://www.sketchcn.com/sketch-chinese-user-manual.html https://github.com/sketch-hq/sketch-document https://developer.sketch.com/file-format/ https://animaapp.github.io/sketch-web-viewer/ htt…

定时发圈操作介绍

1、登陆已有的账号&#xff0c;点击到"朋友圈"功能 2、选择要发圈的微信号&#xff0c;编辑发圈的文案内容 3、自定义想要的时间点 4、点击"立即发送" 5、可进行跟圈

校园防欺凌平台

校园霸凌事件很难被发现&#xff0c;发现者又可能迫于威胁而不敢告发&#xff0c;被霸凌者又因各种原因而选择忍耐&#xff0c;所以&#xff0c;如果能够在发生校园霸凌的时候&#xff0c;做出及时的预警&#xff0c;也许能够拯救挽回无数个家庭。本平台结合防欺凌设备&#xf…

Transformer - Self-Attention层的复杂度的计算

Transformer - Self-Attention层的复杂度的计算 flyfish 矩阵的维度 下面矩阵的维度是32即 3行&#xff0c;2列 6,10等都是矩阵里的元素 如果矩阵A的列数与矩阵B的行数相同&#xff0c;那么这两个矩阵可以相乘。即&#xff0c;若A是一个mn矩阵&#xff0c;B是一个np矩阵&am…

python文件操作常用方法(读写txt、xlsx、CSV、和json文件)

引言 用代码做分析的时候经常需要保存中间成果&#xff0c;保存文件格式各不相同&#xff0c;在这里好好总结一下关于python文件操作的方法和注意事项 Python 提供了丰富的文件操作功能&#xff0c;允许我们创建、读取、更新和删除文件。允许程序与外部世界进行交互。 文章目录…

用c++实现快速排序、最大子段和问题

6.2.2 快速排序 【问题】快速排序(quick sort)的分治策略如下&#xff08;图6-5)。 (1)划分&#xff1a;&#xff08;选定一个记录作为轴值&#xff0c;以轴值为基准将整个序列划分为两个子序列&#xff0c;轴值的位置在划分的过程中确定&#xff0c;并且左侧子序列的所有记录…

mysql主从热备+keepalived 部署mysql高可用主备模式

目录 1、环境准备 2、分别在主服务器和备用服务器上安装keepalived 3、修改keepalived服务的配置文件 3.1 修改主服务器上的keepalive服务的配置文件 3.2 修改备用服务器上的keepalive服务配置文件 4、编写mysql监控脚本放到主服务器上 5、在主服务器和备用服务器上查看…

工厂自动化升级改造(3)-Modbus与MQTT的转换

什么是MQTT,Modbus,见下面文章 工厂自动化升级改造参考(01)--设备通信协议详解及选型-CSDN博客文章浏览阅读608次,点赞9次,收藏6次。>>特点:基于标准的以太网技术,使用TCP/IP协议栈,支持高速数据传输和局域网内的设备通信。>>>特点:跨平台的通信协议,…

【Java基础】集合(2) —— List

List 存储的对象是有序的&#xff08;集合中存储对象的顺序和使用add方法添加对象的顺序一致&#xff09;&#xff0c;存储的对象是可重复的。 List的特有的功能: 都是可以操作索引的功能。 增: void add(int index, E element )boolean addAll(int index, Collection<? …

全面提升数据采集效率:IP代理产品的应用与评估详解

全面提升数据采集效率&#xff1a;IP代理产品的应用与评估详解 文章目录 全面提升数据采集效率&#xff1a;IP代理产品的应用与评估详解背景应用场景&#xff1a;平台首页信息抓取准备评测素材详细的产品使用和评测流程产品介绍亮数据的IP代理服务亮数据的爬虫工具及采集技术 注…