当前位置: 首页 > news >正文

vue3 根据城市名称计算城市之间的距离

<template>
  <div class="distance-calculator">
    <h1>城市距离计算器</h1>

    <!-- 城市输入框 -->
    <div class="input-group">
      <input
          v-model="city1"
          placeholder="请输入第一个城市"
          @keyup.enter="calculateDistance"
      />
      <input
          v-model="city2"
          placeholder="请输入第二个城市"
          @keyup.enter="calculateDistance"
      />
    </div>

    <!-- 计算按钮 -->
    <button @click="calculateDistance" :disabled="loading">
      {{ loading ? '计算中...' : '计算距离' }}
    </button>

    <!-- 结果显示 -->
    <div v-if="result" class="result">
      {{ result }}
    </div>

    <!-- 错误提示 -->
    <div v-if="error" class="error">
      {{ error }}
    </div>
  </div>
</template>

<script>
// 1. 需要安装的依赖:
// - Vue 3 (已包含在项目中)
// - 高德地图JS API (通过CDN引入,无需npm安装)
// - 可选: 如果需要HTTP请求,可以安装axios (npm install axios)

import { ref, onMounted } from 'vue';

export default {
  name: 'DistanceCalculator',

  setup() {
    // 2. 响应式数据
    const city1 = ref('北京'); // 默认值可修改或留空
    const city2 = ref('上海'); // 默认值可修改或留空
    const result = ref('');
    const error = ref('');
    const loading = ref(false);

    // 3. 高德地图实例
    let geocoder = null;
    let AMap = null;

    // 4. 初始化高德地图
    const initAMap = () => {
      return new Promise((resolve, reject) => {
        // 首先设置安全配置
        window._AMapSecurityConfig = {
          securityJsCode: 'efe5df61770675b2985df3e32565fb80'  // 安全密钥
        };

        // 检查是否已加载
        if (window.AMap) {
          AMap = window.AMap;
          // 确保插件加载完成后再初始化
          AMap.plugin(['AMap.Geocoder', 'AMap.GeometryUtil'], () => {
            geocoder = new AMap.Geocoder({
              city: "全国" // 指定查询范围为全国
            });
            resolve();
          });
          return;
        }

        // 动态加载高德地图JS
        const script = document.createElement('script');
        script.src = `https://webapi.amap.com/maps?v=1.4.15&key=05d4c031a356cdffb8055c0d1532ced8`;  // API key
        
        script.onload = () => {
          if (window.AMap) {
            AMap = window.AMap;
            // 加载完成后加载插件
            AMap.plugin(['AMap.Geocoder', 'AMap.GeometryUtil'], () => {
              try {
                geocoder = new AMap.Geocoder({
                  city: "全国" // 指定查询范围为全国
                });
                resolve();
              } catch (err) {
                reject(new Error('Geocoder 插件初始化失败'));
              }
            });
          } else {
            reject(new Error('AMap 加载失败'));
          }
        };
        
        script.onerror = () => {
          reject(new Error('高德地图脚本加载失败'));
        };
        
        document.head.appendChild(script);
      });
    };

    // 5. 计算距离的主要函数
    const calculateDistance = async () => {
      if (loading.value) return;
      
      try {
        loading.value = true;
        error.value = '';
        result.value = '';

        // 确保高德地图已初始化
        if (!geocoder) {
          await initAMap();
        }

        // 验证输入
        if (!city1.value.trim() || !city2.value.trim()) {
          throw new Error('请输入两个城市名称');
        }

        // 获取城市坐标
        const [location1, location2] = await Promise.all([
          new Promise((resolve, reject) => {
            geocoder.getLocation(city1.value, (status, result) => {
              if (status === 'complete' && result.geocodes.length) {
                resolve(result.geocodes[0].location);
              } else {
                reject(new Error(`无法获取 ${city1.value} 的坐标`));
              }
            });
          }),
          new Promise((resolve, reject) => {
            geocoder.getLocation(city2.value, (status, result) => {
              if (status === 'complete' && result.geocodes.length) {
                resolve(result.geocodes[0].location);
              } else {
                reject(new Error(`无法获取 ${city2.value} 的坐标`));
              }
            });
          })
        ]);

        if (!AMap.GeometryUtil) {
          throw new Error('GeometryUtil 插件未加载成功');
        }

        const distance = AMap.GeometryUtil.distance(
          [location1.lng, location1.lat],
          [location2.lng, location2.lat]
        );

        const distanceInKm = Math.round(distance / 1000);
        result.value = `${city1.value} 到 ${city2.value} 的直线距离约为: ${distanceInKm}公里`;

      } catch (err) {
        console.error('计算距离出错:', err);
        error.value = err.message || '计算距离时出错';
      } finally {
        loading.value = false;
      }
    };

    // 6. 组件挂载时初始化
    onMounted(() => {
      // 预加载高德地图
      initAMap().catch(err => {
        console.error('初始化地图失败:', err);
        error.value = '初始化地图失败,请刷新重试';
      });
    });

    return {
      city1,
      city2,
      result,
      error,
      loading,
      calculateDistance
    };
  }
};
</script>

<style scoped>
.distance-calculator {
  max-width: 500px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

.input-group {
  margin: 20px 0;
  display: flex;
  gap: 10px;
}

input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

button {
  background-color: #4CAF50;
  color: white;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.result {
  margin-top: 20px;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
}

.error {
  margin-top: 20px;
  padding: 10px;
  color: #dc3545;
  background-color: #f8d7da;
  border-radius: 4px;
}
</style>

相关文章:

  • 【系统性偏见:AI照出的文明暗伤与生存悖论】
  • 10种涨点即插即用模块 特征处理合集篇(六)!!!(附原文地址+论文+代码)
  • Using SAP an introduction for beginners and business users
  • 磁盘结构损坏防护与应对全解析:从风险预警到数据拯救的关键策略
  • git push origin masterremote: [session-bd46a49f] The token username invalid
  • kaggle共享单车预测
  • 当 EcuBus-Pro + UTA0401 遇上 NSUC1500
  • C++/数据结构:哈希表知识点
  • Redis BitMap 实现签到及连续签到统计
  • Dart之库和可见性和异步支持、生成器、可调用类与Isolates、Typedefs和元数据
  • 微前端 - 以无界为例
  • C语言库zlog日志库工具
  • 23种设计模式-结构型模式-组合
  • RabbitMQ消息队列面试题集合
  • 如何使用 FastAPI 构建 MCP 服务器
  • 【电动汽车再生制动控制技术(万字长文,图文并茂)】
  • 全国职业院校技能大赛 网络建设与运维样题解析
  • 11-SpringBoot3入门-整合aop
  • 分布式计算Ray框架面试题及参考答案
  • 喜讯 | 耘瞳科技视觉检测与测量装备荣膺“2024机器视觉创新产品TOP10”
  • 爱客crm下载/seo案例分享
  • 优化网站内容的方法/产品如何做市场推广
  • 绵阳的网站建设/百度seo优化技巧
  • 莆田企业免费建站/广告公司名称
  • 注册公司注册/seo怎么做教程
  • b2c的网站名称有哪些/最新的销售平台