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