Skip to content

微信小程序基础

第一章:必知必会

一、文档

微信开放文档 - 小程序

小程序注册页

二、小程序目录

一个完整的小程序项目分为两个部分:主体文件、页面文件。

主体文件又称小程序全局文件,顾名思义,全局文件能够作用于整个小程序,影响到小程序的每个页面,且主体文件必须放到项目的根目录下,主要由三部分组成:

文件名作用是否必须
app.js小程序入口文件必须
app.json小程序的全局配置必须
app.wxss小程序的全局样式非必须

页面文件是每个页面所需的文件,小程序页面文件都存放在 pages 目录下,一个页面一个文件夹,每个页面通常由四个文件组成,每个文件只对当前页面有效:

文件名作用是否必须
.js页面逻辑必须
.wxml页面结构必须
.wxss页面样式非必须
.json页面配置非必须

📌 注意事项

① 页面文件,wxss、json 文件能够覆盖主体文件中的样式和配置。

② 强烈建议:页面文件夹名称和页面文件名称要保持一致。

新建小程序文件和文件夹作用清单:

├─pages	                     ➡ 小程序页面存放目录
│  ├─ index				     ➡ index 文件夹代表是 index 页面所需的文件
│  │───── index.js           ➡ index 页面逻辑
│  │───── index.json         ➡ index 页面配置
│  │───── index.wxml         ➡ index 页面结构
│  │───── index.wxss         ➡ index 页面样式
│─ .eslintrc.js              ➡ Eslint 配置文件
│─ app.js                    ➡ 小程序入口,即打开小程序首页执行的项目
│─ app.json                  ➡ 小程序的全局配置
│─ app.wxss                  ➡ 小程序的全局样式
│─ project.config.json       ➡ 小程序开发者工具配置
│─ project.private.config.json
│─ sitemap.json              ➡ 小程序搜索优化

第二章:配置文件

全局配置文件:app.json ➡ 小程序全局配置文件,用于配置小程序的一些全局属性和页面路由。

局部配置文件:页面.json ➡ 小程序页面配置文件,用于配置当前页面的窗口样式、页面标题等。

项目配置文件:project.config.json ➡ 小程序项目的配置文件,用于保存项目的一些配置信息和开发者的个人设置。

搜索配置文件:sitemap.json ➡ 配置小程序及其页面是否允许被微信索引,提高小程序在搜索引擎搜索到的概率。

一、全局配置

小程序 app.json 文件是小程序的全局配置文件,用于配置小程序的一些全局属性和页面路由。

当小程序启动时,会自动读取 app.json 文件中的配置,根据配置生成对应的页面和组件、界面表现、网络超时时间、底部 tab,在小程序运行过程中起着关键的作用。

1. pages

pages 字段:用于指定小程序由哪些页面组成,用于为了让小程序知道由哪些页面组成以及页面定义在哪个目录,每一项都对应一个页面的路径(含文件名) 信息。

json
{
  "pages": [
    "pages/index/index",
    "pages/list/list"
  ]
}

📌 注意事项

① 文件名不需要写文件后缀框架会自动去寻找对应位置的 .json, .js, .wxml, .wxss 四个文件进行处理。

② 小程序中新增 / 减少页面,都需要对 pages 数组进行修改。

③ 未指定 entryPagePath 时,数组的第一项代表小程序的初始页面(首页)。

🔔 开发小技巧

可以通过配置小程序的页面路径快速生成小程序的页面。

2. window

window 字段: 用于设置小程序的状态栏、导航条、标题、窗口背景色。

属性描述类型默认值
navigationBarBackgroundColor导航栏背景颜色HexColor#000000
navigationBarTextStyle导航栏标题颜色,仅支持 black / whitestringwhite
navigationBarTitleText导航栏标题文字内容string
backgroundColor下拉 loading 的样式,仅支持 dark / lightstringdark
enablePullDownRefresh是否开启全局的下拉刷新booleanfalse
backgroundTextStyle设置下拉刷新指示器颜色,仅支持 dark / lightstringdark
onReachBottomDistance页面上拉触底事件触发时距页面底部距离单位为 pxnumber50

3. tabBar

tabBar 字段:定义小程序顶部或底部 tab 栏,如果小程序是一个多 tab 应用,例如:可以在客户端窗口的底部或顶部通过 tab 栏可以切换页面,可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

tabBar 配置项

属性描述类型默认值
colortab 上的文字默认颜色,仅支持十六进制颜色HexColor
selectedColortab 上的文字选中时的颜色,仅支持十六进制颜色HexColor
backgroundColortab 的背景色,仅支持十六进制颜色HexColor
borderStyletabbar 上边框的颜色, 仅支持 black / whitestringblack
listtab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab
positiontabBar 的位置,仅支持 bottom / topstringbottom

List 配置项:list 是一个数组,只能配置最少 2 个、最多 5 个 tab,tab 按数组的顺序排序,每个项都是一个对象。

属性描述类型是否必填
pagePath页面路径,必须在 pages 中先定义string
texttab 上按钮文字string
iconPath图片路径,icon 大小限制为 40kb,
建议尺寸为 81px * 81px。
string
selectedIconPath选中时的图片路径,icon 大小限制为 40kb,
建议尺寸为 81px * 81px,不支持网络图片。
string

📌 注意事项

① list 是一个数组,配置最少 2 个、最多 5 个 tab。

② 当 positiontop 时,不显示 icon。

二、页面配置

小程序的页面配置,也称局部配置。每一个小程序页面也可以使用自己的 .json 文件来对本页面的窗口表现进行配置。

页面配置文件的属性和全局配置文件中的 window 属性几乎一致。只不过这里不需要额外指定 window 字段,因此如果出现相同的配置项,页面中配置项会覆盖全局配置文件中相同的配置项。

属性描述类型默认值
navigationBarBackgroundColor导航栏背景颜色HexColor#000000
navigationBarTextStyle导航栏标题颜色,仅支持 black / whitestringwhite
navigationBarTitleText导航栏标题文字内容string
backgroundColor下拉 loading 的样式,仅支持 dark / lightstringdark
enablePullDownRefresh是否开启全局的下拉刷新booleanfalse
onReachBottomDistance页面上拉触底事件触发时距页面底部距离单位为 pxnumber50

📌 注意事项

页面配置项和 app.json 中的 window 属性几乎一致,但这里不需要额外指定 window 字段。

三、项目配置文件

1. 介绍

通常在使用一个工具的时候,都会针对各自喜好做一些个性化配置。例如编译配置等等,当你换了另外一台电脑重新安装工具的时候,你还要重新配置。

考虑到这点,小程序开发者工具在每个项目的根目录都会生成一个 project.config.json,你在工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。

配置文件:

project.config.json 文件中配置公共的配置。

project.private.config.json 配置个人配置。

优先级:

project.private.config.json 文件同样可以对项目进行配置。project.private.config.json 中的相同设置优先级高于project.config.json

📌 注意事项

① project.private.config.json 写到 .gitignore 避免版本管理的冲突。

② 与最终编译结果有关的设置必须设置到 project.config.json 中。

2. 编译插件

支持使用 sass/less

小程序代码包要求代码文件为 wxml / wxss / js / json / wxs。

如果我们希望使用 sass 或 less 去开发小程序,就需要将 sass / less 文件编译成对应的 wxss 文件。

project.config.json 文件中,修改 setting 下的 useCompilerPlugins 字段为 ["sass"],即可开启工具内置的 sass 编译插件。 如需同时开启 typescript 编译插件,可将该字段修改为 ["typescript ", "sass"]。 目前支持三个编译插件:typescript、less、sass。

json
{
  "setting": {
    "useCompilerPlugins": [
      "sass"
    ]
  }
}

配置好以后,需要将 .wxss 改成 .scss

📌 注意事项

我们在配置的时候,编译插件的名称是 sass,但是文件的后缀名是 .scss。

这是因为 Sass 是 CSS 预处理语言,scss 是 Sass 的一个语法版本。

四、sitemap.json

微信现已开放小程序内搜索,当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。

可以通过 sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。语法如下:

json
{
  "rules": [
    {
      "action": "allow",
      "page": "*"
    }
  ]
}

常用配置项:

属性属性说明属性值
action是否允许被搜索可选项有:allow、disallow
page允许/不允许被搜索的页面页面路径或者通配符
json
// 所有页面都会被微信索引 (默认情况)
{
  "rules": [
    {
      "action": "allow",
      "page": "*"
    }
  ]
}
json
// 配置 path/to/page 页面不被索引,其余页面允许被索引
{
  "rules":[
    {
      "action": "disallow",
      "page": "path/to/page"
    }
  ]
}

📌 注意事项

① 没有 sitemap.json 则默认所有页面都能被索引。

{"action": "allow", "page": "*"} 文件中默认的设置,是优先级最低的默认规则,所有页面都会被微信索引。

第三章:样式和内置组件

小程序中一切皆组件。

一、样式

1. 尺寸单位

随着智能手机的发展,手机设备的宽度也逐渐多元化,这就需要开发者在开发的时候,需要适配不同屏幕宽度的手机。为了解决屏幕适配的问题,微信小程序推出了 rpx 单位。

小程序运行在手机移动端,宿主环境是微信,因为手机尺寸的不一致,在写 CSS 样式时,开发者需要考虑到手机设备的屏幕会有不同的宽度和设备像素比,会采用一些技巧来算像素单位从而实现页面的适配。而 WXSS 在底层支持新的尺寸单位 rpx ,开发者可以免去换算的烦恼,只要交给小程序底层来换算即可。

rpx :小程序新增的拓展单位,可以根据屏幕宽度进行自适应,小程序规定任何型号手机:屏幕宽都为 750 rpx。

🔔 开发建议

开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。

iPhone6 的设计稿一般是 750px,小程序的宽是 750rpx。

在我们开发小程序页面时,量取多少 px ,直接写多少 rpx,开发起来更方便,也能够适配屏幕的适配。

原因

设计稿宽度是 750px,而 iPhone6 的手机设备宽度是 375px, 设计稿想完整展示到手机中,就需要缩小一倍。

在 iPhone6 下,px 和 rpx 的换算关系是:1rpx = 0.5px, 750rpx = 375px,刚好能够填充满整个屏幕的宽度。

2. 全局和局部样式

全局样式:指在 app.wxss 中定义的样式规则,作用于每一个页面,例如:设置字号、背景色、宽高等全局样式。

局部样式:指在 page.wxss 中定义的样式规则,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

二、组件

1. view 组件

view 是小程序提供的组件,是容器组件,类似于 div,也是一个块级元素,占据一行。

2. swiper 组件

在进行网页开发的时候,实现轮播图的时候,我们通常先使用 HTML、CSS 实现轮播图的样式结构,然后使用 JS 控制轮播图的效果,或者直接使用插件实现轮播图的功能,而在小程序中实现小程序功能则相对简单很多。

在小程序中,提供了 swiperswiper-item 组件实现轮播图:

  • swiper:滑块视图容器,常用来实现轮播图,其中只可放置 swiper-item 组件,否则会导致未定义的行为。
  • swiper-item:仅可放置在 swiper 组件中,宽高自动设置为 100%,代表 swiper 中的每一项。

可以使用 swiper 组件提供的属性,实现轮播图的订制,常见属性如下:

属性说明类型
indicator-dots是否显示面板指示点boolean (默认 false)
indicator-color指示点颜色color (默认:rgba(0, 0, 0, .3))
indicator-active-color当前选中的指示点颜色color (默认:#000000)
autoplay是否自动切换boolean (默认 false)
interval自动切换时间间隔number (默认 5000)
circular是否采用衔接滑动boolean (默认 false)
其他属性 ...

3. image 组件

在小程序中没有 img 标签,添加图片需要使用小程序提供的 image 组件,image 组件的语法如下:

html
<!-- src:图片资源地址 -->
<!-- mode 属性:用来设置图片的裁切模式、纵横比例、显示的位置 -->
<!-- lazy-load:图片懒加载,在即将进入一定范围(上下三屏)时才开始加载 -->
<!-- show-menu-by-longpress 属性:长按转发给朋友、收藏、保存图片 -->
<image src="/assets/tom.png" mode="heightFix" lazy-load=”{{ true }}“ show-menu-by-longpress />

4. text 组件

text 是文本组件,类似于 span,是行内元素。

html
<view class="info">
  <!-- user-select:文本是否可选 -->
  <!-- space:是否连续展示空格 -->
  <text user-select space="ensp">同城配送</text>
</view>

5. navigator

在网页开发中,如果想实现页面的跳转需要使用 a 标签,在小程序中如果想实现页面的跳转则需要使用 navigator 组件,语法如下:

html
<!-- url:当前小程序内的跳转链接 --> 
<navigator url="/pages/list/list">

常用的属性有 2 个:

  • url:当前小程序内的跳转链接。

  • open-type:跳转方式。

    • navigate:保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。

    • redirect: 关闭当前页面,跳转到应用内的某个页面。但不能跳转到 tabbar 页面。

    • switchTab:跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。

    • reLaunch:关闭所有页面,打开到应用内的某个页面。适用于需要清空当前所有页面栈的场景,比如登录状态失效后的重新登录。

    • navigateBack:关闭当前页面,返回上一页面或多级页面。通过 delta 属性可以设置返回的层数。适用于返回操作,特别是在嵌套多层页面时返回指定层级的场景。

📌 注意事项

① 路径后可以带参数。参数与路径之间使用 ? 分隔,参数键与参数值用 = 相连,不同参数用 & 分隔。例如:/list?id=10&name=hua,在 onLoad(options) 生命周期函数中获取传递的参数 。

② 属性 open-type="switchTab" 时不支持传参。

6. scroll-view

可滚动视图区域,适用于需要滚动展示内的场景,它可以在小程序中实现类似于网页中的滚动条效果,用户可以通过手指滑动或者点击滚动条来滚动内容,scroll-view 组件可以设置滚动方向、滚动条样式、滚动到顶部或底部时的回调函数等属性,可以根据实际需求进行灵活配置。

1)scroll-view 横向滚动

使用横向滚动时,需要添加 scroll-x 属性,然后通过 css 进行结构绘制,实现页面横向滚动。

2)scroll-view 纵向滚动

使用竖向滚动时,需要给 scroll-view 一个固定高度,同时添加 scroll-y 属性,实现页面纵向滚动。

三、其他

1. 字体图标的使用

css 中怎么使用,这里就怎么使用。只不过把 css 后缀文件改为 wxss。

注意:使用字体图标可能会报错:

[渲染层网络层错误] Failed to load font http://at.alicdn.com/t/c/font_3946178_q5oidsl5xo.woff2?t=1680795910637 net::ERR_CACHE_MISS (env: Windows,mp,1.06.2303220; lib: 2.30.4)

该错误可忽略,详见下面这个链接:

https://developers.weixin.qq.com/miniprogram/dev/api/ui/font/wx.loadFontFace.html

但在控制台出现错误,会影响开发调试,解决方案是:将字体图标转换成 base64 的格式。

2. 背景图片的使用

当编写小程序的样式文件时,我们可以使用 background-image 属性来设置一个元素的背景图像,但是小程序的 background-image 不支持本地路径。

第四章:事件处理

一个应用仅仅只有界面展示是不够的,还需要和用户做交互,例如:响应用户的点击、获取用户输入的值等等,在小程序里边,我们就通过编写 JS 脚本文件来处理用户的操作。

一、事件绑定和事件对象

小程序中绑定事件与在网页开发中绑定事件几乎一致,只不过在小程序不能通过 on 的方式绑定事件,也没有 click 等事件,小程序中绑定事件使用 bind 方法,click 事件也需要使用 tap 事件来进行代替,绑定事件的方式有两种:

第一种方式:bind:事件名,bind 后面需要跟上冒号,冒号后面跟上事件名。

html
<button bind:tap="handler">按钮</button>

第二种方式:bind事件名,bind 后面直接跟上事件名。

html
<button bindtap="handler">按钮</button>

当组件触发事件时,绑定的事件的处理函数会收到一个事件对象,用来记录事件发生时的相关信息。在触发事件时,事件处理程序会主动的给我们传入一个参数 —— event(事件对象)。

二、绑定并阻止事件冒泡

事件分为冒泡事件和非冒泡事件:

① 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。

② 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

使用 bind 绑定的事件,会触发事件冒泡,如果想阻止事件冒泡,可以使用 catch 来绑定事件。

html
<view bindtap="parentHandler">
  <!-- 使用 bind 绑定的事件,会产生事件冒泡 -->
  <!-- <button bindtap="handler">按钮</button> -->

  <!-- 使用 catcht 绑定的事件,会阻止事件冒泡 -->
  <button catchtap="handler">按钮</button>
</view>
js
Page({
  // 页面的初始数据
  data: {},

  // 事件处理程序
  handler (event) {
    console.log('我是子绑定的事件 ~~~')
  },
  
  parentHandler () {
    console.log('我是父绑定的事件 ~~~')
  }
    
  // 其他 coding...
})

WXML 中冒泡事件列表如下表:

类型触发条件
touchstart手指触摸动作开始
touchmove手指触摸后移动
touchcancel手指触摸动作被打断,如来电提醒,弹窗
touchend手指触摸动作结束
tap手指触摸后马上离开
longpress手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
longtap手指触摸后,超过350ms再离开(推荐使用 longpress 事件代替)
transitionend会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart会在一个 WXSS animation 动画开始时触发
animationiteration会在一个 WXSS animation 一次迭代结束时触发
animationend会在一个 WXSS animation 动画完成时触发
touchforcechange在支持 3D Touch 的 iPhone 设备,重按时会触发

📌 注意事项

除上表之外的其他组件自定义事件,如无特殊声明都是非冒泡事件。例如 formsubmit 事件,inputinput 事件。

三、事件传参

1. data-*自定义数据

在组件节点中可以通过 data- 的方式传递一些自定义数据,传递的数据可以通过事件对象的方式 (event.currentTarget.dataset) 进行获取。

📌 注意事项

使用 data- 方法传递参数的时候,多个单词由连字符 - 连接。

连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。

例如:

data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType

data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype

2. mark 自定义数据

小程序进行事件传参的时候,除了使用 data-* 属性传递参数外,还可以使用 mark 标记传递参数。

mark是一种自定义属性,可以在组件上添加,用于来识别具体触发事件的 target 节点。同时 mark 还可以用于承载一些自定义数据(类似于 dataset )。

markdataset 很相似,主要区别在于:

mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值 (事件委托的) 。

dataset 仅包含触发事件那一个节点的 data- 属性值。

第五章:WXML

一、页面数据

1. 声明和绑定数据

小程序页面中使用的数据均需要在 Page() 方法的 data 对象中进行声明定义。

在将数据声明好以后,需要在 WXML 中绑定数据,数据绑定最简单的方式是使用 Mustache 语法(双大括号)将变量包起来。

{{ }} 内部可以做一些简单的运算,支持如下几种方式:

  • 算数运算
  • 三元运算
  • 逻辑判断
  • 其他 …

📌 注意事项

{{ }} 语法中,只能写表达式,不能写语句,也不能调用 js 相关的方法。

2. 修改数据

小程序中修改数据并不能直接进行赋值,而是要通过调用 this.setData 方法才能实现。

将需要修改的数据以 key:value 的形式传给 this.setData 方法。

this.setData 方法有两个作用:更新数据、驱动视图更新。

1)修改基本数据
2)修改对象类型数据

在实际开发中,经常会在 data 中声明对象类型的数据,小程序中通过调用 setData 方法可以修改页面的数据,包括对象类型的数据。

定义一个对象。

json
Page({
  // 定义页面中使用的数据
  data: {
    userInfo: {
      name: 'Tom',
      age: 10,
      gender: '男'
    }
  }
}
[1] 路径方式

修改 / 新增对象中的单个属性。

json
this.setData({
  'userInfo.name': 'Jerry'
})

修改 / 新增对象中的多个属性。

json
// 修改对象中的多个属性
this.setData({
  'userInfo.name': 'Jerry',
  'userInfo.age': 100
})
[2] ES6 的展开运算符

在修改对象类型的数据时,可以使用 ES6 的展开运算符先复制对象,然后利用新值对旧值覆盖的方式修改。

js
const userInfo = {
  ...this.data.userInfo,
  name: 'Jerry',
  age: 100
}

// 修改对象中的多个属性
this.setData({
  userInfo
})
[3] 解构赋值修改

在修改对象类型的数据时,可以使用解构赋值来修改对象属性。

js
// 将 userInfo 从 data 中进行解构
const { userInfo } = this.data

// 产生一份新数据
const newUserInfo = {
  ...userInfo,
  name: 'Jerry',
  age: 100
}

// 修改对象中的多个属性
this.setData({
  userInfo: newUserInfo
})
[4] Object.assign 合并对象

在修改对象类型的数据时,可以使用 Object.assign 方法将多个对象合并为一个对象。

js
// 使用 Object.assign 方法将多个对象合并为一个对象
const userInfo = Object.assign(
  this.data.userInfo, 
  { name: 'Jerry' },
  { age: 100 }
)

// 修改对象中的多个属性
this.setData({
  userInfo
})
[5] 删除对象中的属性

删除对象中的单个属性。

js
// 使用 delete 删除对象中的属性
delete this.data.userInfo.age

this.setData({
  userInfo: this.data.userInfo
})
js
// 使用展开运算符拷贝一份数据,产生一个新对象
const newUser = { ...this.data.userInfo }
// 使用 delete 删除新对象中的属性
delete newUser.age

this.setData({
  // 将新的对象进行赋值
  userInfo: newUser
})

删除对象中的多个属性。

js
const { name, age, ...reset } = this.data.userInfo
// 使用 delete 删除新对象中的属性
delete newUser.age

this.setData({
  userInfo: reset
})

📌 注意事项

小程序的数据绑定机制只能监听到 setData 方法中修改的数据,无法监听到直接删除属性的操作,所以在删除对象属性时,需要先将对象复制一份再进行操作,然后再调用 setData 方法更新数据。

3)修改数组类型数据

数组类型数据也是经常会使用的数据格式之一,下面是修改数组类型数据的方法:

定义一个数组

js
Page({
  // 定义页面中使用的数据
  data: {
    animalList: ['Tom', 'Jerry', 'Spyke',{name: tom}]
  }

  // coding...
}
[1] concat 方法

在修改数组类型的数据时,可以使用数组的 concat 方法来合并数组。

js
// 使用 concat 方法来合并数组
const newList = this.data.animalList.concat('Tyke')

// 使用 setData 进行赋值
this.setData({
  animalList: newList
})
[2] push 方法

在修改数组类型的数据时,可以使用数组的 push 方法来添加元素。

js
// 使用数组的 push 方法来添加元素
this.data.animalList.push('Tyke')

// 使用 setData 进行赋值
this.setData({
  animalList: this.data.animalList
})
[3] ES6 展开运算符

在修改数组类型的数据时,可以使用 ES6 的展开运算符先复制数组,然后进行合并。

js
// 使用 ES6 的展开运算符先复制数组,然后进行合并
const newList = [...this.data.animalList, 'Tyke']

// 使用 setData 进行赋值
this.setData({
  animalList: newList
})
[4] 修改数组中某个元素的值

利用索引的方式进行修改,但必须使用 wx:for 来进行渲染数组,否则会出现错误。

js
this.setData({
  'animalList[2]': 'Tyke' 
})

this.setData({
  'animalList[3].name': 'jack' 
})
[5] filter 方法删除元素

在修改数组类型的数据时,可以使用数组的 filter 方法来删除元素。

js
// 使用数组的 filter 方法来删除元素
const newList = this.data.animalList.filter(item => item !== 'Tom')

// 使用 setData 进行赋值
this.setData({
  animalList: newList
})
[6] splice
js
// 使用数组的 filter 方法来删除元素
this.data.animalList.slice(1, 1)

// 使用 setData 进行赋值
this.setData({
  animalList: this.data.animalList
})

二、数据绑定 - 简易双向绑定

在 WXML 中,普通属性的绑定是单向的,例如:

html
<input value="{{ num }}" />

如果使用 this.setData 来更新 numnum 和输入框的中显示的值都会被更新为值。但如果用户修改了输入框里的值,却不会同时改变 data 中的 num

如果需要在用户输入的同时也将 data 中的数据修改 ,需要借助简易双向绑定机制。此时可以在对应项目之前加入 model: 前缀即可,例如:

html
<input model:value="{{ value }}" />

如果使用 this.setData 来更新 numnum 和输入框的中显示的值都会被更新为值。

如果输入框的值被改变了, data 的数据也会随着改变。

同时, WXML 中所有绑定了数据的位置也会被一同更新。

📌 注意事项

简易双向绑定的属性值如下限制:

① 只能是一个单一字段的绑定。例如,错误用法 <input model:value="值为 " />

② 尚不能写 data 路径,也就是不支持数组和对象。例如,错误用法 <input model:value="{{ a.b }}" />

三、列表渲染

1. 基本使用

列表渲染指通过循环遍历一个数组或对象,将其中的每个元素渲染到页面上。

只需要在组件上使用 wx:for 属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。

默认数组当前项的变量名默认为 item

默认数组的当前项的下标变量名默认为 index

在使用 wx:for 对数组进行遍历的时候,建议加上 wx:key 属性,如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,即以后数据不会改变,或者不必关注其顺序,可以选择忽略。

wx:key 的值以两种形式提供:

① 字符串:代表需要遍历的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。

② 保留关键字 *this 代表在 for 循环中的 item 本身,当 item 本身是一个唯一的字符串或者数字时可以使用。

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。

2. 进阶使用

修改默认下标和变量名:

如果需要对默认的下标和变量名进行修改,可以使用 wx:for-itemwx:for-index

① 使用 wx:for-item 可以指定数组当前元素的变量名。

② 使用 wx:for-index 可以指定数组当前下标的变量名。

html
<view wx:for="{{ animal }}" wx:for-item="itemName" wx:for-index="i">
  {{ itemName.name }} - {{ itemName.avatar }} - {{ i }}
</view>

渲染多节点结构块:

如果需要渲染一个包含多节点的结构块,可以使用一个 <block/> 标签将多个组件包装起来。

html
<block wx:for="{{ animal }}">
  <view>
    <span>{{ item.name }}</span>
    <span>{{ item.avatar }}</span>
  </view>
</block>

注意:<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

四、条件渲染

条件渲染主要用来控制页面结构的展示和隐藏,在微信小程序中实现条件渲染有两种方式:

① 使用 wx:ifwx:elifwx:else 属性组。

② 使用 hidden 属性。

html
<view wx:if="{{condition}}"> True </view>
html
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
html
<view hidden="{{condition}}"> True </view>

wx:ifhidden 二者的区别:

  • wx:if :当条件为 true 时将内容渲染出来,否则元素不会进行渲染,通过移除/新增节点的方式来实现。
  • hidden :当条件为 true 时会将内容隐藏,否则元素会显示内容,通过 display 样式属性来实现的。

第六章:小程序生命周期

一、小程序运行时

1. 运行机制

官方文档:小程序运行时 / 运行机制

2. 更新机制

在访问小程序时,微信会将小程序代码包缓存到本地。

开发者在发布了新的小程序版本以后,微信客户端会检查本地缓存的小程序有没有新版本,并进行小程序代码包的更新。

小程序的更新机制有两种:启动时同步更新和启动时异步更新。

  • 启动时同步更新

    微信运行时,会定期检查最近使用的小程序是否有更新。如果有更新,下次小程序启动时会同步进行更新,更新到最新版本后再打开小程序。如果用户长时间未使用小程序时,会强制同步检查版本更新。

  • 启动时异步更新

    在启动前没有发现更新,小程序每次冷启动时,都会异步检查是否有更新版本。如果发现有新版本,将会异步下载新版本的代码包,将新版本的小程序在下一次冷启动进行使用,当前访问使用的依然是本地的旧版本代码。

在启动时异步更新的情况下,如果开发者希望立刻进行版本更新,可以使用 wx.getUpdateManager API 进行处理。在有新版本时提示用户重启小程序更新新版本。

js
App({
  /**
   * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   */
  onLaunch: function () {
    const updateManager = wx.getUpdateManager()

    updateManager.onCheckForUpdate(function (res) {
      // 请求完新版本信息的回调
      console.log(res.hasUpdate)
    })

    updateManager.onUpdateReady(function () {
      wx.showModal({
        title: '更新提示',
        content: '新版本已经准备好,是否重启应用?',
        success(res) {
          if (res.confirm) {
            // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
            updateManager.applyUpdate()
          }
        }
      })
    })

    updateManager.onUpdateFailed(function () {
      // 新版本下载失败
    })
  }
})

二、生命周期

小程序的生命周期分类三类:应用级别、页面级别和组件级别 3 种类型。

1. 应用级别生命周期

应用生命周期通常是指一个小程序从启动 → 运行 → 销毁的整个过程。

应用生命周期伴随着一些函数,我们称为应用生命周期函数,应用生命周期函数需要在 app.js 文件的 App() 方法中定义。

当整个小程序应用运行到某个时机的时候,我们需要做一些事情。例如:当小程序启动成功之后,我们要获取小程序的一些信息,就可以在小程序启动成功时的钩子函数中写代码获取我们想要的信息。

生命周期必填说明
onLaunch监听小程序初始化,全局只会执行 1 次
onShow监听小程序启动或切前台
onHide监听小程序切后台

📌 注意事项

① 从小程序生命周期的角度来看,我们一般讲的「启动」专指冷启动,热启动一般被称为后台切前台。

② App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

小程序启动后,后台会首先完成小程序的初始化,该过程只会触发一次;之后会完成显示的工作,用户可以操作小程序从前台进入后台以及从后台回复到前台显示;小程序在后台运行一段时间,当系统资源不足时会被注销。

2. 页面级别生命周期

页面生命周期就是指小程序页面从加载 → 运行 → 销毁的整个过程。

当某个页面运行到某个时机的时候,我们需要做一些事情,例如: 当某个页面加载完毕之后,需要发请求获取当前页面所需的数据,就可以在对应的页面加载完成后的钩子函数中执行发送请求的代码。

小程序中的一个页面都需要在对应页面的 .js 文件中调用 Page() 方法来注册。Page() 接受一个 Object 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

生命周期必填说明
onLoad页面加载时触发 (一个页面只会调用一次)
onShow页面显示时触发,页面显示/切入前台时触发
onReady页面初次渲染完成时触发 (一个页面只会调用一次)
代表页面已经准备妥当,可以和视图层进行交互
onHide页面隐藏/切入后台时触发
onUnload页面卸载时触发

onShow 更多关注于页面的显示状态,每次页面出现在用户面前时都会触发,适合做数据刷新等操作;而 onReady 关注于页面的渲染完成状态,仅在页面初次加载完成时触发一次,适合做一些初始化的设置或操作。

📌 注意事项

tabBar 页面之间相互切换,页面不会被销毁。

点击左上角,返回上一个页面,会销毁当前页面 (被打开页面) 。

Released under the MIT License.