一個 Vue 地圖組件錯誤引起的思考

最近在 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 中,便於管理。

相關文章
相關標籤/搜索