前言
在微信小程序中經常會使用到setData函數把變量渲染到視圖層,那么什么是setData呢?如何使用?注意事項有些什么?下面我們就來詳細了解一下!
正文
- setData是小程序開發中使用最頻繁的接口,也是最容易引發性能問題的接口。
- setData函數用于將數據從邏輯層渲染到視圖層(異步),同時改變對應的this.data的值(同步)。
實例1:簡單實現點擊修改變量值
<text>test:{{test}}</text>
<button bindtap="bindTest">點擊改變test值</button>
Page({
data: {
test: "我是測試變量"
},
bindTest: function () {
console.log("this.data.test:" + this.data.test);
this.setData({
test: "我是測試變量,我的值被改變了!"
})
console.log("this.data.test:" + this.data.test);
}
})
效果:
在這里插入圖片描述
實例解析:
- 代碼很容易理解,點擊按鈕test變量的值被改變了,通過setData函數渲染到了前端展示。
-
另外我在this.setDta前后分別打印出了this.data.test的值,看看最終打印結果:
在這里插入圖片描述
這里就說明了setData函數渲染到視圖層后,會同步修改this.data.test的值。
實例2:動態修改數組指定下標的某個參數值(類似購物車)
<block wx:for="{{test}}" wx:key="index">
<view data-index="{{index}}" bindtap="bindTest">{{item.txt}}</view>
</block>
Page({
data: {
test: [
{ txt: "我是1號" },
{ txt: "我是2號" },
{ txt: "我是3號" }
]
},
bindTest: function (e) {
// 被點擊的view
let index = e.currentTarget.dataset.index;
// 根據index找到test對應索引中對應要修改的參數
let revise = "test[" + index + "].txt";
this.setData({
[revise]: "呃,我被人給點了!!!"
})
}
})
效果
在這里插入圖片描述
實例解析:
- 其實這個就是根據index找到test對應索引中對應要修改的參數,然后進行修改并渲染到頁面上;
- 該功能購物車選中狀態、數量更改都可以使用到;
- 此方法比使用循環尋找更改然后再渲染,更方便、性能更好!
注意事項
1.如果Page對象的data中沒有定義該key,則setData自動創建;如有則修改data中原變量的值。
2.直接修改this.data,而不調用this.setData(),是無法改變當前頁面的狀態的,會導致數據不一致。
3.使用this.setData({})時,注意this指向問題。
4.僅支持可以JSON化的數據。
5.單次設置的數據不能超過1024KB,盡量避免一次設置過多的數據。
6.不要把data中的任何一項的value設為undefined,否則這一項將不能被設置,可能會有潛在的問題。
常見的setData操作錯誤(官方文檔)
1.頻繁的去setData
在我們分析過的一些案例里,部分小程序會非常頻繁(毫秒級)的去setData,其導致了兩個后果:
- Android 下用戶在滑動時會感覺到卡頓,操作反饋延遲嚴重,因為 JS 線程一直在編譯執行渲染,未能及時將用戶操作事件傳遞到邏輯層,邏輯層亦無法及時將操作處理結果及時傳遞到視圖層;
- 渲染有出現延時,由于 WebView 的 JS 線程一直處于忙碌狀態,邏輯層到頁面層的通信耗時上升,視圖層收到的數據消息時距離發出時間已經過去了幾百毫秒,渲染的結果并不實時;
2.每次setData都傳遞大量新數據
由setData的底層實現可知,我們的數據傳輸實際是一次evaluateJavascript腳本過程,當數據量過大時會增加腳本的編譯執行時間,占用WebView JS線程。
3.后臺態頁面進行setData
當頁面進入后臺態(用戶不可見),不應該繼續去進行setData,后臺態頁面的渲染用戶是無法感受的,另外后臺態頁面去setData也會搶占前臺頁面的執行。