先來感受一下程式碼,報錯報的簡直扎心。
Component({
/**
* 元件的屬性列表
*/
properties: {
index: {
//當這裡為number 時,拼串的0會被忽視,所以不可以為Number
type: String,
//當我們改變了index的值時,小程式主動來呼叫observer
//並傳遞三個值:新值、舊值、路徑
//observer裡
observer: function (newVal, oldVal, changedPath) {
let val = newVal<10 ? "0" + newVal : newVal
console.log(val)
this.setData({
index: val
})
}
}
},
/**
* 元件的初始資料
*/
data: {
year: "",
month: ""
},
attached: function(){
const months = {
0 : "一月",
1 : "二月",
2 : "三月",
3 : "四月",
4 : "五月",
5 : "六月",
6 : "七月",
7 : "八月",
8 : "九月",
9 : "十月",
10 : "十一月",
11 : "十二月",
}
let date = new Date
let year = (date.getFullYear()).toString()
let monthN = (date.getMonth()).toString()
let monthS = months[monthN]
this.setData({
year: year,
month: monthS
})
},
/**
* 元件的方法列表
*/
methods: {
}
})
複製程式碼
總結下原因:observer函式是在data發生改變時小程式主動呼叫的,在observer函式內setData時又再次改變了properties的值,observer函式再次呼叫,不停的迴圈……無限遞迴呼叫……於是記憶體耗盡。
那麼問題來了,為啥type為Number時不會發生記憶體洩漏?
本質上就是因為properties值根本沒變。當外部改變index值為A(假如),觸發observer函式時,函式內部將傳進來的值進行拼串後,由於值的型別設定為Number,拼串後的值0A會按照數字解析成A,所以進入函式內部後這個值繞了一圈還是沒變,所以不會無限遞迴呼叫observer.
解決辦法:
看到記憶體洩漏、遞迴這些字眼是不是就怕怕的?莫方(說給自己聽)。
既然observer內部改變properties內部資料會產生問題,那麼,我們們就不改變唄!曲線救國。在data裡設定一個變數_index,把拼串後的值給到_index就好啦!注意在wxml中也要把繫結的資料改為{{_index}}。完美~
程式碼如下:
// components/epsoide/index.js
Component({
/**
* 元件的屬性列表
*/
properties: {
index: {
//當這裡為number 時,拼串的0會被忽視,所以不可以為Number
type: String,
//當我們改變了index的值時,小程式主動來呼叫observer
//並傳遞三個值:新值、舊值、路徑
//observer裡
observer: function (newVal, oldVal, changedPath) {
let val = newVal<10 ? "0" + newVal : newVal
this.setData({
_index: val
})
}
}
},
/**
* 元件的初始資料
*/
data: {
year: "",
month: "",
_index: ""
},
attached: function(){
const months = {
0 : "一月",
1 : "二月",
2 : "三月",
3 : "四月",
4 : "五月",
5 : "六月",
6 : "七月",
7 : "八月",
8 : "九月",
9 : "十月",
10 : "十一月",
11 : "十二月",
}
let date = new Date
let year = (date.getFullYear()).toString()
let monthN = (date.getMonth()).toString()
let monthS = months[monthN]
this.setData({
year: year,
month: monthS
})
},
/**
* 元件的方法列表
*/
methods: {
}
})
複製程式碼
最後!!!千萬不要嘗試在observer函式裡改變properties的值!!!