Vue组件通过动态绑定对象更新后子组件视图无刷新的解决方式
一、问题描述
组件的层级关系如图所示, 期望是点击气象设备组件的解析按钮将文本框的数据解析为气象对象(包含经纬度信息),并将该值传递给地图子组件,地图组件根据其经纬度信息更新位置锚点。 数据传递的方式采用对象动态绑定,即将所有的属性值进行向下单向传递。
<DisplayMap v-bind:meteorologyVo="meteorologyVo"></DisplayMap>
地图子组件利用props进行引用:
props:{
meteorologyVo: Object,
}
锚点的HTML代码为:
<bm-marker :position="{lng: meteorologyData.longitude, lat: meteorologyData.latitude}"></bm-marker>
绑定后,点击解析按钮,地图子组件的锚点跑到了经纬度同为0的地方。
二、问题分析
有两个层次的问题需要搞清楚:
- 对象是通过引用传递到子组件中,对象的属性值发生变化,引用未发生变化,导致Vue实例监听不到变化
- 组件的层次过深,地图子组件不是真实的子组件,图中还经历了行组件
ARow
三、曲线解决问题
3.1 添加动态聚合标签
<bm-marker-clusterer :averageCenter="true">
<bm-marker v-for="marker of markers" :key="marker.code" :position="{lng: marker.lng, lat: marker.lat}" @click="lookDetail(marker)" animation="BMAP_ANIMATION_BOUNCE"></bm-marker>
</bm-marker-clusterer>
3.2 添加数组对象markers
data(){
markers: [],
}
3.3 添加对象监听函数
曲线救国,利用数组的操作更新视图,数组的多种方法都可以让Vue实例对DOM进行重新渲染。
watch:{
meteorologyVo:{
handler(val, oldValue){
console.log(oldValue);
let marker = {
code: 2,
lng: val.gpsVo.longitude,
lat: val.gpsVo.latitude,
}
this.markers.pop();
this.markers.push(marker);
},
deep: true
}
四、结果展示
|