nextjs+高德地图 样式问题

nextjs 引入高德地图Amap 路由切换地图样式乱了

很简单的引用 但是路由切换地图就会有问题


import * as React from 'react';
import { Toast } from 'antd-mobile';
import { useState, useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';
import Router, { useRouter } from 'next/router';
import styles from './index.module.scss'
// 地图要使用windows对象,所以用dynamic 
const Amap = dynamic(import('../../components/testAmap'), { ssr: false });
const TestMap = () => {
    const [locInfo, setlocInfo] = useState({});

 
    return (<div>
        <div onClick={() => Router.back()}>返回</div> 
        <div >
            <Amap locInfo={locInfo} />
        </div>
    </div >)

}
export default TestMap;


//Amap:

import React, { useState} from 'react';
import { APILoader, Map, Geolocation, Marker } from '@uiw/react-amap'; 
const Amapwithmap = () => {
  const [data, setData] = useState({}); 

 
  return (
    <> 
      <div className={styles.map_container}>
        <div style={{ width: '100%', height: '200px' }}>
          <Map zoom={10}> 
          </Map>
        </div>
        <pre style={{ padding: 10, marginTop: 10 }}>
          {data ? JSON.stringify(data, null, 2) : '{正在获取}'}
        </pre>
      </div>
    </>
  );
}

const Mount = () => (
  <APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
    <Amapwithmap />
  </APILoader>
);

export default Mount;

img

只要一点返回再回来 地图组件size就崩了 外层div框不住了

img

有没有人遇到过这个奇葩的问题啊

这种情况可能是因为高德地图的样式被重新计算导致的,您可以尝试在页面加载完成后重新计算一下地图的大小和样式。

可以使用useEffect钩子函数来监听路由变化,并在路由变化后重新计算地图的大小和样式。具体代码如下:

import * as React from 'react';
import { Toast } from 'antd-mobile';
import { useState, useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';
import Router, { useRouter } from 'next/router';
import styles from './index.module.scss'
// 地图要使用windows对象,所以用dynamic 
const Amap = dynamic(import('../../components/testAmap'), { ssr: false });

const TestMap = () => {
    const [locInfo, setlocInfo] = useState({});

    // 监听路由变化
    useEffect(() => {
        const handleRouteChange = () => {
            // 重新计算地图大小和样式
            window.AMap && window.AMap.event.trigger(window.map, 'resize');
        };
        Router.events.on('routeChangeComplete', handleRouteChange);
        return () => {
            Router.events.off('routeChangeComplete', handleRouteChange);
        };
    }, []);

    return (
        <div>
            <div onClick={() => Router.back()}>返回</div> 
            <div >
                <Amap locInfo={locInfo} />
            </div>
        </div>
    )
}

export default TestMap;

在上述代码中,我们使用了Router.events来监听路由变化事件,每当路由切换完毕时会执行回调函数handleRouteChange,在该回调函数中重新计算地图的大小和样式。

希望这个方法能解决您的问题。

可以手动销毁和重建Amap的地图实例。在Next.js中,可以使用useEffect钩子在组件挂载和更新时销毁和重建地图实例

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
根据你提供的代码和截图,可能是由于高德地图组件在组件更新时引起的问题。在组件更新时,高德地图组件可能会重新计算其大小和位置,并且可能会超出其父元素的边界,导致其外部的 div 框无法容纳它。

你可以尝试在组件更新时手动重新设置高德地图组件的大小和位置,以确保它能够适应其外部容器的大小。

具体来说,你可以使用 useRef 钩子来获取地图组件的 DOM 元素,并在 useEffect 钩子中计算并设置其大小和位置。以下是一个参考示例代码,供你参考:

import React, { useState, useRef, useEffect } from 'react';
import { APILoader, Map, Geolocation, Marker } from '@uiw/react-amap'; 
import styles from './index.module.scss';

const Amapwithmap = () => {
  const [data, setData] = useState({});
  const mapRef = useRef(null); // 用于获取地图组件的 DOM 元素

  useEffect(() => {
    // 在组件更新时重新设置地图组件的大小和位置
    const mapInstance = mapRef.current.getInstance();
    if (mapInstance) {
      mapInstance.setZoom(10); // 设置地图缩放级别
      mapInstance.setFitView(); // 自适应地图视野
    }
  }, [data]);

  return (
    <div className={styles.map_container}>
      <div style={{ width: '100%', height: '200px' }}>
        <Map ref={mapRef}> 
        </Map>
      </div>
      <pre style={{ padding: 10, marginTop: 10 }}>
        {data ? JSON.stringify(data, null, 2) : '{正在获取}'}
      </pre>
    </div>
  );
}

const Mount = () => (
  <APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
    <Amapwithmap />
  </APILoader>
);

export default Mount;

请注意,上述代码仅提供了一个基本的框架,你可能需要根据实际情况进行修改。此外,你需要确保地图组件的 DOM 元素在组件挂载后才能获取到,因此需要使用 useRef 钩子并将其传递给地图组件的 ref 属性。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

高德地图,挺详细得
https://blog.csdn.net/weixin_45031595/article/details/108975405

\ 根据您的描述,当在Next.js中使用高德地图(Amap)并在路由切换后返回到地图组件时,地图组件的大小会出现问题。外层的div框无法正确地包裹地图组件。

这个问题可能是由于在组件重新渲染时,地图组件无法正确地进行大小适应所导致的。可能的原因是在重新渲染时,地图组件没有进行必要的更新和调整。

为了解决这个问题,您可以尝试在TestMap组件中使用useEffect钩子来监听路由的变化,并在路由变化时重新设置地图组件的大小。具体的做法是在useEffect中添加一个回调函数,当路由发生变化时,您可以通过操作地图组件的DOM元素,重新设置其大小以适应父容器。

以下是一个可能的解决方案示例:

import { useEffect, useRef } from 'react';

const TestMap = () => { const mapContainerRef = useRef(null);

useEffect(() => { const handleRouteChange = () => { // 获取地图容器元素 const mapContainer = mapContainerRef.current; // 设置地图容器的大小 // 根据您的实际需求,可以使用适当的方法来设置地图容器的大小,比如通过修改CSS样式或调用地图组件的相关API。 };

// 监听路由变化
Router.events.on('routeChangeComplete', handleRouteChange);

// 组件卸载时取消监听
return () => {
  Router.events.off('routeChangeComplete', handleRouteChange);
};

}, []);

return (

<div onClick={() => Router.back()}>返回
); };

请根据您的实际需求,通过修改上述示例代码中设置地图容器大小的部分来适配您的项目。

希望这个解决方案能帮助到您!如果问题还未解决或有任何其他疑问,请随时提问。