最近在 Vue 項目裏面編寫一個地圖組件,發現若是把地圖實例掛載到 data 中,會報錯。javascript
代碼以下:java
export default {
data () {
return {
newMap: null
}
},
mounted () {
this.$nextTick(e=>{
this.newMap = new maptalks.Map(...)
})
}
}
複製代碼
錯誤信息以下:chrome
經過在控制檯中打印 data 中的數據,發現 Vue 給全部的屬性都加上 setter/getter ( chrome 控制檯會直接打印原始的 object,而重寫了 setter/getter 的 object 將會用 "(...)" 代替 )。這個時候恍然大悟,原來 Vue data 中會重寫變量的 getter/setter,上面的錯誤就出如今 Vue 重寫地圖實例對象的 getter/setter 時。Vue 重寫 object 的 setter/getter 是爲了跟蹤對象,實現響應式。地圖實例這樣的複雜對象沒有必要跟蹤,如下是幾種能夠避免 Vue 的 walk 過程的解決方案。ssh
1、Object.freezeui
地圖實例仍然掛到 data 上可是使用 Object.freeze 來告訴 Vue 不要監聽this
...
let map = new maptalks.Map(...)
this.newMap = Object.freeze(map)
複製代碼
此方法能夠避免 Vue 的 walk 錯誤,可是,咱們保存地圖實例到 data 中是爲了方便後續調用,若是使用了 Object.freeze ,後面對地圖實例操做如:spa
this.newMap.setCursor('crosshair')
複製代碼
會報錯,錯誤信息以下:eslint
2、定義成局部變量,放到外面code
let newMap = null
export default {
data () {
return {
}
},
mounted () {
this.$nextTick(e=>{
newMap = new maptalks.Map(...)
})
}
}
複製代碼
此方法能夠避免 Vue 的 walk 錯誤,但若是組件有多個實例的話, 會共享同一個 newMap,和以前掛在 data 上的邏輯並不徹底等價。cdn
3、變量名以 _ 開頭
export default {
data () {
return {
/* eslint-disable*/
_newMap: null
/* eslint-enable */
}
},
mounted () {
this.$nextTick(e=>{
this._newMap = new maptalks.Map(...)
})
}
}
複製代碼
此方法能夠避免 Vue 的 walk 錯誤,同時不影響後面對地圖實例進行操做,此方案爲本次選用的方案。
4、不預先定義變量,直接掛載到 this 上
export default {
data () {
return {
}
},
mounted () {
this.$nextTick(e=>{
this.newMap = new maptalks.Map(...)
})
}
}
複製代碼
此方法也能夠避免 Vue 的 walk 錯誤,同時也不影響後面對地圖實例進行操做,但本人喜歡在 Vue 中變量都定義到 data 中,便於管理。