umi3.x使用百度地图

本文介绍了如何在基于Umi的React应用中添加地图定位功能。首先,通过创建自定义插件在HTML中引入BaiduMapsAPI,然后在UMI配置文件中注册该插件。接着,手动添加ejs模板引擎并在其中插入地图脚本。最后,展示了如何在Map组件中初始化地图,进行定位和添加覆盖物的操作。

前言

在写react中需要使用地图的一个定位功能,vue是有这个入口文件的,在umi里面默认没有这个入口文件,所以需要通过自己创建ejs文件,插件结合的方式进行实现

一、用插件把链接添加到页面上

1.在在src/page下 ,新建文件 plugins/mapPlugin.js

export default (api, opts) => {
  // 在HTML尾部添加脚本
  api.addHTMLScripts(() => {
    return [
      {
        // 百度地图
        src: '//api.map.baidu.com/api?v=3.0&ak=AK码',
      },
    ];
  });
};

2.在umirc.ts中导入本地新建的插件文件mapPlugin.js

/**
umi 的路由文件
*/
import { defineConfig } from 'umi';

export default defineConfig({
 nodeModulesTransform: {
   type: 'none',
 },
 routes: [],
 fastRefresh: {},
 plugins:['./src/pages/plugins/mapPlugin.js']
});

二、手动添加ejs模板引擎

<!Doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="apple-mobile-web-app-capable" content="yes"/>
  <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
  <meta name="format-detection" content="telephone=no"/>
  <meta name="format-detection" content="email=no"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
  <title> </title>
  <script src="//api.map.baidu.com/api?v=3.0&ak=AK码"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
// Map组件
import { Navbar, Popup } from 'tdesign-mobile-react';
// import { ChevronLeftIcon } from 'tdesign-icons-react';
import { getMap } from '@/utils/api/home.js'
import { useEffect, useState } from 'react';
import './index.less'
import { useLocation } from 'umi';

export default function MapPage() {
    const location = useLocation()
    let [isShow, setIsShow] = useState(false)
    const [visible, setVisible] = useState(false)
    const handleVisibleChange = (visible: any) => {
        setVisible(visible);
    }
    useEffect(() => {
        initMap()
    }, [])
    const initMap = () => {
        // 获取当前定位城市
        // JSON.parse(sessionStorage.getItem('hkzf_city')||'')  |||window.sessionStorage.getItem('currentCity')
        const { label, value } = JSON.parse(JSON.stringify({ label: "北京", value: "AREA|88cff55c-aaa4-e2e0", pinyin: "beijing", short: "bj" }))
        // 初始化地图实例
        var map = new BMap.Map("container");
        // 创建地址解析器实例
        var myGeo = new BMap.Geocoder();
        // 将地址解析结果显示在地图上,并调整地图视野
        myGeo.getPoint(label, async (point: any) => {
            if (point) {
                //缩放
                map.centerAndZoom(point, 11);
                //添加标记
                map.addOverlay(new BMap.Marker(point))

                //添加控件
                map.addControl(new BMap.ScaleControl())
                // map.addControl(new BMap.ZoomControl())
                renderOverLays(value, 11, map, point)
            } else {
                alert('您选择的地址没有解析到结果!');
            }
        }, label)
        map.addEventListener('movestart', () => {
            if (isShow) {
                setIsShow(false)
            }
        })
    }
    // 创建区, 镇覆盖物
    const createCircle = (item: any, zoom: any, map: any, point: any) => {
        const { coord: { longitude, latitude }, label: areaName, count, value } = item
        const areaPoint = new BMap.Point(longitude, latitude)

        //添加文本覆盖物
        const opts = {
            position: areaPoint,
            offset: new BMap.Size(30, -30)
        }
        //注意:设置setContent以后,第一个参数中设置的文本内容就失效了,因此直接清空即可
        const label = new BMap.Label('', opts)

        //设置房源覆盖物内容
        label.setContent(`
              <div class="contest-box"  key=${value}>
                  <p class="text-bxo">${areaName}</p>
                  <p  class="text-bxo">${count}套</p>
              </div>
            `)

        //设置样式
        const labelStyle = {
            cursor: 'pointer',
            border: '2px solid white',
            whiteSpace: 'nowrap',
            fontSize: '12px',
            textAlign: 'center',
            borderRadius: '50%',
            width: '65px',
            height: '65px',
            background: 'rgba(38, 191, 110, 0.9)'

        }
        label.setStyle(labelStyle)

        zoom += 2
        if (zoom >= 15) {
            zoom = 15
        }
        // 添加单击事件
        label.addEventListener('click', () => {
            // 调用 renderOverlays 方法,获取该区域下的房源数据
            renderOverLays(item.value, zoom, map, point)

            // 放大地图,以当前点击的覆盖物为中心放大地图
            map.centerAndZoom(areaPoint, zoom)

            // 解决清除覆盖物时,百度地图API的JS文件自身报错的问题
            setTimeout(() => {
                // 清除当前覆盖物信息
                map.clearOverlays()
            }, 0)
        })
        map.addOverlay(label)
    }
    // 熏染覆盖物 接收id参数获取区域房源数据 或覆盖类型以及下级地图的缩放级别
    const renderOverLays = async (id: any, zoom: any, map: any, point: any) => {
        let data = await getMap()
        let result = data.body
        console.log(zoom);
        result.forEach((item: any) => {
            // 创建覆盖物
            createOverlays(item, zoom, map, point)
        })
    }
    const createReact = (item: any, zoom: any, map: any, point: any) => {
        const { coord: { longitude, latitude }, label: areaName, count, value } = item
        const areaPoint = new BMap.Point(longitude, latitude)
        //添加文本覆盖物
        const opts = {
            position: areaPoint,
            offset: new BMap.Size(30, -30)
        }
        //注意:设置setContent以后,第一个参数中设置的文本内容就失效了,因此直接清空即可
        const label = new BMap.Label('', opts)

        //设置房源覆盖物内容
        label.setContent(`  
              <div>
                <p>
                    ${areaName} ${count}套
                  </p>

              </div>
            `)

        //设置样式
        const labelStyle = {
            border: 'none',
            cursor: 'pointer',
            whiteSpace: 'nowrap',
            fontSize: '12px',
            textAlign: 'center',
            height: '20px',
            background: 'rgba(38, 191, 110, 0.9)'

        }
        label.setStyle(labelStyle)

        zoom++
        // 添加单击事件
        label.addEventListener('click', () => {
            // 调用 renderOverlays 方法,获取该区域下的房源数据
            renderOverLays(item.value, zoom, map, point)

            // 放大地图,以当前点击的覆盖物为中心放大地图
            map.centerAndZoom(areaPoint, zoom)

            // 解决清除覆盖物时,百度地图API的JS文件自身报错的问题
            setTimeout(() => {
                // 清除当前覆盖物信息
                map.clearOverlays()
            }, 0)
        })
        map.addOverlay(label)
    }

    // 创建覆盖物 根据传入的数据调用对应的方法 创建覆盖物 
    const createOverlays = (item: any, zoom: any, map: any, point: any) => {
        switch (zoom) {
            case 11:
                createCircle(item, zoom, map, point)
                break;
            case 13:
                createCircle(item, zoom, map, point)
                break;
            case 15:
                createReact(item, zoom, map, point)
                break;

            default:
                break;
        }
    }

    return (
        <div className="map">
            <Navbar leftIcon style={{ zIndex: 2 }}>
                地图找房
            </Navbar>
            <div id="container" style={{ height: 799 }}>
                <Popup visible={visible} onVisibleChange={handleVisibleChange} placement="bottom">
                    <div className="vertical"></div>
                </Popup>
            </div>
        </div>
    )
}

效果:
在这里插入图片描述

<think>好的,我现在需要帮助用户在umi 3.x项目中配置和使用环境变量。用户之前的问题是关于antd表格分页不显示的问题,现在转向了umi的环境变量配置,所以需要确保回答与之前的问题没有关联,专注于当前需求。 首先,我得回忆一下umi 3.x的环境变量配置方法。umi 3.x相比2.x有一些变化,可能需要参考官方文档。根据用户提供的引用,他们在2.x中使用了cross-env和不同的配置文件,比如config.prod.js和config.test.js,通过scripts中的环境变量来切换配置。现在用户升级到3.x,可能需要类似的配置方式,但可能有不同的实现方法。 用户提供的引用[4]提到在package.json中配置scripts,使用cross-env设置UMI_ENV等变量。而引用[2]则提到了拆分配置文件,比如config.js引入其他配置。这些可能在3.x中仍然适用,但需要确认是否有变化。 首先,我需要确定umi 3.x中环境变量的标准做法。根据umi的文档,3.x版本支持通过.env文件来管理环境变量。这可能比2.x更简化,不需要那么多手动配置。例如,可以创建.env、.env.local、.env.production等文件,自动根据环境加载对应的变量。 同时,UMI_ENV这个变量在3.x中仍然有效,可以用来指定不同的环境配置。比如,设置UMI_ENV=prod会加载.env.prod和.env.prod.local文件中的变量。用户可能需要在package.json的scripts里设置UMI_ENV,然后在配置文件中使用这些变量。 另外,用户可能需要通过config/config.ts(或.js)来访问这些环境变量。在umi 3.x中,可以通过process.env来访问,但需要注意的是,只有以UMI_APP_开头的变量才会被嵌入到客户端代码中。因此,用户需要将自定义变量前缀为UMI_APP_,例如UMI_APP_API_URL,这样在代码中可以通过process.env.UMI_APP_API_URL来获取。 接下来,步骤可能包括: 1. 安装cross-env,确保跨平台兼容性。 2. 在项目根目录创建.env文件,如.env.dev、.env.test、.env.prod。 3. 在package.json的scripts中配置不同环境的启动和构建命令,使用cross-env设置UMI_ENV。 4. 在config/config.ts中根据环境变量动态配置代理、API地址等。 5. 在代码中使用process.env.UMI_APP_*访问变量。 需要验证这些步骤是否符合umi 3.x的文档,并确保用户能够正确配置。另外,用户可能需要处理不同环境的配置文件,比如代理设置或路由,这时候可以根据UMI_ENV的值来导入不同的配置模块,如引用[2]中提到的拆分配置文件的方法。 可能遇到的问题包括环境变量未正确加载,这时候需要检查变量命名是否符合UMI_APP_前缀,或者.env文件的位置是否正确。此外,如果在docker中部署,如引用[1]提到的,可能需要确保环境变量在容器运行时正确传递,这可能需要调整dockerfile或docker-compose配置。 最后,要确保回答结构清晰,分步骤说明,并提供代码示例,帮助用户一步步实现配置。同时,生成相关问题,帮助用户进一步解决可能遇到的疑问。</think>根据Umi 3.x官方文档和工程实践,以下是配置环境变量的完整方案: --- ### 一、基础配置原理 Umi 3.x采用多环境配置体系,通过`UMI_ENV`变量实现环境隔离[^4]。核心文件结构: ``` ├── .env # 基础环境变量 ├── .env.local # 本地覆盖(git忽略) ├── .env.dev # 开发环境 ├── .env.test # 测试环境 └── .env.prod # 生产环境 ``` ### 二、具体实现步骤 #### 1. 安装依赖 ```bash npm install cross-env --save-dev ``` #### 2. 配置环境文件 **示例:.env.dev** ```ini # 必须UMI_APP_前缀才能在客户端访问 UMI_APP_API_URL = http://api-dev.example.com UMI_APP_ENV = dev PORT = 8001 # 覆盖默认端口 ``` **示例:.env.prod** ```ini UMI_APP_API_URL = https://api-prod.example.com UMI_APP_ENV = prod ``` #### 3. 配置package.json脚本 ```json { "scripts": { "start": "cross-env UMI_ENV=dev umi dev", "start:test": "cross-env UMI_ENV=test umi dev", "build:test": "cross-env UMI_ENV=test umi build", "build:prod": "cross-env UMI_ENV=prod umi build" } } ``` #### 4. 动态配置处理 在`config/config.ts`中读取环境变量: ```typescript import { defineConfig } from &#39;umi&#39;; export default defineConfig({ define: { // 注入到客户端的环境变量 &#39;process.env&#39;: { API_URL: process.env.UMI_APP_API_URL, ENV: process.env.UMI_APP_ENV } }, // 动态配置代理 proxy: process.env.UMI_APP_ENV === &#39;dev&#39; ? { &#39;/api&#39;: { target: process.env.UMI_APP_API_URL, changeOrigin: true, pathRewrite: { &#39;^/api&#39;: &#39;&#39; } } } : {} }); ``` #### 5. 在代码中使用 ```jsx // 访问API地址 const apiUrl = process.env.UMI_APP_API_URL; // 判断环境 if (process.env.UMI_APP_ENV === &#39;prod&#39;) { // 生产环境逻辑 } ``` --- ### 三、高级技巧 #### 1. Docker集成优化 在Dockerfile中注入环境变量: ```dockerfile FROM node:16-alpine ARG UMI_ENV=prod ENV UMI_ENV=${UMI_ENV} COPY . . RUN npm install && npm run build:${UMI_ENV} CMD ["npm", "run", "start:${UMI_ENV}"] ``` #### 2. 多配置文件模式 创建`config/config.dev.ts`和`config/config.prod.ts`: ```typescript // config/config.dev.ts export default { proxy: { // 开发环境代理配置 } } ``` 动态加载配置: ```typescript // config/config.ts import { defineConfig } from &#39;umi&#39;; import devConfig from &#39;./config.dev&#39;; import prodConfig from &#39;./config.prod&#39;; const envConfig = { dev: devConfig, prod: prodConfig }[process.env.UMI_ENV || &#39;dev&#39;]; export default defineConfig({ ...envConfig, // 公共配置 hash: true }); ``` --- ### 四、常见问题排查 1. **变量未生效** - 确认变量前缀为`UMI_APP_` - 检查.env文件命名与`UMI_ENV`匹配 2. **构建后变量丢失** 需在`define`配置中显式声明[^2]: ```typescript define: { &#39;process.env.UMI_APP_API_URL&#39;: process.env.UMI_APP_API_URL } ``` 3. **本地覆盖技巧** 创建`.env.local`文件临时覆盖配置(不会被git跟踪) --- ### 五、版本差异说明 | 功能 | Umi 2.x | Umi 3.x | |--------------------|-----------------------|-----------------------| | 配置文件入口 | .umirc.js/config.js | config/config.ts | | 环境变量注入 | 需手动配置 | 自动加载.env文件 | | 客户端访问方式 | window.环境变量名 | process.env.UMI_APP_* | ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值