【小程序】数据绑定
小程序的脚本逻辑运行在 JSCore
中,JSCore
是没有 DOM
的环境,它完全抛弃了 DOM
结构。因此小程序中数据填充到页面的方法,不能像传统HTML开发那样,先获取DOM,然后赋值给标签。
为了解决这个问题,小程序借鉴了很多流行框架都有的数据绑定思想;同时出于性能考虑,只实现了单向数据绑定
,即只支持从逻辑层传递到 UI 层的数据绑定。
在实现上,小程序采用页面 js 文件
中 Page 方法
参数里的 data 变量
作为数据绑定的桥梁,以Mustache
语法的双大括号{{}}
在UI层实现数据绑定,MINA框架会自动在运行时用 data 中的对应数据去替换这些{{}}
。
此外,数据绑定的形式有两种:
- 初始化数据绑定
- 数据绑定更新
接下来就这两种形式分别做简单的介绍。
初始化数据绑定
这种形式是指直接将数据写在 data
对象下面,在 wxml
布局中就可以通过 {{}}
进行绑定了。比如在 【小程序】image组件的13种模式 中的栗子:
/// .js 文件
/**
* 页面的初始数据
*/
data: {
image: "https://developers.weixin.qq.com/miniprogram/dev/image/cat/0.jpg"
},
/// .wxml 文件
<view>
<image mode="top left" src="{{image}}" />
<image mode="top" src="{{image}}" />
<image mode="top right" src="{{image}}" />
</view>
结合 页面生命周期,数据初始化绑定的具体过程是这样的:
当页面执行了 onShow 函数后,逻辑层会收到一个 Notify;随后逻辑层将data对象以json形式发送到 View 层,View层接到初始化数据后,开始渲染并显示初始化数据(onReady),最终将数据显示UI上。
数据绑定更新
这种形式是指利用 Page对象原型链
上的 setData
(Page.prototype.setData
)方法,达到动态修改 data
对象中的数据,重新渲染显示在 UI 上的目的。
setData
方法接受一个对象,以 key-value
的形式将 this.data
中的 key
对应的值设置为 value
。setData
执行后会通知逻辑层执行重新渲染,并立刻渲染 UI,显示更新的数据。
举个栗子
要演示这个效果,只需要接着前面的代码在 onLoad 中加入如下代码即可:
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
image:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542608065938&di=1925a3cf037576732b77b84507b47185&imgtype=0&src=http%3A%2F%2Fpic.58pic.com%2F58pic%2F14%2F81%2F12%2F33F58PICMYR_1024.jpg"
});
},
此时再次运行,将会显示新的图片。
绑定复杂对象
上面栗子中,data 对象只有一个 string 对象,结构很简单,但实际开发中往往都会很复杂,比如这样:
/**
* 页面的初始数据
*/
data: {
image: "https://developers.weixin.qq.com/miniprogram/dev/image/cat/0.jpg",
user: {
avatar: "https://developers.weixin.qq.com/miniprogram/dev/image/cat/0.jpg",
name: "Shawn",
age: "18",
hobby: [
"吃饭",
"睡觉",
"打豆豆"
],
},
},
此时,wxml 中绑定组件就需要这样写:
<view>
<image src="{{user.avatar}}"/>
<text>{{user.name}}</text>
<text>{{user.hobby[0]}}</text>
</view>
若需要通过 setData 动态更新数据,就要这么写:
this.setData({
"user.name": "I'm Shawn",
"user.hobby[0]": "吃饭吃饭吃饭",
});
注意事项
-
{{}}
中的变量名一定要与data
中的变量名一致,运行时才能被正确的替换。 - 数据绑定出现异常时,开发工具和运行环境都不会提示错误,需要开发者自查。
-
setData
是Page 原型链
上的函数,需要通过this.setData
调用,否则不能正常使用。 - 在使用
setData
时,若data
中已有这个key
,则修改该key
的value
;若data
中没有这个key
,则新加一组key-value
。 - 直接修改
this.data
而不调用this.setData
是无法改变页面的状态的,还会造成数据不一致。 -
setData
仅支持设置可JSON
化的数据。 -
setData
单次设置的数据不能超过1024kB
,请尽量避免一次设置过多的数据。 - 请不要把
data
中任何一项的value
设为undefined
,否则这一项将不被设置并可能遗留一些潜在问题。