知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
您當(dāng)前位置>首頁(yè) » 新聞資訊 » 小程序相關(guān) >
微信小程序中 setData 詳解
發(fā)表時(shí)間:2021-1-5
發(fā)布人:葵宇科技
瀏覽次數(shù):139
在小程序中各個(gè)頁(yè)面之間是相互獨(dú)立的,一個(gè)頁(yè)面分為渲染層(視圖層 webview),邏輯層(JavaScript),系統(tǒng)層(底層),在架構(gòu)上,WebView
和 JavascriptCore
都是獨(dú)立的模塊,并不具備數(shù)據(jù)直接共享的通道,換而言之,若要將邏輯層中的data
的數(shù)據(jù)渲染到頁(yè)面中,他們之間是無(wú)法直接通信的,往往需要系統(tǒng)層作為中間角色
我們都知道視圖層的數(shù)據(jù)來(lái)源于邏輯層 data,而視圖圖層若想要改變邏輯層 data 的數(shù)據(jù),需要借助setData
這個(gè)方法去觸發(fā),以達(dá)到更新視圖層的數(shù)據(jù),具體的工作過(guò)程是怎么樣的?
定義: 設(shè)置數(shù)據(jù),更改數(shù)據(jù)
作用: setData
函數(shù)用于將數(shù)據(jù)從邏輯層發(fā)送到視圖層(異步),同時(shí)改變對(duì)應(yīng)的this.data
的值(同步)
仔細(xì)細(xì)品這句話,會(huì)包含了很多信息
setData
它是微信小程序提供的一個(gè)內(nèi)置的接口,是用于改變邏輯層中data
下的數(shù)據(jù)的- 視圖層
view
的數(shù)據(jù)掛載在邏輯層的data
下,發(fā)送到視圖層中是異步的 - 改變
this.data
是同步,換句話說(shuō),若直接修改this.data
而不調(diào)用this.setData
方法,是無(wú)法改變頁(yè)面的狀態(tài)的,還會(huì)造成數(shù)據(jù)不一致
系統(tǒng)層在把數(shù)據(jù)轉(zhuǎn)發(fā)給渲染層,然后在渲染層展示出來(lái),在這個(gè)過(guò)程當(dāng)中是異步的
視圖層和邏輯層的數(shù)據(jù)傳輸,實(shí)際上通過(guò)兩邊提供的JavScript Core
所實(shí)現(xiàn),即用戶傳輸?shù)臄?shù)據(jù),需要將其轉(zhuǎn)換為字符串形式傳遞,同時(shí)把轉(zhuǎn)換后的數(shù)據(jù)內(nèi)容拼接成一份 JS 腳本,再通過(guò)執(zhí)行 JS 腳本的形式傳遞到兩邊獨(dú)立的環(huán)境
從官方文檔中看到這句Page.prototype.setData(Object data, Function callback)
,得知,setData
方法是掛載當(dāng)前頁(yè)面實(shí)例Page
原型下一個(gè)公用實(shí)例方法
也就是說(shuō),Page 下面的任何一個(gè)方法內(nèi),都可以使用 setData 方法,它接收兩個(gè)參數(shù)
- 一個(gè)是
Object data
,第一個(gè)參數(shù)Object data
是必傳的,數(shù)據(jù)類型是Object
,所代表的含義是,這次要改變的數(shù)據(jù) - 而第二個(gè)參數(shù)
Function callback
回調(diào)函數(shù)是非必填的,它所代表的含義是,setData
引起的界面更新渲染完畢后的回調(diào)函數(shù)
為了便于理解,在小程序中創(chuàng)建一個(gè) page 頁(yè)面,名為setdata
,如下是邏輯層 js 文件
點(diǎn)擊即可查看文
而 wxml 文件如下
點(diǎn)擊即可查看
在Web
開發(fā)中,開發(fā)者使用 JavaScript
通過(guò)Dom
接口來(lái)完成界面的實(shí)時(shí)更新。而在小程序中,使用 WXML
語(yǔ)言所提供的數(shù)據(jù)綁定功能,來(lái)完成此項(xiàng)功能,在小程序中是沒有DOM
,BOM
的那一套東西的,沒有document.getElementById
等的
小程序是數(shù)據(jù)驅(qū)動(dòng)視圖的,邏輯層中的 data 數(shù)據(jù)改變了,視圖層 view 也會(huì)跟著改變,它是單向數(shù)據(jù)流的,如果想要觸發(fā)視圖中數(shù)據(jù)的更新,那么就需要借助setData
這個(gè)方法
上面的WXML
通過(guò)插值表達(dá)式來(lái)綁定 WXML
文件和對(duì)應(yīng)的JavaScript
文件中的data
對(duì)象屬性
在上面的示例中,頁(yè)面會(huì)顯示itclanCoder
,那如何更改邏輯層的數(shù)據(jù)呢
在下面的示例中,演示了如何更改邏輯層的數(shù)據(jù),在 wxml 中新增了一個(gè)按鈕,用bindtap
綁定了一個(gè)handleChangeName
方法,觸發(fā)按鈕,改變 data 下的數(shù)據(jù)
<!--miniprogram/pages/setdata/setdata.wxml-->
<text>{{name}}</text>
<button type="primary" bindtap="handleChangeName">更改data中數(shù)據(jù)</button>
而在邏輯層 JS
// miniprogram/pages/setdata/setdata.js
Page({
/**
* 頁(yè)面的初始數(shù)據(jù)
*/
data: {
name: "itclanCoder"
},
// 改變data的方法
handleChangeName() {
console.log("name開始的數(shù)據(jù)", this.data.name); // itclanCoder
this.setData({
name: "川川"
})
console.log("name經(jīng)過(guò)setData后的數(shù)據(jù)", this.data.name); // 川川
}
})
在上面的示例代碼中,更改data
下面的name
字段值,使用的是setData
方法,這個(gè)方法接收了一個(gè)參數(shù),第一個(gè)參數(shù)是對(duì)象,這個(gè)Object
以 key: value
的形式表示,將 this.data
中的 key
對(duì)應(yīng)的值改變成 value
注意
這個(gè)key
可以以數(shù)據(jù)路徑的形式給出,支持改變數(shù)組中的某一項(xiàng)或?qū)ο蟮哪硞€(gè)屬性,如 array[2].message,a.b.c.d,并且不需要在 this.data
中預(yù)先定義,但凡是頁(yè)面要顯示的變量數(shù)據(jù),最好先掛載在data
下初始化定義,然后在使用
也就是說(shuō)在更改setData
下的變量時(shí),直接寫key
名就可以了的,不用寫this.data.屬性
,如下所示
this.setData({
// this.data.name: "川川" // 這樣寫是會(huì)報(bào)錯(cuò)的
name: "川川" // 正確的寫法
})
而setData
接收第二個(gè)參數(shù),是一個(gè)Function callback
handleChangeName() {
console.log("name開始的數(shù)據(jù)", this.data.name); // itclanCoder
this.setData({
name: "川川"
}, () => { // 接收第二個(gè)回調(diào)函數(shù)
console.log("執(zhí)行setData引起的界面更新渲染完畢后的回調(diào)函數(shù)");
})
console.log("name經(jīng)過(guò)setData后的數(shù)據(jù)", this.data.name); // 川川
}
上面代碼的執(zhí)行順序是
itclancoder
川川
執(zhí)行setData引起的界面更新渲染完畢后的回調(diào)函數(shù)
此結(jié)果說(shuō)明這個(gè)setData
方法是異步的,等待主線程任務(wù)做完了,然后在去執(zhí)行第二個(gè)參數(shù),回調(diào)異步函數(shù)
有時(shí)候,我們的接口數(shù)據(jù)類型是對(duì)象,并非是基本數(shù)據(jù)類型(number,boolean,string,null),但由于業(yè)務(wù)需求,我們往往需要改變對(duì)象下的某個(gè)屬性
如下所示,我想改變person
下的 age 屬性值
// miniprogram/pages/setdata/setdata.js
Page({
/**
* 頁(yè)面的初始數(shù)據(jù)
*/
data: {
person: {
name: "隨筆川跡",
sex: "男神",
age: 20
}
},
handleChangeName() {
this.setData({
person: {
age: 24
}
})
}
})
在上面的代碼中,的確可以更改person
對(duì)象下的age
屬性,但是隨之帶來(lái)的問(wèn)題是,person
對(duì)象下除了age
屬性,其他屬性都消失了
這非常令人郁悶

那如何解決這個(gè)問(wèn)題?
原因:
對(duì)象是一個(gè)引用數(shù)據(jù)類型,上面那種方式,是把我們當(dāng)前的值指向了一個(gè)新的對(duì)象
這樣,就相當(dāng)于現(xiàn)在的對(duì)象把之前的對(duì)象的值給覆蓋掉了的,所以只看到age
屬性值,其他屬性值給覆蓋掉了的,這是一個(gè)非常蛋疼的問(wèn)題,
解決方式如下
- 方法 1: 指明具體的修改對(duì)象屬性
this.setData({
"person.age": 24 // 注意要用雙引號(hào)或單引號(hào)將屬性給引起來(lái)
})
- 方法 2:使用中擴(kuò)號(hào)
['對(duì)象.屬性']:屬性值
this.setData({
['person.age']: "川川" // 訪問(wèn)對(duì)象下的屬性可以用.也可以用中括號(hào),中間代表是一個(gè)變量,需要用引號(hào)引起來(lái)
})
如下所示

- 直接修改
this.data
而不調(diào)用this.setData
是無(wú)法改變頁(yè)面的狀態(tài)的,還會(huì)造成數(shù)據(jù)不一致 - 僅支持設(shè)置可
JSON
化的數(shù)據(jù),如果不是 JSON 對(duì)象數(shù)據(jù)格式,需要將數(shù)據(jù)進(jìn)行轉(zhuǎn)化成json對(duì)象
,key:value
形式 - 單次設(shè)置的數(shù)據(jù)不能超過(guò)
1024kB
(1M),不要一次設(shè)置過(guò)多的數(shù)據(jù)(由于小程序運(yùn)行邏輯線程與渲染線程之上,setData
的調(diào)用會(huì)把數(shù)據(jù)從邏輯層傳到渲染層,數(shù)據(jù)太大會(huì)增加通信時(shí)間,會(huì)增加腳本的編譯執(zhí)行時(shí)間,占用WebView JS
線程,) - 不要把
data
中任何一項(xiàng)的value
設(shè)為undefined
,否則這一項(xiàng)將不被設(shè)置并可能遺留一些潛在問(wèn)題 - 頁(yè)面中需要顯示的數(shù)據(jù),可以掛載在
data
下面初始化,雖然這個(gè)值不一定要先設(shè)置,但是建議先聲明然后在使用 - 避免
setData
的調(diào)用過(guò)于頻繁(setData接口
的調(diào)用涉及邏輯層與渲染層間的線程通信,通信過(guò)于頻繁可能導(dǎo)致處理隊(duì)列阻塞,界面渲染不及時(shí)而導(dǎo)致卡頓,應(yīng)避免無(wú)用的頻繁調(diào)用)- 在
Android
下用戶在滑動(dòng)時(shí)會(huì)感覺到卡頓,操作反饋延遲嚴(yán)重,因?yàn)?code>JS 線程一直在編譯執(zhí)行渲染,未能及時(shí)將用戶操作事件傳遞到邏輯層,邏輯層亦無(wú)法及時(shí)將操作處理結(jié)果及時(shí)傳遞到視圖層 - 渲染有出現(xiàn)延時(shí),由于
WebView
的 JS 線程一直處于忙碌狀態(tài),所以,邏輯層到頁(yè)面層的通信耗時(shí)上升,視圖層收到的數(shù)據(jù)消息時(shí)距離發(fā)出時(shí)間已經(jīng)過(guò)去了幾百毫秒,渲染的結(jié)果并不是實(shí)時(shí)的
- 在
- 避免 setData 數(shù)據(jù)冗余(
setData
操作會(huì)引起框架處理一些渲染界面相關(guān)的工作,避免將未綁定在 WXML 的變量傳入setData
,減少不必要的性能消耗) - 后臺(tái)態(tài)頁(yè)面進(jìn)行
setData
(比如退出小程序),當(dāng)頁(yè)面進(jìn)入后臺(tái)態(tài)(用戶不可見),不應(yīng)該繼續(xù)去進(jìn)行setData
,后臺(tái)態(tài)頁(yè)面的渲染用戶是無(wú)法感受到的,另外后臺(tái)態(tài)頁(yè)面去setData
也會(huì)搶占前臺(tái)頁(yè)面的執(zhí)行
在本文中主要介紹了下setData
的使用,它是用于修改掛載在 data 下面的數(shù)據(jù)的,當(dāng)想要修改視圖 view,那么需要借助 setData 函數(shù),它接收兩個(gè)參數(shù),第一個(gè)參數(shù)時(shí)必傳的,也就是要修改視圖 view 層的對(duì)象,而第二個(gè)參數(shù)時(shí)非必傳的
setData 將數(shù)據(jù)從邏輯層發(fā)送到視圖層是異步,同時(shí)改變對(duì)應(yīng)的this.data
的值是同步,它并不是實(shí)時(shí)的,這也導(dǎo)致了必須要考慮性能的因素。從而介紹了 setData 的使用注意事項(xiàng),值得注意的是,如何修改對(duì)象下的某個(gè)屬性,這個(gè)在往后的開發(fā)中,是使用比較頻繁的.
相關(guān)案例查看更多
相關(guān)閱讀
- 網(wǎng)站建設(shè)首頁(yè)
- 云南網(wǎng)站建設(shè)公司排名
- 云南科技公司
- 政府網(wǎng)站建設(shè)服務(wù)
- 昆明小程序開發(fā)
- 文山小程序開發(fā)
- 昆明小程序公司
- 網(wǎng)站建設(shè)哪家強(qiáng)
- 小程序定制
- 網(wǎng)站建設(shè)方案 doc
- 做網(wǎng)站
- 網(wǎng)站建設(shè)公司地址
- 網(wǎng)站建設(shè)招商
- 昆明小程序代建
- 網(wǎng)絡(luò)營(yíng)銷
- 微信分銷系統(tǒng)
- 網(wǎng)絡(luò)公司排名
- 網(wǎng)站建設(shè)報(bào)價(jià)
- 云南小程序開發(fā)課程
- 汽車報(bào)廢回收軟件
- 關(guān)鍵詞快速排名
- web前端
- 云南小程序開發(fā)公司哪家好
- 云南小程序設(shè)計(jì)
- 昆明做網(wǎng)站
- 開通微信小程序被騙
- 昆明軟件定制
- 云南網(wǎng)站設(shè)計(jì)
- 小程序表單
- 云南etc小程序