Vue3侦听器监听数据变化早于mapContext初始化的问题
目录
- 1 问题描述
- 2 引发原因
- 3 解决方法
1 问题描述
采用 uni-app 开发包含地图功能的小程序,有时需要使用侦听器 watch
监听地图组件的某个属性,当其变化时,需要操作地图上下文 mapContext
,例如在地图上显示一些标记点。我把 mapContext
的初始化放在了 onMounted
生命周期函数中,实际运行后发现,在真机中监听到组件属性值发生变化后,调用 mapContext.addMarkers()
报错,打印 mapContext
发现为 null
。
2 引发原因
watch
监听到组件属性值发生变化时,mapContext
尚未初始化完成。
3 解决方法
借助 Promise
实现每次调用 mapContext
前都确保 mapContext
已初始化完成。
<script setup>
// 地图上下文
let mapContext = null
onMounted(() => {
// 获取地图上下文
const query = uni.createSelectorQuery().in(instance.proxy)
query
.select('#customMap')
.context(({ context }) => {
// console.log('地图上下文', context)
mapContext = context
})
.exec()
})
/**
* 确保地图上下文初始化完成
*/
const ensureMapContext = () => {
return new Promise((resolve, reject) => {
if (mapContext) {
resolve(mapContext)
} else {
// 如果未初始化完成,则设置一个轮询
const checkInterval = setInterval(() => {
if (mapContext) {
clearInterval(checkInterval)
resolve(mapContext)
}
}, 100) // 每隔100ms检查一次
// 设置一个超时,防止无限等待
setTimeout(() => {
if (!mapContext) {
clearInterval(checkInterval)
reject(new Error('地图上下文初始化超时'))
}
}, 3000) // 超时3秒
}
})
}
const props = defineProps({
a: {
type: Number,
default: 0
}
})
watch(
() => props.a,
(newValue) => {
ensureMapContext().then(mapContext => {
mapContext.moveToLocation()
}).catch(err => {
console.log('ensureMapContext error', err)
})
}
)
</script>