setData 机制

解释:setData 函数用于将数据,从逻辑层发送到视图层,当开发者调用 setData 后,数据的变化会引起视图层的更新。
参数说明

属性类型默认值必填描述
dataObject这次要改变的数据
callbackFunctionsetData 引起的界面更新渲染完毕后的回调函数

说明

  • Object 以key: value的形式表示,将this.data中的key对应的值改变成value
    key可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如array[2].messagea.b.c.d,并且不需要在this.data中预先定义;
  • 直接修改this.data而不调用this.setData是无法改变页面的状态的,还会造成数据不一致;
  • 仅支持设置可 JSON 化的数据;
  • 请不要把data中任何一项的value设为undefined,否则将会有一些潜在问题出现;
  • data 的键名必须遵守 camelCase(驼峰式)的命名规范,不得使用 kebab-case(短横线隔开式)规范。

代码示例

在开发者工具中打开

在开发者工具中打开

在 WEB IDE 中打开

  • SWAN
  • JS
  1. <!-- index.swan -->
  2. <view>{{text}}</view>
  3. <button bindtap="changeText"> Change normal data </button>
  4. <view>{{num}}</view>
  5. <button bindtap="changeNum"> Change normal num </button>
  6. <view>{{arr[0].text}}</view>
  7. <button bindtap="changeItemInArr"> Change Arr data </button>
  8. <view>{{obj.text}}</view>
  9. <button bindtap="changeItemInObj"> Change Obj data </button>
  10. <view>{{newField.text}}</view>
  11. <button bindtap="addNewField"> Add new data </button>
  1. // index.js
  2. Page({
  3. data: {
  4. text: 'init data',
  5. num: 0,
  6. arr: [{text: 'init data'}],
  7. obj: {
  8. text: 'init data'
  9. }
  10. },
  11. changeText() {
  12. // 不要直接通过 this.data.text = 'changed data' 修改this.data,应该使用 setData
  13. this.setData({
  14. text: 'changed data'
  15. });
  16. },
  17. changeNum() {
  18. // 或者,可以修改 this.data 之后马上用 setData 设置一下修改了的字段
  19. this.data.num = 1
  20. this.setData({
  21. num: this.data.num
  22. });
  23. },
  24. changeItemInArr() {
  25. // 对于对象或数组字段,可以直接修改一个子字段,这样方式会有带来更好的性能
  26. this.setData({
  27. 'arr[0].text':'changed data'
  28. });
  29. },
  30. changeItemInObj(){
  31. this.setData({
  32. 'obj.text': 'changed data'
  33. });
  34. },
  35. addNewField() {
  36. this.setData({
  37. 'newField.text': 'new data'
  38. });
  39. }
  40. });

连续使用 setData 来改变界面的方法也可以达到动画的效果。这样可以任意地改变界面,但通常会产生较大的延迟或卡顿,甚至导致小程序僵死。此时可以通过将页面的 setData 改为自定义组件中的 setData 来提升性能。下面的例子是使用 setData 来实现秒表动画的示例。

代码示例

在开发者工具中打开

在开发者工具中打开

在 WEB IDE 中打开

  • SWAN
  • JS
  1. <view>
  2. <stopwatch id="stopwatch" class="stopwatch" />
  3. <button class="btn" s-if="{{!started}}" bindtap="start">开始计时</button>
  4. <button class="btn" s-if="{{started}}" bindtap="stop">停止计时</button>
  5. </view>
  1. const app = getApp()
  2. Page({
  3. data: {
  4. started: false
  5. },
  6. start: function() {
  7. this.setData({
  8. started: true
  9. })
  10. this.selectComponent('#stopwatch').start()
  11. },
  12. stop: function() {
  13. this.setData({
  14. started: false
  15. })
  16. this.selectComponent('#stopwatch').stop()
  17. }
  18. })
  19. // 自定义组件中js
  20. Component({
  21. data: {
  22. text: '00:00.000'
  23. },
  24. methods: {
  25. start: function() {
  26. var convertTimeStampToString = function(ts) {
  27. var ms = String(1000 + Math.floor(ts) % 1000).slice(1)
  28. var s = String(100 + Math.floor(ts / 1000) % 60).slice(1)
  29. var m = Math.floor(ts / 60000)
  30. if (m < 10) m = '0' + m
  31. return m + ':' + s + '.' + ms
  32. }
  33. this.setData({
  34. text: convertTimeStampToString(0)
  35. })
  36. var startTime = Date.now()
  37. var self = this
  38. this._interval = setInterval(function() {
  39. self.setData({
  40. text: convertTimeStampToString(Date.now() - startTime)
  41. })
  42. }, 33)
  43. },
  44. stop: function() {
  45. clearInterval(this._interval)
  46. }
  47. }
  48. })

逻辑层在设置数据后可执行函数。

代码示例

  • JS
  1. this.setData({
  2. text: 'Set some data for updating view.'
  3. }, function() {
  4. // this is setData callback
  5. })