文档

小程序开发者账号的注册

  1. Appid: wx7c1a7c8cc78fac72
  2. AppSecret:xxx

小程序代码的项目结构

1.项目的基本组成结构
  1. pages目录:用来存放所有小程序的界面
    1. pages数组中的第一项就是小程序项目的首页
  2. utils目录:用来存放工具性质的模块,例如格式化时间的模块
  3. app.js:小程序项目的入口文件
  4. app.json:小程序项目的全局配置文件
    1. 配置项pages:记录当前小程序所有页面的路径。可以在此增加路径,保存编译后就会新建小程序页面
    2. 配置项window:全局定义小程序所有界面的背景色、文字颜色等。
    3. style:全局定义小程序组件所使用的样式版本
    4. sitemapLocation:用来指明sitemap.json的位置
  5. app.wxss:小程序项目的全局样式文件
  6. project.config.json:项目的配置文件
    1. setting 中保存了编译相关的配置
    2. projectname 中保存的是项目名称
    3. appid 中保存的是小程序的账号ID
  7. sitemap.json:用来配置小程序及其页面是否允许被微信索引
    1. 关闭siteMap的索引提示:在project.config.json 的 setting 中配置字段checkSiteMap为false
2.小程序页面的组成部分
  1. .js文件:页面的脚本文件,存放页面的数据、事件处理函数等
  2. .json文件:当前页面的配置文件,配置窗口的外观、表现等
  3. .wxss文件:当前页面的样式文件
  4. .wxml文件:页面的模板结构文件
3.小程序代码的主要构成
  1. WXML:全称为WeiXin Markup Language,类似于网页开发中的HTML。它和HTML的主要区别是:
    1. 标签名称不同:例如HTML中的div标签,在WXML中提供了与之类似的view标签。
    2. 属性节点不同:例如HTML中a标签使用href作为属性表示链接地址,而在WXML中与a标签对应的navigator标签使用url作为属性。
    3. WXML提供了类似于Vue的模板语法:例如数据绑定、列表渲染、条件渲染。
  2. WXSS:全称为Wei Xin Style Sheets,类似于网页开发中的CSS。它与CSS的区别:
    1. 提供了rpx尺寸单位
    2. 提供了全局的样式和局部样式
    3. WXSS 仅支持部分 CSS 选择器
  3. 小程序中的js文件:分为三类

小程序中组件的分类

参考

1.常用的视图容器类组件
  1. view:普通视图区域,类似于HTML中的div元素,是一个块级元素,常用来实现页面的布局效果
    1. 示例:实现横向布局效果,使用flex布局
    <!--wxml文件-->
    <view class="container1">
        <view>A</view>
        <view>B</view>
        <view>C</view>
    </view>
    <!--wxss文件-->
    .container1 view{
      width: 100px;
      height: 100px;
      line-height: 100px;
      text-align: center;
    }
    .container1 view:nth-child(1) {
      background-color: red;
    }
    .container1 view:nth-child(2) {
      background-color: green;
    }
    .container1 view:nth-child(3) {
      background-color: blue;
    }
    .container1 {
      display: flex;
      justify-content: space-between;
    }
    
  2. scroll-view:可滚动的视图区域,常用来实现滚动列表效果
    1. 示例:实现纵向滚动效果
    <!-- scroll-x属性表示允许横向滚动 -->
    <!-- scroll-y属性表示允许纵向滚动 -->
    <!-- 使用纵向滚动,必须给scroll-view一个固定高度 -->
    <scroll-view class="container1" scroll-y="true">
      <view>A</view>
      <view>B</view>
      <view>C</view>
    </scroll-view>
    .container1 {
      height: 100px;
      border: 1px solid red;
    }
    .container1 view {
      width: 100px;
      height: 100px;
      line-height: 100px;
      text-align: center;
    }
    .container1 view:nth-child(1) {
      background-color: red;
    }
    .container1 view:nth-child(2) {
      background-color: green;
    }
    .container1 view:nth-child(3) {
      background-color: blue;
    }
    
  3. swiper 和 swiper-item:轮播图容器组件,可以用来做轮播图
    1. swipper组件的常用属性如下

    2. 示例:实现轮播效果

    <swiper class="swiper-container"            indicator-dots="true" autoplay="true" indicator-color="red" indicator-active-color="white" interval="1000" circular="true">
        <swiper-item>A</swiper-item>
        <swiper-item>B</swiper-item>
        <swiper-item>C</swiper-item>
    </swiper>
    
    .swiper-container {
      width: 100%;
      height: 100px;
    }
    .swiper-container swiper-item {
      line-height: 100px;
      text-align: center;
      background-color: chartreuse;
    }
    
2.常用的基础内容组件
  1. text:文本组件,类似于HTML中的span标签,是一个行内元素。

    1. 示例:通过该组件的selectable属性实现长按选中文本内容的效果
    <text user-select="true">这段文字长按可以选中</text>
    

  2. rich-text:富文本组件,支持把HTML字符串渲染为 WXML 结构

    1. 示例:通过rich-text组件的nodes属性节点,把 HTML 字符串渲染为对应的 UI 结构
    <rich-text nodes="<h1 style='color:red;'>test</h1>"></rich-text>
    
3.其他常用组件
  1. button:按钮组件

    1. type属性:指定按钮的类型
    2. size属性:指定按钮的尺寸
    3. plain属性:按钮是否镂空,背景色透明。
  2. image:图片组件,image组件默认宽度约300px、高度约 240px

    1. mode 属性用来指定图片的裁剪和缩放模式,常用的 mode 属性值如下:
  3. navigator组件:页面导航组件,类似于HTML中的a元素

WXML模板语法

1.数据绑定
  1. 在页面配置文件中的data配置项中定义数据
  2. 在WXML模板文件中使用数据:使用插值语法。在微信小程序开发中,插值语法既可以绑定内容,也可以绑定属性。不同于vue,vue中通过v-bind指令或者v-model指令绑定属性。
  3. 示例:
<!--wxml文件-->
<view>
    <!-- 使用插值语法绑定内容 -->
    <text>{{msg}}</text>
    <!-- 绑定内容时也可以进行三元运算、算术运算等 -->
    <text>{{count + 100}}</text>
    <!-- 使用插值语法绑定属性 -->
    <image src="{{src}}" mode="widthFix"></image>
</view>
<!--页面配置文件中-->
/**
   * 页面的初始数据
   */
  data: {
      msg: 'helloworld',
      src: '/images/link-01.png',
      count: 0
  },
2.事件绑定
  1. 小程序中常用到的事件如下:

  2. 当事件被触发,回调函数执行的时候,会收到一个事件对象event,该对象的详细属性如下所示:

target和currentTarget属性的区别:target 是触发该事件的源头组件,而 currentTarget 则是当前事件所绑定的组件。
3. 事件绑定:
1. 通过绑定tap事件响应用户的触摸行为,在事件回调函数中为data中的数据进行赋值
```
count的值加一
count的值为:{{count}}

data: {
  count: 0
},
// e为事件对象
btnTapHandler(e) {
  this.setData({
      count: this.data.count + 1
  })
}
```
2. 通过绑定input事件来响应文本框的输入事件
```
<input bindinput="inputHandler"></input>

inputHandler(e) {
    // e.detail.value为文本输入框中变化后的新值
    console.log(e.detail.value)
  }
```
  1. 在事件处理函数中为data中的数据赋值:通过调用this.setData(dataObject)方法,可以给页面data中的数据重新赋值
  2. 事件传参:可以为组件提供data-xxx自定义属性进行传参,其中xxx代表的是参数的名字。
    1. 参数的获取:事件对象.target.dataset.参数名
<!-- 事件传参示例:info即为参数的名字 -->
<button bindtap="btnTapHandler" data-info="{{2}}" type="primary">事件传参</button>

// e为事件对象
btnTapHandler(e) {
  // 获取向时间回调函数中传递的参数的值
  console.log(e.target.dataset.info)
}
  1. 实现文本框和data之间的数据同步:因为不存在vue中数据的双向绑定特性,所在在微信小程序中的实现主要是在事件回调函数中通过通过调用this.setData(dataObject)方法,给页面data中的数据重新赋值
<input bindinput="inputHandler" value="{{count}}"></input>

inputHandler(e) {
    this.setData({
        count: e.detail.value
    })
  }
3.条件渲染
  1. 在小程序中使用wx:ifwx:elifwx:else来判断是否渲染一个组件。
<view>
    <view wx:if="{{type === 1}}">男</view>
    <view wx:elif="{{type === 2}}">女</view>
    <view wx:else="{{type === 3}}">保密</view>
</view>
  1. 一次控制多个组件的展示与隐藏,可以使用一个block标签将多个组件包裹起来,在block标签上使用wx:if属性。block标签类似于vue中的template标签,并不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何渲染。
<block wx:if="{{type === 0}}">
    <view>AAA</view>
    <view>BBB</view>
    <view>CCC</view>
</block>
<block wx:else="{{type === 1}}">
    <view>DDD</view>
</block>
  1. hidden属性:可以控制元素的显示和隐藏。
<view hidden="{{type === 0}}">AAA</view>
  1. wx:if和hidden的比较:wx:if等同于vue中的v-if指令,它通过动态创建和移除元素的方式,控制元素的展示与隐藏;hidden等同于vue中的v-show指令,该属性控制元素的display属性控制元素的显示和隐藏。
    1. 元素频繁切换,考虑到效率,应当使用hidden
    2. 控制条件复杂,应当搭配使用wx:elif、wx:else控制元素的显示和隐藏。
4.列表渲染
  1. 使用wx:for可以进行列表渲染,循环中每一项的索引使用index表示,循环中的每一个当前项使用item表示。
<view wx:for="{{list}}">
    <text>索引为:{{index}},姓名为:{{item.name}}</text>
</view>

data: {
      list: [
          {name: '张三', age: 23},
          {name: '李四', age: 25},
          {name: '王五', age: 26}
      ]
  }
  1. 指定表示索引的变量名和循环中的每一个当前项的变量名:使用 wx:for-index可以指定当前循环项的索引的变量名,使用wx:for-item可以指定当前项的变量名
<!--指定表示索引的变量名称为idx,表示当前项的变量名为itm-->
<view wx:for="{{list}}" wx:for-index="idx" wx:for-item="itm">
    <text>索引为:{{idx}}, 姓名为:{{itm.name}}</text>
</view>
  1. 为渲染出来的列表项指定唯一的key值可以使用wx:key值。
<view wx:for="{{list}}" wx:key="id">
    <text>索引为:{{index}},姓名为:{{item.name}}</text>
</view>

data: {
      list: [
          {id: 1, name: '张三', age: 23},
          {id: 2, name: '李四', age: 25},
          {id: 3, name: '王五', age: 26}
      ]
  },

WXSS模板样式

1.简介
  1. 简介:WXSS:全称为Wei Xin Style Sheets,类似于网页开发中的css.
2.WXSS中扩展的特性:
  1. rpx尺寸单位:rpx全称为responsive pixel,是微信小程序独有的,用来解决屏幕适配的尺寸单位。为了实现屏幕的自动适配,rpx把所有设备的屏幕,在宽度上等分为750份(即:当前屏幕的总宽度为 750rpx)
    1. 在 iPhone6上,屏幕宽度为375px,共有750个物理像素,等分为 750rpx。所以1个rpx等于0.5个px,1个px等于2个rpx。官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准
  2. @import进行外联样式的导入
<!--common文件夹位于项目根目录下-->
@import "/common/common.wxss";
3.全局样式和局部样式
  1. 全局样式:app.wxss文件中定义的是全局样式,作用于每一个页面。
  2. 局部样式:在pages目录下每一个页面的wxss文件中定义的是局部样式,只能作用于当前页面。

全局配置与页面配置

1.全局配置
  1. 小程序项目根目录下的app.json是小程序的全局配置文件。常用的配置项包括pages、window、tabBar、style、

  2. 小程序窗口的组成部分如下图所示:

  3. window节点的常用配置项如下:

  4. tabBar节点主要用于实现多页面的快速切换,在小程序中通常将其分为底部tabBar和顶部tabBar。

    1. tabBar中只能配置最少 2 个、最多5个tab页签

    2. 当渲染顶部tabBar时,不显示icon,只显示文本

    3. tabBar的六个组成部分如下:

    4. tabBar节点的配置项如下所示:

    5. 每个list配置项的配置选项如下所示:

2.页面配置
  1. 每一个页面都有自己的json文件作为页面的配置文件。
  2. 页面配置中常用的配置项:

发送网络请求

1.小程序中网络数据请求的限制
  1. 出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
    1. 只能请求 HTTPS 类型的接口
    2. 在小程序管理后台配置 request 合法域名
  2. 后端程序员仅仅提供了http协议的接口、暂时没有提供 https 协议的接口。可以在微信开发者工具中点击详情=》本地设置=》勾选不校验合法域名来跳过request合法域名的校验。
2.发送网络请求
  1. 发送get请求:
wx.request({
  url: 'https://www.escook.cn/api/get',
  method: 'GET',
  data: {
    name: '李四',
    age: 23
  },
  // 响应成功执行的回调
  success: (res) => {
    console.log(res)
  }
})
  1. 发送post请求:
wx.request({
  url: 'https://www.escook.cn/api/post',
  method: 'POST',
  data: {
    name: '李四',
    age: 23
  },
  success: (res) => {
    console.log(res)
  }
})

页面导航

页面导航:页面之间的相互跳转

1.小程序中实现页面导航的两种方式
  1. 声明式导航:在页面上声明一个navigator导航组件,通过点击navigator组件实现页面跳转。

    1. 导航到tabBar页面(即app.json中tabBar配置项中配置的页面):使用navigator组件跳转到指定的tabBar页面,同时指定url属性和open-type属性。url属性表示要跳转的页面地址,必须以/开头,open-type表示跳转的方式,必须为switchTab
    <!--从home首页跳转到消息页-->
    <navigator open-type="switchTab" url="/pages/message/message">导航到消息页</navigator>
    
    1. 导航到非tabBar页面:使用navigator组件跳转到普通的非tabBar页面,同时指定url属性和open-type属性。url属性表示要跳转的页面地址,必须以/开头,open-type表示跳转的方式,必须为navigate
    <!--从首页导航到非tabBar页info-->
    <navigator url="/pages/info/info" open-type="navigate">导航到非tabBar页面</navigator>
    <!--open-type="navigate"可以省略-->
    <navigator url="/pages/info/info">导航到非tabBar页面</navigator>
    
    1. 后退导航:可以指定open-type属性和delta属性,后退到上一页面或者多级页面。open-type 的值必须是navigateBack,表示要进行后退导航,delta 的值必须是数字,表示要后退的层级。如果只是后退到上一页面,则可以省略delta属性,因为其默认值就是1
    <navigator open-type="navigateBack" delta="1">返回上一页</navigator>
    
  2. 编程式导航:调用小程序的API,实现页面的跳转。

    1. 导航到tabBar页面:调用wx.switchTab(Object object) 方法,可以跳转到 tabBar页面。其中 Object 参数对象的属性列表如下:
    <button type="primary" bindtap="goToMessage">导航到tabBar页面</button>
    <!--home.js-->
    goToMessage() {
        wx.switchTab({
          url: '/pages/message/message',
        })
    }
    
    1. 导航到非tabBar页面:调用wx.navigateTo(Object object)方法,可以跳转到非tabBar的页面。其中 Object 参数对象的属性列表如下:
    <button type="primary" bindtap="goToInfo">跳转到info页面</button>
    
    goToInfo() {
        wx.navigateTo({
          url: '/pages/info/info',
        })
    }
    
    1. 后退导航:调用wx.navigateBack(Object object)方法,可以返回上一页面或多级页面。其中 Object 参数对象可选的属性列表如下:
    <button type="warn" bindtap="goToBack">返回到上一页</button>
    
    goToBack() {
        wx.navigateBack({
            delta: 1
        })
    }
    
2.导航传参
  1. 声明式导航传参:navigator组件的url属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数。其中参数与路径之间使用问好分隔,参数键与参数值之间使用等号相连,不同参数键值对使用&分隔。
<navigator url="/pages/info/info?name=zs&age=24">导航到非tabBar页面</navigator>
  1. 编程式导航传参:调用wx.navigateTo(Object object)方法跳转页面时,也可以携带参数
<button type="default" bindtap="goToInfo">跳转到info页面</button>

goToInfo() {
    wx.navigateTo({
      url: '/pages/info/info?id=3&age=25',
    })
}
  1. 在页面的生命周期函数onload中接收导航参数(不管编程式导航还是声明式导航)。
/**
 * 生命周期函数--监听页面加载
 */
onLoad(options) {
    // options就是导航传递过来的参数对象
    console.log(options)
}

页面事件

1.下拉刷新事件
  1. 下拉刷新:指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
  2. 启用下拉刷新的方式:
    1. 全局开启下拉刷新:在app.json的window节点中,将 enablePullDownRefresh 设置为 true
    2. 局部开启下拉刷新:在页面的.json配置文件中,将 enablePullDownRefresh 设置为 true。这个方式推荐使用,因为并不是所有的页面需要开启下拉刷新的效果。
  3. 设置下拉刷新窗口的样式:
    1. backgroundColor:设置下拉刷新窗口的背景颜色,仅支持16 进制的颜色值
    2. backgroundTextStyle:设置下拉刷新 loading 的样式,仅支持 dark 和 light
  4. 监听页面的下拉刷事件:在页面的.js文件中,通过 onPullDownRefresh()函数即可监听当前页面的下拉刷新事件
/**
 * 页面相关事件处理函数--监听用户下拉动作
 */
onPullDownRefresh() {
    this.setData({
        count: 0
    })
},
  1. 停止下拉刷新的效果:下拉刷新的loading效果会一直显示,不会主动消失,所以需要手动隐藏下拉刷新的 loading 效果。调用wx.stopPullDownRefresh()可以停止当前页面的下拉刷新。
/**
 * 页面相关事件处理函数--监听用户下拉动作
 */
onPullDownRefresh() {
    this.setData({
        count: 0
    })
    // 当数据重置成功后,关闭下拉刷新的效果
    wx.stopPullDownRefresh()
},
2.上拉触底事件
  1. 上拉触底:通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
  2. 监听页面的上拉触底事件:在页面的.js文件中,通过 onReachBottom()函数即可监听当前页面的上拉触底事件。
/**
 * 页面上拉触底事件的处理函数
 */
onReachBottom() {
    console.log("触发了页面触底事件!")
},
  1. 配置上拉触底距离:上拉触底距离指的是触发上拉触底事件时,滚动条距离页面底部的距离。页面的.json 配置文件中,通过onReachBottomDistance属性来配置上拉触底的距离。小程序默认的触底距离是 50px
  2. 上拉触底添加loading提示效果:wx.showLoading({title: '数据加载中...'})
  3. 隐藏loading提示效果:wx.hideLoading()

生命周期

1.生命周期的分类
  1. 在小程序中,生命周期分为两类:
    1. 页面的生命周期:指的是小程序中每个页面的加载=》渲染=》销毁的过程。
    2. 应用的生命周期:指的是小程序从启动=》运行=》销毁的过程。
2.生命周期函数
  1. 应用的生命周期函数:特指小程序从启动 -> 运行 -> 销毁期间依次调用的那些函数
App({

  /**
   * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   */
  onLaunch: function () {
        console.log("小程序初始化完成!")
  },

  /**
   * 当小程序启动,或从后台进入前台显示,会触发 onShow
   */
  onShow: function (options) {
        console.log("小程序从后台进入前台!")
  },

  /**
   * 当小程序从前台进入后台,会触发 onHide
   */
  onHide: function () {
        console.log("小程序从前台进入后台!")
  },

  /**
   * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
   */
  onError: function (msg) {
    
  }
})

  1. 页面的生命周期函数:特指小程序中,每个页面从加载 -> 渲染 -> 销毁期间依次调用的那些函数
/**
 * 生命周期函数--监听页面加载
 */
onLoad(options) {},
/**
 * 生命周期函数--监听页面初次渲染完成
 */
onReady() {},
/**
 * 生命周期函数--监听页面显示
 */
onShow() {},
/**
 * 生命周期函数--监听页面隐藏
 */
onHide() {},
/**
 * 生命周期函数--监听页面卸载
 */
onUnload() {},

WXS脚本

1.WXS脚本概述
  1. WXS:全称Wei Xin Script,是小程序独有的一套脚本语言,结合WXML使用。
  2. 应用场景:wxml中无法调用在页面的.js中定义的函数,但是,wxml中可以调用wxs中定义的函数。因此,小程序中 wxs 的典型应用场景就是“过滤器”。
  3. WXS和JS的关系:
    1. WXS中的数据类型:
      1. number:数值类型
      2. string:字符串类型
      3. boolean:布尔类型
      4. object:对象类型
      5. function:函数类型
      6. array:数组类型
      7. date:日期类型
      8. regexp:正则
    2. WXS不支持类似于ES6及以上的语法格式:不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写等;支持var定义变量,普通function函数等类似于ES5的语法。
    3. WXS遵循CommonJS规范:比如module 对象、require函数、module.exports对象
2.WXS脚本的基础语法
  1. 内嵌WXS脚本:WXS代码可以编写在WXML文件中的wxs标签内,等同于在HTML文件中将js代码编写在script标签内。
    1. wxs标签必须提供module属性,用于指定当前wxs的模块名称,方便再WXML中访问模块中的成员。
    <!--name为data中定义的属性-->
    <view>姓名为:{{moduleA.toUpper(name)}}</view>
    <wxs module="moduleA">
        module.exports.toUpper = function(str) {
            return str.toUpperCase()
        }
    </wxs>
    
  2. WXML中使用外联的WXS脚本:wxs代码可以编写在以wxs为后缀名的文件中,等同于将js代码编写在以js为后缀名的文件中。
    1. 定义外联脚本:在utils目录下新建tools.wxs文件
    function toLower(str) {
        return str.toLowerCase()
    }
    module.exports = {
        toLower: toLower
    }
    
    1. 在WXML中使用外联脚本:使用wxs标签引入外联脚本,使用module属性指定模块的名称,src属性指定要引入的脚本的路径,必须是相对路径。
    <text>姓名为:{{moduleA.toLower(name)}}</text>
    
    <!-- 引用外联的wxs脚本,并命名为moduleA -->
    <wxs module="moduleA" src="../../utils/tools.wxs"></wxs>
    
3.WXS的特点
  1. 和js这门脚本语言是不一样的
  2. WXS编写的代码不能作为组件中的事件回调,它的应用场景是作为过滤器, 例如
<!--对data中的name数据进行过滤,转小写-->
<text>姓名为:{{moduleA.toLower(name)}}</text>
  1. 隔离性:隔离性指的是wxs的运行环境和其他JavaScript代码是隔离的
    1. wxs 不能调用 js 中定义的函数
    2. wxs 不能调用小程序提供的 API
  2. 性能好:
    1. 在 iOS设备上,小程序内的WXS会比JavaScript 代码快 2 ~ 20 倍
    2. 在 android 设备上,二者的运行效率无差异

自定义组件

1.组件的创建与引用
  1. 组件的创建:
    1. 在项目的根目录下新建components文件夹,用于存放组件
    2. 为了将不同的组件存放在不同的目录,在components目录下新建一个文件夹用于存放组件,例如test
    3. 在test目录下右击新建组件,键入组件名称后回车,即会生成四个文件。
  2. 组件的引用方式:
    1. 局部引用:组件只能在当前被引用的页面内使用。引用方式:在页面的json配置文件中定义如下:
    // home页面的json配置文件下
    {
    "usingComponents": {
            "my-test1": "/components/test/test1"
        }
    }
    //home页面中使用组件
    <my-test1></my-test1>
    
    1. 全局引用:组件可以在每个小程序页面中使用。引用方式:在全局配置文件app.json下进行配置,如下所示:
    {
    // 和pages节点平级
    "usingComponents": {
            "my-test2": "/components/test2/test2"
        },
    }
    // 使用组件
    <my-test2></my-test2>
    
    1. 引用方式的选择:如果某组件在多个页面中经常被用到,建议进行“全局引用”;如果某组件只在特定的页面中被用到,建议进行“局部引用”
  3. 组件和页面的区别:
    1. 组件和页面都由js、json、wxss、wxml、四个文件组成。
    2. 组件的.json文件中需要声明"component":true 属性
    3. 组件的 .js 文件中调用的是Component()函数,而页面调用的是Page函数
    4. 组件的事件处理函数需要定义到methods节点中,而页面是定义在与data平级的地方
2.样式
  1. 组件的样式隔离:
    1. 默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构。即组件A的样式不会影响组件B的样式,组件A的样式也不会影响小程序页面的样式,小程序页面的样式(包括app.wxss中定义的样式)也不会影响组件A的样式。
    2. 只有class选择器会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响。因此建议在组件和引用组件的页面中建议使用class选择器,不要使用 id、属性、标签选择器!
  2. 修改组件的样式隔离选项:默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过styleIsolation修改组件的样式隔离选项
    1. styleIsolation的可选值如下:

    2. 示例:

    // 在组件的js文件下新增如下配置
    options: {
        // 启动样式隔离
        // styleIsolation: 'isolated'
        // styleIsolation: 'apply-shared'
        styleIsolation: 'shared'
    },
    
3.自定义组件的数据、方法、属性
  1. data数据:在小程序的组件中,用于组件模板渲染的私有数据,需要定义到 data 节点中
  2. 方法:在小程序的组件中,事件处理函数和自定义方法需要定义到methods节点中。自定义方法建议以下划线_开头,方便自定义组件中对纯数据字段进行处理。
  3. properties属性:在小程序的组件中,properties属性用来接收外界传递到组件中的数据
// 在组件的js文件下
/**
 * 组件的属性列表
 */
properties: {
    count: {
        type: Number,// 属性值的数据类型
        value: 10 // 属性的默认值为10
    }
    // 简写形式
    count: Number
},

// 外界使用到组件的页面进行传值
<my-test1 count="100"></my-test1>
  1. data和properties的区别:两者指向同一块地址,是一个东西。只不过data更倾向于存储组件的私有数据,properties 更倾向于存储外界传递到组件中的数据。
  2. properties属性值的修改:在vue中修改properties属性的值会产生警告,但是在微信小程序中,properties和data就是同一个东西,所以properties属性的值也可以用于页面渲染,或使用setData为properties中的属性重新赋值
addCount() {
    this.setData({
        count: this.properties.count + 100
    })
}
4.数据监听器
  1. 数据监听器:用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于vue中的 watch 侦听器。在小程序组件中,数据监听器的基本语法格式如下:
// 监听单个或者多个字段
Component({
    observers: {
        '字段1, 字段2': function(字段1的新值, 字段2的新值) {
        
        }
    },
})
// 监听对象中的单个或者多个属性
Component({
    observers: {
        '对象.属性A, 对象.属性B': function(属性A的新值, 属性B的新值) {
        
        }
    },
})
// 通配符 ** 表示监听对象中所有属性的变化
Component({
    observers: {
        '对象.**': function(obj) {
            
        }
    },
})
  1. 示例:
 /**
 * 组件的初始数据
 */
data: {
    x1: 0,
    x2: 0,
    sum: 0,
    user: {
        name: 'zs',
        age: 23
    }
},
observers: {
    'x1, x2': function(x1, x2) {
        this.setData({
            sum: x1 + x2
    })
    },
    'user.name, user.age': function(name, age) {
    }
},
5.纯数据字段
  1. 纯数据字段:纯数据字段指的是那些不用于界面渲染的data字段。
  2. 应用场景:例如有些情况下,某些data中的字段既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。带有这种特性的data字段适合被设置为纯数据字段。
  3. 作用:纯数据字段有助于提升页面更新的性能。
  4. 使用规则:在Component构造器的options节点中,指定 pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段。示例如下:
data: {
    // 纯数据字段
    _count: 100,
}

Component({
    // 在组件的js文件下新增如下配置
    options: {
        // 指定所有以_开头的数据字段为纯数据字段
        pureDataPattern: /^_/
    },
}
6.组件的生命周期
  1. 小程序组件可用的全部生命周期函数如下:

    1. lifetimes节点:在小程序组件中,生命周期函数可以直接定义在Component构造器的第一级参数中,可以在lifetimes字段内进行声明,例如:
    Component({
        lifetimes: {
            attached() {
            },
            detached() {
            }
        },
    }
    
  2. 组件所在页面的生命周期:有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期。例如,监听着组件所在的页面展示,页面显示时,执行某个动作。

    1. 在自定义组件中,组件所在页面的生命周期函数有如下 3 个,分别是:
      1. show:组件所在的页面被展示时执行
      2. hide:组件所在的页面被隐藏时执行
      3. resize:组件所在的页面尺寸变化时执行
    2. pageLifetimes节点:组件所在页面的生命周期函数,需要定义在pageLifetimes节点中,例如:
    Component({
        pageLifetimes: {
            show: function() {
                console.log("show")
            },
            hide: function() {
                console.log("hide")
            },
            resize: function() {
                console.log("resize")
            }
        },
    }
    
7.插槽
  1. 插槽:在自定义组件的wxml结构中,可以提供一个 节点(插槽),用于承载组件使用者提供的 wxml 结构。在封装组件时,在wxml文件中使用slot作为占位符,在使用组件时为slot占位符提供具体的内容节点。
  2. 单个插槽:在小程序中,默认每个自定义组件中只允许使用一个进行占位,这种个数上的限制叫做单个插槽。
<!--组件的封装者-->
<view>这是组件的内部节点</view>
<!-- 使用slot进行占位,具体的内容由组件的使用者决定 -->
<slot></slot>

<!--组件的使用者-->
<my-test1 count="100">
    <!-- 下面的内容将放在组件slot的位置上 -->
    <view>AAA</view>
    <view>BBB</view>
</my-test1>
  1. 多个插槽:
    1. 启用多个插槽:在小程序的自定义组件中,需要使用多插槽时,可以在组件的.js文件中,通过如下方式进行启用:
    Component({
    
        // 在组件的js文件下新增如下配置
        options: {
            multipleSlots: true //在组件定义时的选项中启用多slot支持 
        }
    }
    
    1. 组件中定义多个插槽:可以在组件的.wxml中使用多个<slot>标签,以不同的name来区分不同的插槽。
    <!-- name为first的第一个插槽 -->
    <slot name="first"></slot>
    <!-- name为second的第二个插槽 -->
    <slot name="second"></slot>
    
    1. 使用多个插槽:在使用带有多个插槽的自定义组件时,需要用slot属性来将节点插入到不同的中。
    <my-test1 count="100">
        <view slot="first">AAA</view>
        <view slot="second">BBB</view>
    </my-test1>
    
8.父子组件之间的通信
  1. 父子组件之间通信的三种方式:
    1. 属性绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容的数据
    <!--父组件中-->
    /**
     * 组件的初始数据
     */
    data: {
        count: 100
    }
    <!--父组件向子组件传递值-->
    <my-test3 count="{{count}}">父组件向子组件传值</my-test3>
    
    <!--子组件使用properties接收-->
    Component({
        /**
         * 组件的属性列表
         */
        properties: {
            count: Number
        }
    }
    
    1. 事件绑定:用于子组件向父组件传递数据,可以传递任意数据
      1. 在父组件的js中,定义一个函数(即事件的回调函数),这个函数即将通过自定义事件的形式,传递给子组件
      methods: {
          // 在父组件的 js 中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。
          synCount(e) {
              // e即事件对象
              console.log(e)
              this.setData({
                  count: e.detail.value
              })
          }
      }
      
      1. 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
      <!-- 使用bind:自定义事件名称 -->
      <my-test3 count="{{count}}" bind:sync="synCount">父组件向子组件传值</my-test3>
      
      1. 在子组件的js中,通过调用this.triggerEvent('自定义事件名称', { /* 参数对象 */ }) ,将数据发送到父组件。子组件触发负组件中定义的事件名称
      methods: {
          addCount() {
              this.setData({
                  count: this.properties.count + 100
              })
              this.triggerEvent('sync', {
                  value: this.properties.count
              })
          }
      }
      
      1. 在父组件的js中,在事件回调函数内通过e.detail获取到子组件传递过来的数据
      synCount(e) {
          // e即事件对象
          console.log(e)
          this.setData({
              count: e.detail.value
          })
      }
      
    2. 获取组件实例:父组件还可以通过this.selectComponent("id或者类选择器")获取子组件实例对象,这样就可以直接访问子组件的任意数据和方法。
    <!-- 使用bind:自定义事件名称 -->
    <my-test3 count="{{count}}" bind:sync="synCount" class="class1" id="id1">父组件向子组件传值</my-test3>
    <button type="warn" bindtap="getChild">获取子组件实例</button>
    
    getChild() {
        const child = this.selectComponent('.class1')
        // 调用子组件的setData方法
        child.setData({
            count: this.properties.count + 1
        })
    }
    
9.自定义组件的behaviors
  1. behaviors:behaviors是小程序中,用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”。每个behavior可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。每个组件可以引用多个behavior,behavior 也可以引用其它 behavior。
  2. behavior的创建:调用Behavior(Object object)方法即可创建一个共享的behavior实例对象,供所有的组件使用
// 项目根目录下新建behaviors文件夹,该文件夹下新建xxx.js
module.exports = Behavior({
    properties: {

    },
    data: {
        name: 'test'
    },
    methods: {

    }
})
  1. behavior的导入和使用
// 导入自定义的behavior模块
const myBehavior = require("../../behavior/my-behavior")
Component({
    // 将导入的behavior实例对象挂载到behaviors数组节点中
    behaviors: [myBehavior]
})

// 可以在页面上直接使用behavior模块中定义的数据
  1. behaviors中可用的节点

Vant Weapp的基本使用

1.安装
  1. 小程序中支持使用npm安装一些第三方包,从而来提高小程序的开发效率。
  2. Vant Weapp的安装:参考Vant Weapp官网
    1. 在项目根目录下执行npm init进行初始化
    2. 通过npm安装npm i vant-weapp -S --production
    3. 在微信开发者工具中构建npm包
    4. 全局引入或者局部引入Vant Weapp中的组件。全局引入示例如下
    {
        "usingComponents": {
            "my-test2": "/components/test2/test2",
            "van-button": "./miniprogram_npm/vant-weapp/button/index"
        }
    }
    
2.全局主题样式的定制
  1. CSS变量:也叫做自定义属性。
    1. CSS变量的定义:变量名需要以两个减号开始。例如:
    <!--定义一个CSS变量,其作用域为整个HTML文档-->
    html {
        --main-bg-color: brown;
    }
    
    1. CSS变量的使用:使用var函数取值
    .class1 {
        background-color: var(--main-bg-color);
    }
    
  2. ant Weapp 使用CSS变量来实现定制主题。在app.wxss 中,写入 CSS 变量,即可对全局生效。例如:
/* 指定作用域为page,page为页面的根元素 */
page {
    --button-primary-background-color: #2b4b6b;
    --button-primary-border-color: #ff0000;
}

API promise化

  1. API promise化:指的是通过额外的配置,将官方提供的、基于回调函数的异步API,升级改造为基于Promise 的异步 API,从而提高代码的可读性、维护性,避免回调地狱的问题。
  2. API promise化的实现:
    1. 安装miniprogram-api-promise包。每次安装新的包后,先删除miniprogram_npm目录,然后需要在微信开发者工具中重新构建npm包
    npm install --save miniprogram-api-promise@1.0.4
    
    1. 在小程序入口文件app.js中调用promisifyAll()方法
    import {promisifyAll} from 'miniprogram-api-promise'
    const wxp = wx.p = {}
    // promisify all wx对象的API
    promisifyAll(wx, wxp)
    
  3. 调用promise化后的异步API示例:
<van-button type="primary" bindtap="getInfo">按钮</van-button>
async getInfo() {
    const {data: result} = await wx.p.request({
      url: 'https://www.escook.cn/api/get',
      method: 'GET',
      data: {
          name: 'zs',
          age: 23
      }
    })
    console.log(result)
},

全局数据共享

  1. 全局数据共享也叫做状态管理,是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex、Redux、MobX 等。
1.小程序中的全局数据共享方案
  1. 在小程序中,可使用mobx-miniprogram配合mobx-miniprogram-bindings实现全局数据共享。其中:
    mobx-miniprogram用来创建Store实例对象。mobx-miniprogram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用。
  2. MobX相关包的安装:npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1

分包

1.简介
  1. 分包:分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
  2. 分包的好处:
    1. 可以优化小程序首次启动的下载时间
    2. 在多团队共同开发时可以更好的解耦协作
  3. 分包的加载规则:
    1. 在小程序启动时,默认会下载主包并启动主包内页面。进入小程序都会首先看到tabBar页面,因此tabBar 页面需要放到主包中
    2. 当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示,非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载。这样就不用将小程序的所有页面和资源都打包到一起,节省小程序首次启动时间。
2.分包的使用
  1. 在app.json的subpackages节点中声明分包的结构。小程序会按subpackages的配置进行分包,subpackages 之外的目录将被打包到主包中
3.独立分包
  1. 独立分包:独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
  2. 独立分包和普通分包的区别:是否依赖于主包运行
    1. 普通分包必须依赖于主包才能运行
    2. 独立分包可以在不下载主包的情况下,独立运行
  3. 独立分包的应用场景:开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
    1. 当小程序从普通的分包页面启动时,需要首先下载主包,而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度。注意:一个小程序中可以有多个独立分包。
  4. 独立分包的配置方法:通过independent声明独立分包
  5. 分包预下载:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
    1. 预下载分包的行为,会在进入指定的页面时触发。在app.json中,使用preloadRule节点定义分包的预下载规则

自定义tabBar

  1. https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html