You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue.js中用Leaflet实现API分类过滤的彩色标记点及弹窗

在Vue.js中结合Leaflet实现分类过滤、颜色标记与弹窗展示

以下是具体实现步骤和代码示例:

1. 安装依赖

首先安装必要的包:

npm install vue leaflet @vue-leaflet/vue-leaflet axios

(注:axios用于API请求,也可以用原生fetch替代)

2. 完整组件实现

创建Vue组件,整合地图初始化、数据请求、过滤渲染、颜色标记和弹窗功能:

<template>
  <div class="map-container">
    <!-- 分类过滤下拉框 -->
    <select v-model="selectedCategory" @change="filterMarkers">
      <option value="all">所有分类</option>
      <option v-for="category in categories" :key="category" :value="category">{{ category }}</option>
    </select>
    
    <!-- Leaflet地图容器 -->
    <l-map ref="map" :zoom="13" :center="[51.505, -0.09]">
      <l-tile-layer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"></l-tile-layer>
      <!-- 标记点聚类组(可选,提升大量标记点的性能) -->
      <l-marker-cluster-group>
        <l-marker 
          v-for="marker in filteredMarkers" 
          :key="marker.id" 
          :lat-lng="[marker.lat, marker.lng]"
          :icon="getMarkerIcon(marker.category)"
        >
          <!-- 内置弹窗组件,点击自动触发 -->
          <l-popup>
            <div class="popup-content">
              <h3>{{ marker.title }}</h3>
              <p>{{ marker.description }}</p>
              <p>分类:<span :style="{color: colorMap[marker.category]}">{{ marker.category }}</span></p>
            </div>
          </l-popup>
        </l-marker>
      </l-marker-cluster-group>
    </l-map>
  </div>
</template>

<script>
import { LMap, LTileLayer, LMarker, LPopup, LMarkerClusterGroup } from '@vue-leaflet/vue-leaflet'
import L from 'leaflet'
import axios from 'axios'

// 导入必要样式
import 'leaflet/dist/leaflet.css'
import 'leaflet.markercluster/dist/MarkerCluster.css'
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'

export default {
  components: {
    LMap,
    LTileLayer,
    LMarker,
    LPopup,
    LMarkerClusterGroup
  },
  data() {
    return {
      markers: [], // 存储API返回的全量标记点数据
      filteredMarkers: [], // 过滤后的标记点集合
      selectedCategory: 'all', // 默认显示所有分类
      categories: [], // 提取的所有分类选项
      // 分类与颜色映射表,可根据需求自定义
      colorMap: {
        '餐饮': '#ff6b6b',
        '住宿': '#4ecdc4',
        '景点': '#45b7d1',
        '购物': '#96ceb4',
        '交通': '#ffcc5c'
      }
    }
  },
  mounted() {
    // 初始化时请求API数据
    this.fetchMarkerData()
  },
  methods: {
    // 从API获取标记点数据
    async fetchMarkerData() {
      try {
        const res = await axios.get('你的API接口地址')
        this.markers = res.data
        // 提取所有不重复的分类选项
        this.categories = [...new Set(this.markers.map(item => item.category))]
        // 初始化过滤列表
        this.filteredMarkers = [...this.markers]
      } catch (err) {
        console.error('数据请求失败:', err)
      }
    },
    // 根据分类生成对应颜色的标记图标
    getMarkerIcon(category) {
      const markerColor = this.colorMap[category] || '#333'
      // 使用divIcon自定义带颜色的圆形标记
      return L.divIcon({
        className: 'custom-marker',
        html: `<div style="background: ${markerColor}; border-radius: 50%; width: 20px; height: 20px; border: 2px solid #fff;"></div>`,
        iconSize: [20, 20],
        iconAnchor: [10, 10] // 图标锚点对应标记点位置
      })
    },
    // 根据选中分类过滤标记点
    filterMarkers() {
      if (this.selectedCategory === 'all') {
        this.filteredMarkers = [...this.markers]
      } else {
        this.filteredMarkers = this.markers.filter(marker => marker.category === this.selectedCategory)
      }
    }
  }
}
</script>

<style scoped>
.map-container {
  height: 80vh;
  position: relative;
}
select {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 1000;
  padding: 8px 12px;
  border-radius: 4px;
  border: 1px solid #ddd;
  background: #fff;
}
.popup-content {
  min-width: 180px;
}
</style>

核心逻辑说明

  • 标记点颜色控制:通过L.divIcon生成自定义HTML图标,结合colorMap映射表,实现不同分类标记点的颜色区分,无需额外图标库。
  • 分类过滤:监听下拉框选择事件,通过数组过滤方法更新filteredMarkers,Vue响应式系统会自动重新渲染地图上的标记点。
  • 弹窗展示:直接使用l-popup组件嵌套在l-marker内部,点击标记点时自动弹出,内容可直接绑定API返回的字段。
  • 聚类优化:使用LMarkerClusterGroup包裹标记点,当地图缩放时自动聚合密集标记点,提升大数量标记场景下的地图性能。

适配调整建议

  • 根据实际API返回的数据结构,修改fetchMarkerData中的字段映射逻辑。
  • 如果不需要聚类功能,移除LMarkerClusterGroup组件,直接渲染l-marker即可。
  • 若需要更复杂的图标样式,可替换为leaflet-awesome-markers库,只需调整getMarkerIcon方法的实现。

内容的提问来源于stack exchange,提问作者Ujang Aripin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:35:31