微信小程序中 setData 详解

article/2025/8/27 5:18:34

虽互不曾谋面,但希望能和您成为笔尖下的朋友

以读书,技术,生活为主,偶尔撒点鸡汤

不作,不敷衍,意在真诚吐露,用心分享

点击左上方,可关注本刊

标星公众号(ID:itclanCoder

如果不知道如何操作

点击这里,标星不迷路

━━━━━━

━━━━━━

我希望您保持空杯

一边阅读一边思考

更重要是要动手敲

如果有收获三连击

作者 | 随笔川迹

ID | suibichuanji

前言

撰文:川川

在小程序中各个页面之间是相互独立的,一个页面分为渲染层(视图层 webview),逻辑层(JavaScript),系统层(底层)

在架构上,WebViewJavascriptCore 都是独立的模块,并不具备数据直接共享的通道

换而言之,若要将逻辑层中的data的数据渲染到页面中,他们之间是无法直接通信的,往往需要系统层作为中间角色

我们都知道视图层的数据来源于逻辑层 data,而视图图层若想要改变逻辑层 data 的数据,需要借助setData这个方法去触发,以达到更新视图层的数据,具体的工作过程是怎么样的?

·  正  ·  文  ·  来  ·  啦  ·

01

setData是什么?

定义: 设置数据,更改数据

作用: setData函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data的值(同步)

仔细细品这句话,会包含了很多信息

  • setData它是微信小程序提供的一个内置的接口,是用于改变逻辑层中 data下的数据的

  • 视图层 view的数据挂载在逻辑层的 data下,发送到视图层中是异步的

  • 改变 this.data是同步,换句话说,若直接修改 this.data 而不调用 this.setData方法,是无法改变页面的状态的,还会造成数据不一致

从上面的这张图中就可以看到,当逻辑层data数据渲染到界面的时候,逻辑层的数据需要经过系统层,当系统层接收到这个逻辑层的数据后

系统层在把数据转发给渲染层,然后在渲染层展示出来,在这个过程当中是异步的 

视图层和逻辑层的数据传输,实际上通过两边提供的 JavScript Core所实现,即用户传输的数据,需要将其转换为字符串形式传递

同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立的环境

02

setData两个重要的参数

从官方文档中看到这句Page.prototype.setData(Object data, Function callback),得知,setData方法是挂载当前页面实例Page原型下一个公用实例方法

也就是说,Page 下面的任何一个方法内,都可以使用 setData 方法,它接收两个参数

  • 一个是Object data,第一个参数Object data是必传的,数据类型是Object,所代表的含义是,这次要改变的数据

  • 而第二个参数Function callback回调函数是非必填的,它所代表的含义是,setData引起的界面更新渲染完毕后的回调函数

为了便于理解,在小程序中创建一个 page 页面,名为setdata,如下是逻辑层 js 文件

// miniprogram/pages/setdata/setdata.js
Page({/*** 页面的初始数据*/data: {name: "itclanCoder"},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {}
})

而 wxml 文件如下

<!--miniprogram/pages/setdata/setdata.wxml-->
<text>{{name}}</text>

在Web 开发中,开发者使用JavaScript通过Dom接口来完成界面的实时更新。而在小程序中,使用WXML语言所提供的数据绑定功能,来完成此项功能

在小程序中是没有DOM,BOM的那一套东西的,没有document.getElementById等的

小程序是数据驱动视图的,逻辑层中的 data 数据改变了,视图层 view 也会跟着改变,它是单向数据流的,如果想要触发视图中数据的更新,那么就需要借助setData这个方法

上面的WXML通过{{变量名}}来绑定 WXML文件和对应的JavaScript文件中的data对象属性

在上面的示例中,页面会显示itclanCoder,那如何更改逻辑层的数据呢

在下面的示例中,演示了如何更改逻辑层的数据,在 wxml 中新增了一个按钮,用bindtap绑定了一个handleChangeName方法,触发按钮,改变 data 下的数据

<!--miniprogram/pages/setdata/setdata.wxml-->
<text>{{name}}</text>
<button type="primary" bindtap="handleChangeName">更改data中数据</button>

而在逻辑层 JS

// miniprogram/pages/setdata/setdata.js
Page({/*** 页面的初始数据*/data: {name: "itclanCoder"},// 改变data的方法handleChangeName() {console.log("name开始的数据", this.data.name); // itclanCoderthis.setData({name: "川川"})console.log("name经过setData后的数据", this.data.name); // 川川}})

在上面的示例代码中,更改data下面的name字段值,使用的是setData方法,这个方法接收了一个参数,第一个参数是对象,这个Object 以 key: value 的形式表示,将 this.data中的 key对应的值改变成 value

注意

这个key可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].message,a.b.c.d,并且不需要在 this.data中预先定义,但凡是页面要显示的变量数据,最好先挂载在data下初始化定义,然后在使用

也就是说在更改setData下的变量时,直接写key名就可以了的,不用写this.data.属性,如下所示

this.setData({// this.data.name: "川川" // 这样写是会报错的name: "川川"               // 正确的写法
})

而setData接收第二个参数,是一个Function callback

handleChangeName() {console.log("name开始的数据", this.data.name); // itclanCoderthis.setData({name: "川川"}, () => { // 接收第二个回调函数console.log("执行setData引起的界面更新渲染完毕后的回调函数");})console.log("name经过setData后的数据", this.data.name); // 川川}

上面代码的执行顺序是

itclancoder
川川
执行setData引起的界面更新渲染完毕后的回调函数

此结果说明这个setData方法是异步的,等待主线程任务做完了,然后在去执行第二个参数,回调异步函数

03

如何更改某个对象下的属性

有时候,我们的接口数据类型是对象,并非是基本数据类型(number,boolean,string,null),但由于业务需求,我们往往需要改变对象下的某个属性

如下所示,我想改变person下的 age 属性值

// miniprogram/pages/setdata/setdata.js
Page({/*** 页面的初始数据*/data: {person: {name: "随笔川迹",sex: "男神",age: 20}},handleChangeName() {this.setData({person: {age: 24}})}
})

在上面的代码中,的确可以更改person对象下的age属性,但是随之带来的问题是,person对象下除了age属性,其他属性都消失了

这非常令人郁闷

那如何解决这个问题?

  • 方法 1: 指明具体的修改对象属性

this.setData({"person.age": 24  // 注意要用双引号或单引号将属性给引起来
})
  • 方法 2:使用中扩号['对象.属性']:属性值

this.setData({['person.age']: "川川"   // 访问对象下的属性可以用.也可以用中括号,中间代表是一个变量,需要用引号引起来
})

如下所示

这个在以后的开发中,很有用,有时候,在需要更改对象下的某个属性值的时候,就可以使用这种方式

04

setData注意事项

  • 直接修改 this.data,而不调用this.setData是无法改变页面的状态的,还会造成数据不一致

  • 仅支持设置可JSON化的数据,如果不是 JSON 对象数据格式,需要将数据进行转化成json对象`,key:value形式

  • 单次设置的数据不能超过1024kB(1M),不要一次设置过多的数据(由于小程序运行逻辑线程与渲染线程之上,setData的调用会把数据从逻辑层传到渲染层,数据太大会增加通信时间,会增加脚本的编译执行时间,占用 WebView JS 线程,)

  • 不要把 data中任何一项的value设为undefined,否则这一项将不被设置并可能遗留一些潜在问题

  • 页面中需要显示的数据,可以挂载在data下面初始化,虽然这个值不一定要先设置,但是建议先声明然后在使用

  • 避免setData的调用过于频繁(setData接口的调用涉及逻辑层与渲染层间的线程通信,通信过于频繁可能导致处理队列阻塞,界面渲染不及时而导致卡顿,应避免无用的频繁调用)

  • 在Android下用户在滑动时会感觉到卡顿,操作反馈延迟严重,因为JS线程一直在编译执行渲染,未能及时将用户操作事件传递到逻辑层,逻辑层亦无法及时将操作处理结果及时传递到视图层

  • 渲染有出现延时,由于WebView的 JS 线程一直处于忙碌状态,所以,逻辑层到页面层的通信耗时上升,视图层收到的数据消息时距离发出时间已经过去了几百毫秒,渲染的结果并不是实时的

  • 避免 setData 数据冗余(setData操作会引起框架处理一些渲染界面相关的工作,避免将未绑定在 WXML 的变量传入setData,减少不必要的性能消耗)

  • 后台态页面进行setData(比如退出小程序),当页面进入后台态(用户不可见),不应该继续去进行 setData,后台态页面的渲染用户是无法感受到的,另外后台态页面去 setData 也会抢占前台页面的执行

结语

在本文中主要介绍了下setData的使用,它是用于修改挂载在 data 下面的数据的,当想要修改视图 view,那么需要借助 setData 函数,它接收两个参数,第一个参数时必传的,也就是要修改视图 view 层的对象,而第二个参数时非必传的

setData 将数据从逻辑层发送到视图层是异步,同时改变对应的this.data的值是同步,它并不是实时的,这也导致了必须要考虑性能的因素

从而介绍了 setData 的使用注意事项,值得注意的是,如何修改对象下的某个属性,这个在往后的开发中,是使用比较频繁的.

如果小伙伴们有问题,欢迎大家下面留言,一起学习讨论

这个世界很酷

遇见您本就是命中注定

知交零落已是人生常态

能够偶尔话起

而心中仍然温柔

便是好朋友

我希望您就是我的那个朋友

终日守候

看我码字,听我读书

坚持给川川点赞

 愿少年您

不畏风雨,砥砺"潜"行

  听川川,荡气回肠  

看川川,码中怀孕

读川川,浮想联翩

写川川,镂骨铭心

公众号(ID:itclanCoder)

码能让您早脱菜籍,文能让您洗净铅华

  可能您还想看更多:

  • 小程序-云开发-多图片内容安全检测

小程序-云开发-多图片内容安全检测

  • 小程序-云开发-如何切换开发(测试)坏境与生产坏境

小程序-云开发-如何切换开发(测试)坏境与生产坏境

  • 小程序-云开发-如何对敏感词进行过滤即内容安全的检测(下)

小程序-云开发-如何对敏感词进行过滤即内容安全的检测(下)

- End -

在看点一下 大家都知道


http://chatgpt.dhexx.cn/article/r0Fim3DF.shtml

相关文章

微信小程序————setData()方法的使用和注意事项

微信小程序setData()使用&#xff1a; ##Page.prototype.setData(Object data, Function callback) setData 函数用于将数据从逻辑层发送到视图层&#xff08;异步&#xff09;&#xff0c;同时改变对应的 this.data 的值&#xff08;同步&#xff09;。 参数说明&#xff1a; …

微信小程序setData注意事项,使用方法

1..微信小程序开发中&#xff0c;为了减少data和视图层数据表现不一致&#xff0c;全部采用setData方法修改值。 setData函数注意事项 1..直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的&#xff0c;还会造成数据不一致。 2..单次设罟的数据不能超过1024kB&…

layui自定义table中的templet

1.效果图如下 2.后端返回数据如下 3.实现代码如下 {field: "triggerPara",title: "触发参数",templet: function (d) {let text"" , type;for(let i 0 ; i < d.triggerPara.length ; i ){if(d.triggerPara[i].type 0){type 门禁}else i…

layui table 更新行触发templet重新渲染

更新方法 obj.update({// 这里的字段必须要在 table.render.cols.filed 有定义&#xff0c;否则无法触发表格渲染// key 决定是否重新渲染某一列&#xff0c;value 由 templet 里的语句进行逻辑处理canView: !data.canView }); , {field: canView, title: 操作, toolbar: #te…

layui2.4.5版本解决table使用templet导出数据问题

在使用 table 自带的导出功能时对使用了templet的数据导出为空 使用较高的版本可以解决此类问题&#xff1a;https://gitee.com/layui/layui/issues/I40UJ9 但是此文章中的项目比较老以及页面功能都比较多升级layui版本可能会影响比较大&#xff0c;所以就对layui源码进行微调…

layui表格使用自定义模板templet

前言 在前文 layuispringboot实现表格增删改查 中&#xff0c;我们展示了如何使用layui将数据库数据渲染到前端表格中&#xff0c;但现在问题来了&#xff0c;如果不加特殊处理&#xff0c;前端表格直接显示数据库存储信息是不合适的&#xff0c;例如数据库有一个类型字段&…

layui 动态表格 templet模板函数

1&#xff0c;需求说明 关于动态标题栏的相关知识跳转链接&#xff1a;layui 静态 动态复杂多表头 2&#xff0c;尝试的用法 var chenbenkemuList${chenbenkemuList};var columnAry[]for (var i 0; i < chenbenkemuList.length; i) {var onechenbenkemu chenbenkemuList[…

layui:templet

在使用layui-table的时候,由于它每次都是动态刷新,无法保存我们做的一些页面上元素的修改。 我希望我设置完默认地址之后,下次访问应该是和这次一样变成了灰色的。 这个时候要用到templet,官方文档中的{{d}}就是table获取回来的data,直接做判断,设置样式即可! <

LayUi 之 templet

templet是什么东西&#xff1f; 我们都知道LayUi中有模板&#xff0c;就是把我们需要展示的东西放在模板中展示&#xff0c;你就比如我们想要展示一些数据&#xff0c;但是这些数据不是我们想要的数据或者不是我们想要的样子&#xff0c;这个时候我们可以通过模板前端更改一下…

Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释

一、线程5种状态 1.新建状态&#xff08;New&#xff09; 新创建了一个线程对象。 2.就绪状态&#xff08;Runnable&#xff09; 线程对象创建后&#xff0c;其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中&#xff0c;变得可运行&#xff0c;等待获取C…

java线程状态(六种五种)

java线程的状态常见的有两种说法&#xff0c;一种是将其分为6种一种是分为5种 1. 六种&#xff1a; 划分依据&#xff1a;主要是从java代码的角度来进行划分。 1. 新建状态 &#xff1a; 使用new关键字创建一个thread对象&#xff0c;刚刚创建出的这个线程就处于新建状态。在…

统计Java进程中的线程状态(jstack+linux)

统计Java进程中的线程状态 第一步&#xff1a;查看Java进程ID 第二步&#xff1a;使用jstack命令dump线程信息&#xff0c;看看pid45890进程中的线程都是什么状态 /usr/local/java/jdk1.8.0_144/bin/jstack 84976 >/opt/test.dump第三步&#xff1a;统计所有线程分别处于什…

线程状态图

1. 新建状态(New) : 线程对象被创建后&#xff0c;就进入了新建状态。例如&#xff0c;Thread thread new Thread()。 2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后&#xff0c;其它线程调用了该对象的start()方法&#xff0c;从而来启动该线程…

Java 线程状态之 TIMED_WAITING

定义 一个正在限时等待另一个线程执行一个动作的线程处于这一状态。 A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. 更详细的定义还是看 javadoc&#xff08;jdk8&#xff09;&#xff1a; 带指定…

jstack 线程状态

转自 http://www.cnblogs.com/nexiyi/p/java_thread_jstack.html jstack 线程状态 jstack 线程里&#xff0c;值得关注的线程状态有&#xff1a; 死锁&#xff0c;Deadlock&#xff08;重点关注&#xff09; 执行中&#xff0c;Runnable 等待资源&#xff0c;Waiting on co…

Java 中线程状态有哪些?

写在前面 本文隶属于专栏《100个问题搞定Java并发》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和文献引用请见100个问题搞定Java并发 解答 线程的状态在java中有明确…

理解Java线程状态(6种,6种,6种)

什么是线程 线程具有许多传统进程所具有的特征&#xff0c;故又称为轻型进程(Light—Weight Process)或进程元&#xff1b;而把传统的进程称为重型进程(Heavy—Weight Process)&#xff0c;它相当于只有一个线程的任务。在引入了线程的操作系统中&#xff0c;通常一个进程都有…

图文详解jvm中的线程状态

本文使用下面这张图详细介绍JAVA线程的六种状态 JAVA线程的六种状态详解 在java.lang.Thread类中&#xff0c;定义了线程的以下六种状态(同一个时刻线程只能有一种状态) NEW&#xff08;新建&#xff09; 这个状态是指线程刚创建&#xff0c;但还未调用线程的start()方法进…

python封装线程类(启动、终止、查看线程状态)

文章目录 一、简单说明二、实现步骤三、测试 一、简单说明 将启动、终止和查看线程状态的方法封装成类声明时传入要启动的方法通过 start、stop 和 state 执行启动、终止 和 查看状态 二、实现步骤 # encoding: utf-8import time import threading import inspect import ct…