第三单元 小程序基础一
一、昨日知识点回顾
1.小程序项目结构 2.小程序全局配置 3.小程序常用的UI组件 4.小程序生命周期
二、本单元知识点概述
三、本单元教学目标
(Ⅰ)重点知识目标
1.小程序语法 2.wxs
(Ⅱ)能力目标
1.掌握小程序基本语法 2.掌握wxs的使用及应用场景
四、本单元知识详讲
3.1. 数据绑定
3.1.1 如何定义页面的数据
-
小程序中每个页面,由4部分组成,其中 .js 文件内可以定义页面的数据、生命周期函数、其它业务逻辑
-
如果要在.js文件内定义页面的数据,只需把数据定义到 data 节点下即可
-
示例代码:
Page({ data: { msg: "hello world" } })
3.1.2 Mustache的语法格式
-
把data中的数据绑定到页面中渲染,使用 Mustache 语法(双大括号)将变量包起来即可
-
语法格式:
<view>{{ 要绑定的数据名称 }}</view>
-
示例代码:
<view>{{ msg }}</view>
Page({ data: { // 定义小程序的数据 msg: "hello world", // 字符串类型 arr: [1, 2, 3], // array falg: true // Boolean } })
-
Mustache 语法的主要应用场景:
-
绑定内容
-
绑定属性:小程序中所有的自定义属性都是
data-*
的格式<view data-id="{{ id }}">我是要绑定的属性</view>
Page({ id: 0 })
-
运算(三元表达式、算术运算、逻辑判断、字符串运算、数据路径运算)
-
3.2. 小程序中的事件
3.2.1 BindTap绑定触摸事件
-
绑定触摸事件
-
在小程序中,不存在网页中的 onclick 鼠标点击事件,而是通过 tap 事件来响应触摸行为
-
语法格式:
<button bindtap="handleTap">点击</button>
在相应的Page定义中写上相应的事件处理函数,事件参数是event
Page({ // 手指触摸事件 handleTap(ev) { // ev: 代表的就是事件对象 console.log(ev) } })
-
阻止事件冒泡:将bindtap事件换成catchtap事件
<button catchtap="handleTap">点击</button>
-
-
绑定文本框输入事件
-
在小程序中,通过 input 事件来响应文本框的输入事件
-
语法格式:
<input type="text" bindinput="handleInput" />
在相应的Page定义中写上相应的事件处理函数,事件参数是event
Page({ handleInput(ev) { console.log(ev) } })
-
3.2.2 data与文本框之间的数据同步
-
监听文本框的数据变化
-
在文本框的 input 事件处理函数中,通过事件参数 event,能够访问到文本框的最新值
-
语法格式: event.detail.value
-
示例代码:
Page({ handleInput(ev) { // 获取到文本框输入的值:ev.detail.value console.log(ev.detail.value) } })
-
-
修改data中的数据
-
通过 this.setData(dataObject, cb) 方法,可以给页面中的 data 数据重新赋值
-
dataObject:data中要改变的数据
-
-
-
cb(可选):当数据更新完毕以后触发的回调函数
-
示例代码:
Page({ handleInput(ev) { this.setData({ value: ev.detail.value }, () => { // 数据更新完毕以后触发,是可选的 console.log('数据更新完毕了') }) } })
3.2.3 通过data-*自定义属性参数
-
不能在绑定事件的同时传递参数
-
小程序中的事件传参比较特殊,不能在为组件绑定事件的同时,为事件处理函数传递参数
-
错误代码示例:
<button type="primary" bindtap='btnHandler(123)'>事件传参</button>
-
原因:小程序会把 bindtap 后指定的值,统一当作事件名称来处理
-
-
通过data-*自定义属性传参
-
如果要在组件触发事件处理函数的时候,传递参数,可以为组件提供 data-* 自定义属性传参
-
示例代码:
<button data-id="{{ id }}" bindtap="handleTap">点击</button>
-
-
获取data-*自定义属性中传递的参数
-
通过事件参数 event.currentTarget.dataset.参数名,能够获取 data-* 自定义属性传递到事件处理函数中的参数
-
示例代码:
handleTap(ev) { console.log(ev.currentTarget.dataset.id) }
-
3.3. wxs
3.3.1 什么是wxs
-
概念:wxs(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构
-
使用场景:在wxml语法的渲染当中,在mustache中是不能调用函数的
3.3.2 Wxs的使用注意事项以及遵循的规范
-
没有兼容性:wxs 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行
-
与JavaScript不同:wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致
-
隔离性:wxs 的运行环境和其他 javascript 代码是隔离的,wxs 中不能调用其他 javascript 文件中定义的
函数,也不能调用小程序提供的API
-
不能作为事件回调:wxs 函数不能作为组件的事件回调
-
ios设备上比javascript运行快:由于运行环境的差异,在 iOS 设备上小程序内的 wxs 会比 javascript
代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异
-
wxs遵循CommonJs模块化规范
3.3.3 使用module.exports向外共享成员
-
通过 module.exports 属性,可以对外共享本模块的私有变量与函数。
-
示例代码:
var num = 100; // 定义一个变量 var test = function() { console.log(1) } module.exports = { // 暴露私有成员 num2: num }
3.3.4 Wxs的内嵌与外联
-
内嵌写法
-
wxs 代码可以编写在 wxml 文件中的
<wxs></wxs>
标签内,就像 javascript 代码可以编写在 html 文件 中的<script></script>
标签内一样 -
wxml 文件中的每个
<wxs></wxs>
标签,必须提供一个 module 属性,用来指定当前<wxs></wxs>
标 签的模块名。在单个 wxml 文件内,建议其值唯一 -
示例代码:
<!-- pages/index/index.wxml --> <wxs module="mod"> var num = 100; function reverseMsg(str) { return str.split('').reverse().join('') } module.exports = { // 想外暴露私有成员 num: num, reverseMsg: reverseMsg } </wxs>
-
-
外联写法
-
wxs 代码还可以编写在以 .wxs 为后缀名的文件内,就像 javascript 代码可以编写在以 .js 为后缀名的文 件中一样
-
示例代码:
// utils/utils.wxs var num = 100; function reverseMsg(str) { return str.split('').reverse().join('') } module.exports = { // 想外暴露私有成员 num: num, reverseMsg: reverseMsg }
<!-- pages/index/index.wxml --> <wxs module="mod" src="../../utils/utils.wxs"></wxs>
-
3.3.5 使用require引入其他wxs模块以及注意事项
-
假设有两个 wxs 模块,路径分别为 /pages/tools.wxs 和 /pages/logic.wxs,如果要在 logic.wxs 中引 入 tools.wxs 脚本
-
示例代码:
// require中的路径只能是相对路径 var mod = require('./tool.wxs') function reverseMsg(str) { return str.split('').reverse().join('') } module.exports = { // 想外暴露私有成员 num: mod.num, reverseMsg: reverseMsg }
-
注意事项:
-
只能引用 .wxs 文件模块,且必须使用相对路径。
-
wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多 次引用,使用的都是同一个 wxs 模块对象。
-
如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。
-
3.3.6 Wxs支持的数据类型
-
WXS 语言目前共有以下几种数据类型:
-
number
: 数值 -
string
:字符串 -
boolean
:布尔值 -
object
:对象 -
function
:函数 -
array
: 数组 -
date
:日期 -
regexp
:正则
-
3.4. 条件渲染
3.4.1 wx:if
-
在小程序中,使用 wx:if="{{ condition }}" 来判断是否需要渲染该代码块
<view wx:if="{{ arr.length === 3 }}">1</view>
-
也可以用 wx:elif 和 wx:else 来添加一个 else 块
<view wx:elif="{{ arr.length < 3 }}">2</view> <view wx:else>3</view>
3.4.2 block wx:if
-
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个
<block></block>
标签将多个组件包装起来,并在上边使用 wx:if 控制属性 -
示例代码:
<block wx:if="{{ flag }}"> <view>123</view> <view>456</view> </block>
-
注意:
<block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲,只接受控制属性
3.4.3 hidden
-
在小程序中,直接使用 hidden="{{ condition }}" 也能控制元素的显示与隐藏
-
示例代码:
<block hidden="{{ flag }}"> <view>123</view> <view>456</view> </block>
3.4.4 hidden和wx:if的区别
-
被
wx:if
控制的区域,框架有一个局部渲染的过程,会根据控制条件的改变, 动态创建或销毁对应的UI结构 -
wx:if
是惰性的,如果在初始渲染条件为 false,框架什么也不做, 在条件第一次变成真的时候才开始局部渲染 -
hidden
只是 简单的控制组件的显示与 隐藏,组件始终会被渲染 -
wx:if
有更高的切换消耗而hidden
有更高的 初始渲染消耗。因此,如果需要 频繁切换的情景下,用hidden
更好,如果 运行时条件不大可能改变则wx:if
较好。
3.5. 列表渲染
3.5.1 wx:for
-
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件
-
默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item
-
语法示例:
<view wx:for="{{ arr }}" wx:key="index">{{ item }}---{{ index }}</view>
Page({ arr: ['A', 'B', 'C', 'D'] })
3.5.2 block wx:for
-
类似 block wx:if,也可以将
wx:for
用在<block></block>
标签上,以渲染一个包含多节点的结构块 -
示例代码:
<block wx:for="arr" wx:key="index"> <text>{{item }}</text> <text>{{ index }}</text> </block>
3.5.3 指定索引与当前项的变量名
-
使用wx:for-item可以指定数组当前元素的变量名
-
使用wx:for-index可以指定数组当前下标的变量名
-
语法示例:
<view wx:for="{{ arr }}" wx:key="idx" wx:for-item="el" wx:for-index="idx"> {{ el }} --- {{ idx }} </view>
3.5.4 列表渲染中的wx:key
-
key在列表循环中的作用
-
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如
<input/>
中的输入内容,<checkbox/>
的选中状态),需要使用wx:key
来指定列表中项目的 唯一的标识符 -
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率
-
-
key值的注意点
-
key 值必须具有唯一性,且不能动态改变
-
key 的值必须是数字或字符串
-
保留关键字*this代表在 for 循环中的item本身,它也可以充当 key 值,但是有以下限制:需要item本身是一个唯一的字符串或者数字。
-
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略
-
五、本单元知识总结
1.明白下单的流程
六、作业安排
(Ⅰ)认真掌握知识点和前端的技术