小程序的核心语法
开篇
小程序核心语法:
- 数据驱动原则
- 实现两个案例,串联核心知识点
- 商品案例
- 列表案例
小程序的数据驱动原则
问题:
- 什么是数据驱动?
- 在小程序中如何完成数据绑定?
数据驱动:
// 商品
let product = {
price: 10,
num: 5
}
// 总价格
let total = 0;
// 计算总价格的方法
function getTotal(product) {
return product.price * product.num
}
// 计算商品的总价格
total = getTotal(product)
// 进行打印
console.log('总价格:' + total);
// 50 太贵了,所以我们少购买了两个商品,也就是让 num = 3
product.num = 3;
// 问:总价格是多少?
console.log('总价格:' + total); // 此时,打印发现总价格还是 50 元,如果要说原因的话,那么应该很简单,【因为我们没有重新进行价格的计算嘛】
// 但是,此时大家有没有想过一点?我们为什么要进行价格的计算呢?
// ----------------------------------------------------
// 当商品的数量发生变化时,商品的总价格【理应发生变化】,不是吗?
上面的例子,就是我想要跟大家说的:【当数量发生变化时,商品的总价格理应发生改变】。
那么同样的道理,在我们的页面中,假如:
某一个 DOM 依赖于某个数据进行展示,那么【当数据发生变化时,视图也理应发生变化】。
而这个就是【响应式数据驱动】。
PS:如果大家想要跟深入的了解,那么可以查看博客:聊一聊响应式构建的那些经历
小程序中完成响应式:
-
在
data
中定义数据// index.js // 获取应用实例 const app = getApp() Page({ data: { product: { price: 10, num: 5 } } })
-
在
wxml
中使用数据<view> <view> <!-- wxml 中访问数据,必须使用 { {}} 语法,{ {}} 语法中可以放置【任意的、单一的 JavaScript 表达式】 --> 商品的单价:{ {product.price}} </view> <view> 商品的数量:{ {product.num}} </view> <view> 商品的总价格:{ {product.price * product.num}} </view> </view>
现在我们已经可以在 js 的 data
中定义数据,并且在 wxml 中通过 {
{}}
语法使用数据。
那么我们回过头来看我们的问题:
答案:
- 什么是数据驱动?
- 当数据发生变化时,视图理应发生变化
- 在小程序中如何完成数据绑定?
- 在 data 中定义数据
- 在 wxml 中通过 { {}} 使用数据
但是在此时,大家心里应该还有一个疑惑,那就是:【现在数据还没有发生变化呀?我也没有看到视图的变化呀?】。
如果你心中确实有这么一个困惑的话,那么就继续往下看!
小程序中的常用事件与属性列表
问题:
- 如何为按钮添加点击事件?
- 如何修改 data 中数据的值?
处理点击事件
接下来我们希望做一件事情:
创建一个按钮
当用户点击按钮时
让 product 的 num + 1
创建按钮的方式非常简单:
<button type="primary">num + 1</button>
问题在于:我们如何给这个按钮添加点击事件呢?
有过开发经验的同学,可能会猜到:我们可以给 button
一个 click
事件来监听按钮的点击。
可是大家需要知道,现在我们是在【小程序】中,那么如果想要给 button
添加点击事件则不可以使用 click
而是 bind:tap / bindtap
。
其中 bind: / bind
表示【绑定事件】,tap
为绑定的具体事件。小程序具体事件列表,可以点击 这里 查看。
<button type="primary" bind:tap="onAddNum">num + 1</button>
接下来需要在 js
中定义对应的 事件
/**
* 定义事件处理的方法
*/
onAddNum () {
console.log('onAddNum')
}
到目前:我们已经 监听了按钮的点击事件,并且写入了对应的处理函数 ,接下来就需要 **修改 num 的值 **
修改 data 的数据
想要修改 data
中的数据,那么我们需要借助一个函数 setData
。
setData
接收一个 对象作为参数,这个对象就是最新的 data
数据。
其中 key
为要修改的数据, value
为最新的值
访问 data 的数据
因为我们想要让 num + 1
,所以我们还需要拿到 num
的当前值,想要访问 num
的值,可以通过 this.data.product.num
的形式访问
所以最终的修改 num
的代码为:
/**
* 定义事件处理的方法
*/
onAddNum () {
this.setData({
'product.num': this.data.product.num + 1
})
此时,当我们点击 button
,可以发现:【当 num 发生改变时,总价格也发生了对应的变化】
答案:
- 如何为按钮添加点击事件?
bindtap
||bind:tap
- 如何修改 data 中数据的值?
- 通过
this.setData({})
定义新的值- 通过
this.data
访问具体的值
事件传参
问题:
- 如果想要在【点击事件中】传递参数,那么需要怎么做?
新的需求
现在让我们把需求变得更加复杂一些。
我们希望
onAddNum
方法可以接收一个参数,每次点击num
增加的数量为传入的参数
那么如果想要实现这个需求的话,那么就需要涉及到一个知识点:【事件传参】。
如果大家有过开发经验的话,那么可能会认为这是一个非常简单的需求,顺便可以写下如下代码:
// html
<button type="primary" bind:tap="onAddNum(5)">num + 1</button>
// js
onAddNum (step) {
this.setData({
'product.num': this.data.product.num + step
})
}
可是,假如我们真按照以上代码进行实现的话,那么 你应该会收到以下如下的警告:
这个警告的意思是:没有一个叫做 onAddNum(5)
的方法用来处理当前的这个 tap
事件。
也即是说:onAddNum(5)
会被当做一个 完整的方法名字,而不是 方法名为:onAddNum
,传入了参数为 5
!
那么如果我们想要传递参数应该怎么做呢?
在小程序中,如果想要给 **点击事件传递参数的话,**那么需要借助 event 对象 和 data- 属性 !
参数的传递包含两个部分:
- 形参
- 实参
形参:
首先先来看 形参,对于 点击事件的回调方法 而言,默认会接收一个参数 event (事件对象)。这个 event
对象为:回调方法的唯一参数
实参:
对于 小程序 中,我们不能直接为 回调方法传递实参。
而是需要通过:属性绑定的形式,把需要传递的参数绑定到 当前 DOM
元素中,绑定数据的属性需要以 data-
开头。该属性可以通过 e.target.dataset
进行访问。
// html
<button type="primary" bind:tap="onAddNum" data-step="5">num + 1</button>
// js
onAddNum (e) {
// 获取 data-step 的值
let step = parseInt(e.target.dataset.step);
this.setData({
'product.num': this.data.product.num + step
})
}
答案:
- 如果想要在【点击事件中】传递参数,那么需要怎么做?
- 通过属性绑定(data-xx)的形式,把需要传递的参数绑定到 当前
DOM
元素中- 在对应的回调函数中,通过
e.target.dataset
进行访问
实现【双向数据绑定】
问题:
- 什么叫做双向数据绑定?
- 小程序中如何实现双向数据绑定?
上一章节中我们通过【事件传参】实现了【每次点击 + 5】 的功能,但是这样的功能未免还是有些太单调了。
所以我们接下来希望实现一个新的功能:
创建一个数字输入框,输入框 与【商品数量】完成 【双向数据绑定】。
即:
- 输入框内容发生变化时,商品数量同步跟随变化
- 商品数量发生变化时,输入框内容同步跟随变化
那么这样的功能我们应该如何去实现呢?
如果想要实现这个功能,那么我们需要先把这个功能进行拆解,【把一个复杂的功能拆解成多个简单的功能】是实现一个复杂逻辑的标准方式。
那么如何进行拆解呢? 大家可以先进行以下思考,然后再继续向下进行学习!
以上功能拆解如下:
- 创建一个【数字输入框】
- 设置 【商品数量】 为输入框的初始值
- 监听用户的输入行为
- 获取用户输入的值
- 赋值给【商品数量】
// html
<view>
商品的数量:
<!-- 1. 创建一个【数字输入框】 -->
<!-- 2. 设置 【商品数量】 为输入框的初始值 -->
<input class="num-input" type="number" value="{
{ product.num }}" bindinput="onInput" />
</view>
// js
/**
* 3. 监听 input 的输入事件
*/
onInput (e) {
// 4. 获取用户输入的值
const val = parseInt(e.detail.value);
// 5. 赋值给【商品数量】
this.setData({
'product.num': val
})
那么现在功能我们已经实现了,那么大家在回忆一下我们的问题:
答案:
- 什么叫做双向数据绑定?
- 当视图发生变化时,数据跟随发生变化。
- 当数据发生变化时,视图跟随发生变化.
- 小程序中如何实现双向数据绑定?
- 通过
value
为input
视图绑定数据- 通过监听
bindinput
获取视图的变化,在回调方法中修改数据
条件渲染
问题:
- v-if 和 hidden 的区别是什么?
现在你已经买了很多的商品了,可是当你出去结账的时候,售货员小姐姐对你发出了一声惊呼:
- 如果【总价格 <= 100 】:hello 帅哥
- 如果【总价格 > 100 && 总价格 < 1000】:哇哦 有钱人哦
- 如果【总价格 >= 1000】:土豪你好
如果想要实现这么一个功能的话,那么就需要使用【条件渲染】的功能了。
小程序中提供了两个 API 都可以实现【条件渲染】的功能:
wx:if ... wx:elif ... wx:else
hidden
那么下面我们就分别用这两个语法来实现一下这个功能:
<!-- wx:if ... wx:elif ... wx:else:判断结果为 true 则进行渲染,否则不进行渲染 -->
<view>
售货员小姐姐惊呼:
<text wx:if="{
{ product.price * product.num <= 100 }}">hello 帅哥</text>
<text wx:elif="{
{ product.price * product.num > 100 && product.price * product.num < 1000 }}">哇哦 有钱人哦</text>
<text wx:else>土豪你好</text