nuxt使用antv-l7踩坑

简介: nuxt.js 下使用 antv-l7 实在是有太多的坑了,官方文档也不是很全,只能不断摸索和尝试,下面我把这些坑记录下来,也许能帮到你。这些解决方案不会是唯一解,也不见得是最优解,但至少解决了我的问题,而且还保留了代码的相对整洁和高效。如果你有更好的解决方案,欢迎留言;如果未来官方修复了这些问题,或者提供了更好的使用方法,那请忽略这篇文章。

nuxt.js 下使用 antv-l7 实在是有太多的坑了,官方文档也不是很全,只能不断摸索和尝试,下面我把这些坑记录下来,也许能帮到你。

这些解决方案不会是唯一解,也不见得是最优解,但至少解决了我的问题,而且还保留了代码的相对整洁和高效。如果你有更好的解决方案,欢迎留言;如果未来官方修复了这些问题,或者提供了更好的使用方法,那请忽略这篇文章。

nuxt 下只能通过 plugin 的方式引入 l7

不能直接用 import { Scene } from '@antv/l7' 这样的方法,在任何地方都不行,会出现 window undefined 的错误

比较隐蔽的情况是,访问 localhost:3000/ 等页面是正常的,然后通过点击菜单(即利用 Nuxt to 来完成跳转),那及时使用了 import 也一切正常,但,这种时候,这个页面是不能被刷新的,也不能直接访问,否则一样会出现 window undefined 的错误

解决方案就是和其他的 client only 组件一样,通过 plugin 的方式引入

plugins 目录下新建 l7.js

import Vue from 'vue'

const l7 = require('@antv/l7')
const l7maps = require('@antv/l7-maps')

Vue.prototype.$l7 = l7
Vue.prototype.$l7maps = l7maps

并在 nuxt.config 中设置为仅 client 引入插件

plugins: [
    '@/plugins/fontawesome',
    { src: '@/plugins/g2', ssr: false }, // antv-g2 也是一样
    { src: '@/plugins/l7', ssr: false },
  ],

使用时,利用 this.$l7 的方式使用

const { Scene, Popup } = this.$l7
const { GaodeMap, Mapbox } = this.$l7maps

地图不能重复渲染,会卡死

这个坑出现的原因还没有找到,怀疑是 antv-l7 这个库在实现时有问题,也可能是与 nuxt 的某种机制冲突,因为好像单独用的时候是没问题的

问题表现如下:假设有一个页面,叫做 map,其中有 2 个地图,中国地图和世界地图,这两个地图显示在不同的 <div id= 中,利用一个 Switch 按钮切换

会出现的问题是,首次进入页面(不妨设进入中国地图)一切正常,点击 Switch 切换到世界地图,正常,再切换回中国地图,卡死

类似的卡死问题还有,进入 map 页面后点击菜单切换到别的页面,然后切换回来,卡死

使用 antv-l7 提供的 scene.destroy 并不能解决问题

后来利用了 keep-alive 解决,即 <Nuxt keep-alive />,将地图的代码封装成一个 Component,然后把这个组件保留起来,避免重复加载

<Nuxt keep-alive />

图层的位置在拖动时会变

地图图层和标注点的图层拖动时不一致,导致拖动后点的位置错位

position: relative

这个其实在官方文档写了,这个属性很重要,否则地图会铺满上层 div,并且缩放时点的位置会偏移

可以根据自己的情况考虑使用 absolute

MapBox 地图不会自动铺满,而 GaodeMap 会铺满

大坑

如果设置了类似于父组件的宽度根据浏览器的宽度变化这样的功能,期望地图的大小始终跟着浏览器宽度变化的话,GaodeMao 没有任何问题,会自动铺满整个屏幕,但 MapBox 地图在初次显示时,仍然会莫名其妙变成 400 * 300 大小,只有在重新改变浏览器宽度时才会正确铺满

这个问题在 Github 上有人提出(https://github.com/mapbox/mapbox-gl-js/issues/3265),是由于 MapBox 初次加载时长宽一定为 300 * 400,必须经过一次 map.resize() 才能正确获得目标 div 的大小

由于 AntV-l7 做了一层封装,所以我们不太好直接去调用 map.resize(),但是我们可以简单地直接触发 window 的 resize 事件

scene.on('loaded', () => {
    window.dispatchEvent(new Event('resize'))
})

这样,窗口大小不变,但是 window.resize 被触发了,MapBox 的 resize 也被触发了,MapBox 的大小也就正常了

地图的 scene 的 on load 中读取 vuex 中的值无效

不知道原因,在组件 mounted 的时候去读 vuex 中的屏幕宽度,期望能够设置到 div 的样式,但发现这个值能够被正确输出,地图大小却不对

怀疑是 antv-l7 绘制是在 mounted 拿到数据之前,但我没仔细去研究 antv-l7 地图绘制是在什么阶段完成的,所以不知道是不是用 async 这样的方法就可以确保 mounted 拿到数据后才绘制地图,也可能根本就不是这个原因,总之,我不知道有没有更好的解决方案

我通过强制让数据发生变化,触发 vue 对所有组件的重新绘制

that.screenWidth = that.$store.getters['size/getWidth']
that.screenWidth -= 1
that.screenWidth += 1 // nextTick
目录
相关文章
|
移动开发 数据可视化 UED
从网页到应用:简易教程教你如何在线生成App
本文将介绍一种简便的方法,让您能够将网页封装成APP。通过这种技术,您可以将您的网页应用程序转化为移动应用程序,从而更好地满足用户的需求。无需编程知识,只需几个简单的步骤,即可轻松将您的网页转化为功能强大的应用程序。
|
JSON Go 数据格式
【Golang】解决使用interface{}解析json数字会变成科学计数法的问题
【2月更文挑战第9天】解决使用interface{}解析json数字会变成科学计数法的问题
509 0
|
8月前
|
人工智能 自然语言处理 JavaScript
宜搭上新,DeepSeek 插件来了!
钉钉宜搭近日上线了DeepSeek插件,无需编写复杂代码,普通用户也能轻松调用强大的AI大模型能力。安装后,平台新增「AI生成」组件,支持创意内容生成、JS代码编译、工作汇报等场景,大幅提升工作效率。快来体验这一高效智能的办公方式吧!
2662 9
|
4月前
|
Ubuntu 数据库
解决Ubuntu系统获取锁失败的问题
不过记住,这种方式有如凤凰涅槃,万不得已时才使用。这样,繁琐的锁定问题就被巧妙解决了。从此,当你再次面对这类状况时,就能秉持锁匠之智,轻松应对。
170 23
|
8月前
|
设计模式 JavaScript 算法
浅谈几种js设计模式
设计模式是软件开发中的宝贵工具,能够提高代码的可维护性和扩展性。通过单例模式、工厂模式、观察者模式和策略模式,我们可以解决不同场景下的实际问题,编写更加优雅和高效的代码。
211 8
|
4月前
|
存储 编解码 算法
哈夫曼树完全解析:从原理到应用
哈夫曼树是一种带权路径长度最短的二叉树,广泛应用于数据压缩领域。它通过为高频元素分配短编码、低频元素分配长编码,显著减少数据量。构建时根据权重动态合并节点,最终生成无歧义前缀编码。其核心特性包括最优压缩效率、贪心策略有效性和高空间利用率。在现代应用中,哈夫曼编码被用于ZIP压缩、PNG图像、HTTP/2头部压缩及多媒体处理等领域。例如,对字符串“ABRACADABRA”进行压缩,可将88bit数据降至26bit,压缩率达70.5%。
|
11月前
|
监控 关系型数据库 MySQL
如何监控和诊断 MySQL 数据库的性能问题?
【10月更文挑战第28天】监控和诊断MySQL数据库的性能问题是确保数据库高效稳定运行的关键
1252 1
|
移动开发 搜索推荐 开发者
HTML5中的语义化标签有哪些?
【4月更文挑战第1天】HTML5中的语义化标签有哪些?
708 0
HTML5中的语义化标签有哪些?
|
监控
IEC104初学者教程,第八章:总召唤流程详解
IEC 60870-5-104(简称IEC104)是一种用于远程控制和监控系统的通信协议。它广泛应用于电力系统和其他工业自动化系统中。总召唤(General Interrogation,简称GI)是IEC104协议中的一个重要功能,用于从远程终端设备(RTU)获取其当前的状态和数据。总召唤过程的基本步骤如下:
469 5
IEC104初学者教程,第八章:总召唤流程详解