nuxt使用antv-l7踩坑

nuxt.js 下使用 antv-l7 實在是有太多的坑了,官方文檔也不是很全,只能不斷摸索和嘗試,下面我把這些坑記錄下來,也許能幫到你。

這些解決方案不會是唯一解,也不見得是最優(yōu)解,但至少解決了我的問題,而且還保留了代碼的相對整潔和高效。如果你有更好的解決方案,歡迎留言;如果未來官方修復了這些問題,或者提供了更好的使用方法,那請忽略這篇文章。

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

不能直接用 import { Scene } from '@antv/l7' 這樣的方法,在任何地方都不行,會出現(xiàn) window undefined 的錯誤

比較隱蔽的情況是,訪問 localhost:3000/ 等頁面是正常的,然后通過點擊菜單(即利用 Nuxt to 來完成跳轉(zhuǎn)),那及時使用了 import 也一切正常,但,這種時候,這個頁面是不能被刷新的,也不能直接訪問,否則一樣會出現(xiàn) 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

地圖不能重復渲染,會卡死

這個坑出現(xiàn)的原因還沒有找到,懷疑是 antv-l7 這個庫在實現(xiàn)時有問題,也可能是與 nuxt 的某種機制沖突,因為好像單獨用的時候是沒問題的

問題表現(xiàn)如下:假設有一個頁面,叫做 map,其中有 2 個地圖,中國地圖和世界地圖,這兩個地圖顯示在不同的 <div id= 中,利用一個 Switch 按鈕切換

會出現(xiàn)的問題是,首次進入頁面(不妨設進入中國地圖)一切正常,點擊 Switch 切換到世界地圖,正常,再切換回中國地圖,卡死

類似的卡死問題還有,進入 map 頁面后點擊菜單切換到別的頁面,然后切換回來,卡死

使用 antv-l7 提供的 scene.destroy 并不能解決問題

后來利用了 keep-alive 解決,即 <Nuxt keep-alive />,將地圖的代碼封裝成一個 Component,然后把這個組件保留起來,避免重復加載

<Nuxt keep-alive />

圖層的位置在拖動時會變

地圖圖層和標注點的圖層拖動時不一致,導致拖動后點的位置錯位

position: relative

這個其實在官方文檔寫了,這個屬性很重要,否則地圖會鋪滿上層 div,并且縮放時點的位置會偏移

可以根據(jù)自己的情況考慮使用 absolute

MapBox 地圖不會自動鋪滿,而 GaodeMap 會鋪滿

大坑

如果設置了類似于父組件的寬度根據(jù)瀏覽器的寬度變化這樣的功能,期望地圖的大小始終跟著瀏覽器寬度變化的話,GaodeMao 沒有任何問題,會自動鋪滿整個屏幕,但 MapBox 地圖在初次顯示時,仍然會莫名其妙變成 400 * 300 大小,只有在重新改變?yōu)g覽器寬度時才會正確鋪滿

這個問題在 Github 上有人提出(https://github.com/mapbox/mapbox-gl-js/issues/3265),是由于 MapBox 初次加載時長寬一定為 300 * 400,必須經(jīng)過一次 map.resize() 才能正確獲得目標 div 的大小

由于 AntV-l7 做了一層封裝,所以我們不太好直接去調(diào)用 map.resize(),但是我們可以簡單地直接觸發(fā) window 的 resize 事件

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

這樣,窗口大小不變,但是 window.resize 被觸發(fā)了,MapBox 的 resize 也被觸發(fā)了,MapBox 的大小也就正常了

地圖的 scene 的 on load 中讀取 vuex 中的值無效

不知道原因,在組件 mounted 的時候去讀 vuex 中的屏幕寬度,期望能夠設置到 div 的樣式,但發(fā)現(xiàn)這個值能夠被正確輸出,地圖大小卻不對

懷疑是 antv-l7 繪制是在 mounted 拿到數(shù)據(jù)之前,但我沒仔細去研究 antv-l7 地圖繪制是在什么階段完成的,所以不知道是不是用 async 這樣的方法就可以確保 mounted 拿到數(shù)據(jù)后才繪制地圖,也可能根本就不是這個原因,總之,我不知道有沒有更好的解決方案

我通過強制讓數(shù)據(jù)發(fā)生變化,觸發(fā) vue 對所有組件的重新繪制

that.screenWidth = that.$store.getters['size/getWidth']
that.screenWidth -= 1
that.screenWidth += 1 // nextTick
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容