注:本文章只描述一些重点,详情使用方法见官方文档:微信开放文档/开发
一、声明和绑定数据
小程序页面中使用的数据均需要在Page()方法的data对象中声明定义,将数据声明好以后,在WXML中使用Mustache语法(双大括号{{}})将变量包起来,从而将数据绑定
1、绑定属性值,若需要动态绑定一个变量,属性值也需要使用双大括号包裹在内;如果属性值是布尔值,也需要使用双大括号包裹在内
2、在{{}}内部可以做一些简单运算,支持以下几种方式:算数运算,逻辑判断,三元运算,其他
3、在{{}}内,只能写表达式,不能写语句,也不能调用js相关的方法
声明数据-js文件代码示例:
data: {
work:"若风里有诗",
obj:{
name:"诗歌"
},
id:1,
ischecked:false
}
绑定数据-wxml文件代码示例:
<!-- 展示内容 -->
<view>{{ work }}</view>
<view>{{ obj.name }}</view>
<!-- 绑定属性值,若需要动态绑定一个变量,属性值也需要使用双大括号包裹在内 -->
<view id="{{ id }}">绑定属性值</view>
<!-- 如果属性值是布尔值,也需要使用双大括号包裹在内 -->
<checkbox checked="{{ flase }}" />
<checkbox checked="{{ ischecked }}" />
<!-- 在{{}}内部可以做一些简单运算,支持以下几种方式:算数运算,逻辑判断,三元运算,其他 -->
<!-- 算术运算 -->
<view>{{ id + 1 }}</view>
<view>{{ id - 1 }}</view>
<!-- 三元运算 -->
<view>{{ id == 1 ? "等于" : "不等于"}}</view>
<!-- 逻辑运算 -->
<view>{{ id == 1 }}</view>
<!-- 注意:在{{}}内,只能写表达式,不能写语句,也不能调用js相关的方法 -->
<!-- 错误示范: -->
<!-- <view>{{ if (id == 1) {} }}</view>
<view>{{ <obj.name.toUpperCase() }}</view> -->
二、setData()修改数据
小程序中修改数据不推荐通过赋值的方法进行修改,通过此方法修改数据无法改变页面的数据
而是通过调用setData()方法修改数据,此方法接收对象作为参数,key是需要修改的数据,value是新的值
setData()方法不仅可以更新数据,还能驱动视图更新,即修改页面的数据
wxml文件代码示例:
<view>{{ num }}</view>
<button bind:tap="updateNum">更新 num</button>
js文件代码示例:
//声明数据
data: {
num:1
}
//更新数据
updateNum(){
//通过赋值的方式直接修改数据,通过此方法修改数据无法改变页面的数据
// this.data.num += 1
// key是需要修改的数据,value是新的值
// setData()方法有两个作用:
// 1、更新数据
// 2、驱动视图更新
this.setData({
num: this.data.num + 1
})
//打印数据
console.log(this.data.num)
}
三、setData()修改对象类型数据
1、新增单个/多个属性
2、修改单个/多个属性
3、删除单个/多个属性
wxml文件代码示例:
<view>{{userinfo.name}}</view>
<view>{{userinfo.age}}</view>
<button type="warn" bind:tap="updateUserInfo">修改对象类型数据</button>
js文件代码示例:
//声明数据对象
data: {
userinfo:{
name: "Tom",
age: 10,
test: 111
}
}
//更新 userInfo
updateUserInfo(){
// //一、新增单个/多个属性
// this.setData({
// //如果给对象新增属性,可以把key写成数据路径的形式a.b.c
// 'userinfo.name':'Tom',
// 'userinfo.age':18
// })
// //二、修改单个/多个属性
// this.setData({
// //如果给对象修改属性,可以把key写成数据路径的形式a.b.c
// 'userinfo.name':'Bob',
// 'userinfo.age':16
// })
//目前新增和修改都是使用数据路径,若修改数据量比较小还可以,如果量比较大,就比较麻烦,需要优化:可以使用 ES6 提供的展开运算符和 Object.assign()
// 1、ES6 提供的展开运算符:通过展开运算符能够将对象中的属性复制给另外一个对象,后面的属性会覆盖前面的属性
// const userinfo = {
// ...this.data.userinfo,
// name: "jerry",
// age: 20
// }
// this.setData({
// userinfo
// })
// 2、Object.assign() 将多个对象合并为一个对象
// const userinfo = Object.assign(this.data.userinfo,{name:'lida'},{age:24})
// this.setData({
// userinfo
// })
// 三、删除单个/多个属性
// // 1、删除单个属性
// delete this.data.userinfo.age
// console.log(this.data.userinfo)
// this.setData({
// userinfo:this.data.userinfo
// })
// 2、删除多个属性 rest 剩余参数
const{age ,test ,...rest} = this.data.userinfo
this.setData({
userinfo:rest
})
}
四、setData()修改数组类型数据
1、新增数组元素
2、修改数组元素
3、删除数组元素
wxml文件代码示例:
<view wx:for="{{ list }}" wx:key="index">{{ item }}</view>
<view>{{ dictList[0].name }}</view>
<button type="primary" bind:tap="updateList">修改数组类型数据</button>
js文件代码示例:
//声明数组数据
data: {
list:[1, 2, 3],
dictList: [ {id: 1,name: 'tom'} ]
}
//更新数组数据
updateList(){
// 1、新增数组元素
//如果直接用 push 方法,可以更新 data,但不能更新页面中的内容
// this.data.list.push(4)
// console.log(this.data.list)
//1.1 同时更新数据和页面中的内容的第一种语法
// this.data.list.push(4)
// this.setData({
// list: this.data.list
// })
//1.2 同时更新数据和页面中的内容的第二种语法
// const newList = this.data.list.concat(4)
// this.setData({
// list: newList
// })
//1.3 同时更新数据和页面中的内容的第三种语法
// const newList = [ ...this.data.list, 4]
// this.setData({
// list: newList
// })
// 2、修改数组元素
// this.setData({
// 'list[1]': 6,
// 'dictList[0].name': "jerry"
// })
// 3、删除数组元素
//如果直接用 splice 方法,可以删除 data 元素,但不能更新页面中的内容
//3.1 同时删除数据和页面中的内容的第一种语法
// this.data.list.splice(1,1)
// this.setData({
// list: this.data.list
// })
//3.2 同时删除数据和页面中的内容的第二种语法
const newList = this.data.list.filter(item => item !==2 )
this.setData({
list: newList
})
}
五、简易双向绑定数据
在wxml语法中,普通属性的绑定是单向的:数据可以影响页面,反过来页面却不能影响数据:例如 <input value=“{{value}}/”
若希望用户输入数据的同时改变data中的数据,可以才有简易双向绑定机制,只需要在对象属性之前添加 model: 前缀即可:例如 <input model:value=“{{value}}/”
注意事项:简易双向绑定的属性值有以下限制:
1、只能是一个单一字段的绑定,不能进行拼接
2、尚不能写数据路径,也就是不支持数组和对象
wxml文件代码示例:
<!-- 在wxml语法中,普通属性的绑定是单向的:数据可以影响页面,反过来页面却不能影响数据,注:可通过调试器->AppData,来查看数据的值 -->
<!-- <input type="text" value="{{value}}"/> -->
<!-- 若希望用户输入数据的同时改变data中的数据,可以才有简易双向绑定机制,只需要在对象属性之前添加 model: 前缀即可 -->
<input type="text" model:value="{{value}}"/>
<!-- 如果需要获取复选框的选中状态,需要给 checked 添加 model: -->
<checkbox model:checked="{{ isChecked }}"/> 是否同意该协议
<!-- 注意事项1:属性值只能是一个单一字段的绑定,错误示例: -->
<!-- <input type="text" model:value="值为{{value}}"/> -->
<!-- 注意事项2:属性值不能写数据路径,也就是不支持数组和对象,错误示例: -->
<!-- <input model:value="{{obj.value}}"/> -->
js文件代码示例:
//声明数据
data: {
value: 123,
isChecked: false,
obj:{
value: 456
}
}
六、列表渲染
1、列表渲染的基本使用:
列表渲染是通过循环遍历每一个数组或对象,将其中每一个元素渲染到页面上
在组件中使用 wx:for 属性绑定一个数组或对象,既可使用每一项数据重复渲染当前组件,每一项变量名默认为 item,下标变量名默认为 index
1.1、在使用 wx:for 进行遍历时,建议加上 wx:key 属性,wx:key 值以两种形式提供:
1.1.1、字符串:代表需要遍历的 array 中 item 的某个属性,该属性的值需要是列表中唯一的字符串或数字,且不能动态改变
1.1.2、保留关键字 *this 代表在 for 循环中的 item 本身,当 item 本身是唯一的字符串或数字时可以使用
1.2、注意事项:
1.2.1、如果不加 wx:key ,会报一个 warning,若明确知道该列表是静态的,即以后数据不会改变或不必关注其顺序,则可选择忽略
1.2.2、在给 wx:key 添加属性值的时候,不需要使用双大括号语法,直接使用遍历的 array 中 item 的某个属性
2、列表渲染的进阶用法:
2.1、如果需要对默认的变量名和下标进行修改,可以使用 wx:for-item 和 wx:for-index:
2.1.1、使用 wx:for-item 可以指定数组当前元素的变量名
2.1.2、 使用 wx:for-index 可以指定当前下标的变量名
2.2、将 wx:for 用在block标签上,以渲染一个包含多个节点的结构块
2.2.1、block并不是一个组件,它仅仅是一个包装元素,在页面不会有任何渲染,只接受控制属性
2.2.2、block标签在 wxml 中用于组织代码结构,支持列表渲染、条件渲染等
wxml文件代码示例:
<!-- 如果渲染的是一个数组,item:数组的每一项,index:下标 -->
<!-- <view wx:for="{{ numList }}">{{item}} - {{index}}</view> -->
<!-- 如果渲染的是一个对象,item:对象的属性值,index:对象的属性 -->
<!-- <view wx:for="{{ obj }}">{{item}} - {{index}}</view> -->
<!-- wx:key 提升性能 -->
<!-- wx:key 值是 array 中 item 的某个属性 -->
<view wx:for="{{ fruitList }}" wx:key="id">{{item.name}}</view>
<view wx:for="{{ fruitList }}" wx:key="index">{{item.name}}</view>
<!-- wx:key 值是 *this,*this 代表在 for 循环中的 item 本身 -->
<view wx:for="{{ numList }}" wx:key="*this">{{item}}</view>
<view class="line"></view>
<!--
如果需要修改默认变量名,需使用 wx:for-item 属性
如果需要修改默认下标变量名,需使用 wx:for-index 属性
两个属性需要和 wx:for 写在同一个组件上
在重命名修改后,需要使用新的变量名
-->
<!-- 数组 -->
<view wx:for="{{ fruitList }}" wx:key="id" wx:for-item="fruitItem" wx:for-index="i">
{{fruitItem.name}}
</view>
<!-- 对象 -->
<view wx:for="{{ obj }}" wx:key="index" wx:for-item="value" wx:for-index="key">
{{value}} - {{key}}
</view>
<view class="line"></view>
<!-- <block/>并不是一个组件,只是包装元素,可组织代码结构,支持列表渲染 -->
<block wx:for="{{ fruitList }}" wx:key="id" wx:for-item="fruitItem" wx:for-index="i">
<view>名字:{{fruitItem.name}}</view>
<view>价格:{{fruitItem.price}}</view>
</block>
js文件代码示例:
data: {
numList:[1, 2, 3],
fruitList:[
{id: 1, name:'🍎', price: 10},
{id: 2, name:'🍋', price: 20},
{id: 3, name:'🍌', price: 30}
],
obj:{
name: "Lida",
age: "30"
}
}
七、条件渲染
1、条件渲染主要是用来控制页面结构的展示与隐藏,有两种方式可实现:
1.1、使用 wx:if、wx:elif、wx:else 属性值
1.2、使用 hidden 属性
2、 wx:if 和 hidden 两者的区别:
2.1、wx:if:当条件为true时将结构展示出来,否则不会展示,通过移除/新增节点的方式来实现
2.2、hidden:当条件为true时将结构隐藏起来,否则结构会展示,通过 css 的 display 样式属性来实现的
3、注意事项:
3.1、wx:elif、wx:else 不能单独使用,在使用时必须结合 wx:if 来使用
3.2、使用了 wx:if 属性组的组件不能被打断,组件必须连贯才可以
wxml文件代码示例:
<!--
wx:if 属性组:wx:if、wx:elif、wx:else
只有对应的条件成立,属性所在的组件才会进行展示
-->
<view wx:if="{{ num === 1 }}">num 等于 {{num}}</view>
<view wx:elif="{{ num === 2 }}">num 等于 {{num}}</view>
<view wx:else>num 大于 2,目前 num 等于 {{num}}</view>
<button type="warn" bind:tap="updateNum">更新 num</button>
<!-- hidden 属性值若是 true,就会隐藏结构,若是 false,才会展示结构 -->
<view hidden="{{ !isFlag }}">若 isFlag 是 true 展示结构,否则隐藏结构</view>
js文件代码示例:
data: {
num: 1,
isFlag: true
}