npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

laisongis-v3

v3.0.6

Published

基于vue3搭建的GIS组件

Readme

laisongis-v3

基于VUE3开发的地图组件,目前支持高德地图,谷歌地图

安装

npm i laisongis-v3

使用 -- 全局导入

main.ts页面

import App from './App.vue'
import laisonGis from 'laisongis-v3'
import 'laisongis-v3/dist/style.css'

const app = createApp(App)
app.use(laisonGis)

使用页面

<template>
  <div style="width: 100%">
    <mapEntrance
      :mapOrigin="mapOrigin"
      :propInitData="propInitData"
      :markerData="markerData"
      :dialogMsg="dialogMsg"
      :infoWinStyle="infoWinStyle"
      @click="mapClick"
      @dragend="mapDragend"
      @zoomend="mapZoomend"
      @mapOverlaysClick="mapCoverClick"
      @mapOverlaysDragend="mapCoverDragend"
    />
  </div>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from "vue";
import marker from "@/assets/image/marker.png";
import { InfoWindowsConfigAMap } from "@/views/mapTest/infoWinAMap";
import { InfoWindowsConfigGoogle } from "@/views/mapTest/infoWindowsGoogle";

export default defineComponent({
  name: "mapTest",
  setup() {
    const propInitData = reactive({
      center: {
        lng: 120.1099,
        lat: 30.2671,
      },
      zoom: 10,
      mapIndex: 1,
      projection: "EPSG:4490",
      viewMode: "3d",
      mapType: "roadmap",
      zooms: [1, 21],
    });
    const markerData = ref([
      {
        center: [120.1099, 30.2671],
        data: {
          type: "equip",
          info: {
            meterNo: "no002",
            userName: "tony",
            nickName: "王五",
            address: "江苏省",
            id: "1",
          },
        },
        dataIndex: 1,
        // autoOpen: true,
        showCluster: true,
        style: {
          size: [60, 60],
          image: marker,
          imageSize: [40, 40],
        },
      },
      {
        center: [121, 31],
        data: {
          type: "concentator",
          info: {
            concentorNo: "1",
            installTime: "里斯",
            address: "黑龙江省",
            id: "2",
          },
        },
        dataIndex: 2,
        showCluster: true,
        population: 100,
        // autoOpen: true,
        populationStyle: {
          strokeColor: "rgb(150, 194, 255)",
          strokeOpacity: 0.8,
          strokeWeight: 2,
          fillColor: "rgb(207, 227, 255)",
          fillOpacity: 0.35,
        },
        style: {
          size: [60, 60],
          image: marker,
          imageSize: [40, 40],
        },
      },
    ]);
    // 弹窗label
    const dialogMsg = [
      {
        type: "equip",
        data: [
          // { label: '标题', fields: 'title' },
          { label: "表号", fields: "meterNo" },
          { label: "用户名", fields: "userName" },
          { label: "姓名", fields: "nickName" },
          { label: "安装地址", fields: "address" },
          { label: "id", fields: "id" },
        ],
      },
      {
        type: "concentator",
        data: [
          // { label: '标题', fields: 'title' },
          { label: "集中器编号", fields: "concentorNo" },
          { label: "安装地址", fields: "address" },
          { label: "安装时间", fields: "installTime" },
          { label: "id", fields: "id" },
        ],
      }
    ];
    const mapOrigin = ref("amap");

    function mapClick(data: any) {
      console.log("地图点击事件", data);
    }

    function mapDragend(data: any) {
      console.log("地图拖拽", data);
    }

    function mapZoomend(data: any) {
      console.log("地图缩放", data);
    }

    function mapCoverClick(data: any) {
      console.log("覆盖物点击事件", data);
    }

    function mapCoverDragend(data: any) {
      console.log("覆盖物拖拽事件", data);
      markerData.value.forEach((i) => {
        if (i.dataIndex === data.data.dataIndex) {
          i.center = data.coord;
        }
      });
    }

   // 高德弹窗样式
   function infoWinStyle(val: any, clickEvent: any) {
      return InfoWindowsConfigAMap(val, clickEvent);
   }

   // //谷歌弹窗样式
   // function infoWinStyle(val: any) {
   //    return InfoWindowsConfigGoogle(val);
   // }

    return {
      propInitData,
      mapOrigin,
      markerData,
      dialogMsg,
      handle,
      mapClick,
      mapCoverClick,
      mapCoverDragend,
      infoWinStyle,
      mapDragend,
      mapZoomend,
    };
  },
});
</script>

弹窗样式

/**
 * 信息弹窗配置
 */
export function InfoWindowsConfigAMap(data, closeInfoWindow) {
    // 弹窗内容
    let title = '', content = [], contentHtml = ''
    data.data?.forEach(i => {
        if (i.fields !== 'title') {
            contentHtml += "<span>" + i.label + ":" + i.value + "</span>"
        }
    })
    content.push(contentHtml)
    // 定义信息弹窗
    let info = document.createElement("div");
    info.style.setProperty('position', 'relative');
    info.style.setProperty('top', '10');
    info.style.setProperty('width', 'auto');
    info.style.setProperty('padding', '0');
    info.style.setProperty('margin-left', '-90px')
    info.style.setProperty('margin-top', '-150px')
    info.style.setProperty('display', 'flex')
    info.style.setProperty('flex-direction', 'column-reverse')
    info.style.setProperty('cursor', 'default')

    // 宽度设置
    info.style.width = "220px";
    info.style.height = '140px'
    let titleD = document.createElement("div");
    titleD.style.setProperty('display', 'inline-block');
    titleD.innerHTML = title;

    // 定义底部内容
    var bottom = document.createElement("div");
    bottom.className = "info-bottom";
    bottom.style.position = 'relative';
    bottom.style.top = '0px';
    bottom.style.margin = '0 auto';
    var sharp = document.createElement("img");
    sharp.src = "https://webapi.amap.com/images/sharp.png";
    bottom.appendChild(sharp);
    info.appendChild(bottom);

    // 定义中部内容
    let middle = document.createElement("div");
    middle.innerHTML = content;
    middle.style.setProperty('display', 'flex')
    middle.style.setProperty('background', 'white');
    middle.style.setProperty('border', '1px solid #b4b4b4');
    middle.style.setProperty('padding', '10px');
    middle.style.setProperty('align-items', 'flex-start')
    middle.style.setProperty('flex-direction', 'column-reverse')
    middle.style.setProperty('font-size', '14px')
    middle.style.setProperty('font-weight', '500')
    middle.style.setProperty('padding-top', '10px')
    middle.style.setProperty('color', 'black')

    info.appendChild(middle);

    // 定义关闭按钮 
    let closeX = document.createElement("img");
    let top = document.createElement("div");
    top.style.setProperty('display', 'flex');
    top.style.setProperty('background', 'white');
    top.style.setProperty('padding', '5px');
    top.style.setProperty('flex-direction', 'row-reverse');
    top.style.setProperty('border', '1px solid #b4b4b4');
    top.style.setProperty('border-bottom', 'none');
    top.style.setProperty('background', '#efefef');
    closeX.src = "https://webapi.amap.com/images/close2.gif";
    closeX.style.setProperty('cursor', 'pointer')
    closeX.dataIndex = data.dataIndex
    closeX.onclick = closeInfoWindow

    top.appendChild(closeX);
    info.appendChild(top);

    return info;
}

功能介绍

  • 可自由切换地图服务源(AMAP/Google)
  • 可自由配置地图初始化数据
  • 自定义地图样式
  • 自定义地图语言
  • 自定义是否显示弹窗
  • 自定义是否打开多个弹窗
  • 自定义弹窗是否在页面移动时关闭
  • 自定义覆盖点数据
  • 自定覆盖线段数据
  • 自定义覆盖面数据
  • 自定义配置弹窗内容
  • 自定义配置弹窗样式
  • 自定义信息跳转地图
  • 手动重新加载页面
  • 自定义定位信息配置

参数配置


   /** 地图服务源 */ 
   mapOrigin = 'amap' / 'google' // 高德地图/谷歌地图

   /** 传入的地图初始化数据 */
   propInitData = {
      center: { // 地图中心点坐标
         lng: xxx,
         lat: xxx,
      },
      zoom: xx, // 地图初始化层级
      projection: "EPSG:4490", // 地图坐标系
      viewMode: '2D' / '3D', // 地图展示模式 2D/3D
      mapType: 'roadmap' / 'satellite' / 'hybrid', // 地图显示类型  默认道路图/绿色卫星图/卫星/道路图混合(鸟瞰图)
      zooms: [1, 21], // 地图可缩放层级 [1, 21]
      minZoom: 1, // 地图最小缩放层级
      maxZoom: 21, // 地图最大缩放层级
   }

   /** 地图样式 */
   mapStyle = {}

   /** 地图初始化语言 */
   language = 'zh-CN' / 'en'

   /** 是否显示弹窗 */
   popUpToggle = true / false 

   /** 是否打开多个弹窗 */
   multiPopUpToggle = true /false

   /** 弹窗是否在页面移动时关闭 */
   popUpCloseScroll = true / false

   /** 覆盖点数据集合 */
   markerData = [{
      center: xxx,
      autoOpen: true / false, // 是否自动打开弹窗
      editOverlays: true / false, // 是否可拖拽
      dataIndex: xx, // 数据key值
      data: { // 弹窗数据
         type: string, // 弹窗类型,与dialogMsg的type匹配
         infoMsg: {} // 覆盖点弹窗数据
      },
      style: { // 覆盖点样式
         size: [xx, xx],
         image: string,
         imageSize: [xx, xx]
      },
   }]

   /** 折线数据集合 */
   lineData = [{
      path: [],
      data: {
         type: string,
         infoMsg: {}
      },
      dataIndex: number,
      strokeColor: string,
      strokeOpacity: number,
      strokeWeight: number,
      zIndex: number,
      editOverlays: boolean,
      editable: boolean,
   }]

   /** 覆盖面数据集合 */
   sideData = [{
      path: [],
      data: {
         type: string,
         infoMsg: {}
      },
      dataIndex: number,
      strokeColor: string,
      strokeOpacity: number,
      strokeWeight: number,
      zIndex: number,
      editOverlays: boolean,
      editable: boolean,
   }]

   /** 弹窗label */
   dialogMsg = {} 

   /** 弹窗样式 */
   infoWinStyle = Function

   /** 输入坐标后跳转至 */
   skipMsg = {}

   /** 重新加载页面 */
   reLoadControl = true / false

   /** 定位信息配置项 */
   positionOption = {}