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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@route-optimization/vue

v1.0.4

Published

Vue 3 composables and components for route optimization and delivery management

Downloads

379

Readme

@route-optimization/vue

Vue 3 composables and components for route optimization and delivery management with Google Maps integration.

Installation

npm install @route-optimization/vue @route-optimization/core
# or
pnpm add @route-optimization/vue @route-optimization/core
# or
yarn add @route-optimization/vue @route-optimization/core

Features

  • ✅ Vue 3 Composition API composables
  • ✅ Ready-to-use components with slots for customization
  • ✅ TypeScript support with full type definitions
  • ✅ Reactive map controls (zoom, center, bounds)
  • ✅ Route rendering with automatic bounds fitting
  • ✅ Loading and error states built-in
  • ✅ Lightweight bundle (~7KB ES, ~5KB CJS)
  • ✅ Zero runtime dependencies (except Vue 3 and core)

Quick Start

Basic Usage with Component

<template>
  <div>
    <RouteMapView
      :api-key="googleMapsApiKey"
      :route="deliveryRoute"
      height="500px"
      :auto-fit-bounds="true"
      @map-ready="onMapReady"
      @route-rendered="onRouteRendered"
      @error="onError"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { RouteMapView } from '@route-optimization/vue';
import type { Route } from '@route-optimization/core';

const googleMapsApiKey = 'YOUR_GOOGLE_MAPS_API_KEY';

const deliveryRoute = ref<Route>({
  id: 'route-1',
  vehicleId: 'vehicle-1',
  stops: [
    {
      id: 'stop-1',
      location: { lat: 13.7563, lng: 100.5018 },
      address: 'Bangkok, Thailand',
      type: 'START',
      sequence: 0,
    },
    {
      id: 'stop-2',
      location: { lat: 13.7467, lng: 100.5342 },
      address: 'Sukhumvit, Bangkok',
      type: 'DELIVERY',
      sequence: 1,
    },
  ],
  totalDistance: 5200,
  totalDuration: 15,
  status: 'pending',
});

const onMapReady = (map: google.maps.Map) => {
  console.log('Map ready:', map);
};

const onRouteRendered = (route: Route) => {
  console.log('Route rendered:', route);
};

const onError = (error: Error) => {
  console.error('Map error:', error);
};
</script>

Using Composables

<template>
  <div>
    <div ref="mapContainer" style="height: 500px"></div>

    <div v-if="isLoading">Loading map...</div>
    <div v-if="error">Error: {{ error.message }}</div>

    <button @click="renderCurrentRoute" :disabled="!mapInstance">Render Route</button>
    <button @click="clearRoute">Clear</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useRouteMap } from '@route-optimization/vue';
import type { Route } from '@route-optimization/core';

const mapContainer = ref<HTMLElement | null>(null);

const { mapInstance, isLoading, error, renderRoute, clearRoute, fitBounds } = useRouteMap({
  apiKey: 'YOUR_GOOGLE_MAPS_API_KEY',
  mapContainer,
  center: { lat: 13.7563, lng: 100.5018 },
  zoom: 12,
  onMapReady: (map) => {
    console.log('Map initialized:', map);
  },
  onError: (err) => {
    console.error('Map error:', err);
  },
});

const route = ref<Route>({
  // ... your route data
});

const renderCurrentRoute = async () => {
  if (route.value) {
    await renderRoute(route.value);
    fitBounds();
  }
};
</script>

Map Controls

<template>
  <div style="position: relative">
    <RouteMapView ref="mapViewRef" :api-key="apiKey" :route="route" height="600px" />

    <MapControls
      v-if="mapViewRef?.mapInstance"
      :map-instance="mapViewRef.mapInstance"
      :show-zoom-level="true"
      :show-reset-button="true"
      @zoom-change="onZoomChange"
    >
      <template #zoom-in-icon>
        <PlusIcon />
      </template>
      <template #zoom-out-icon>
        <MinusIcon />
      </template>
    </MapControls>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { RouteMapView, MapControls } from '@route-optimization/vue';

const mapViewRef = ref();
const apiKey = 'YOUR_GOOGLE_MAPS_API_KEY';

const onZoomChange = (zoom: number) => {
  console.log('Zoom level:', zoom);
};
</script>

API Reference

RouteMapView Component

A complete map view component with route rendering.

Props:

| Prop | Type | Default | Description | | --------------- | --------------- | --------------------------------- | ---------------------------------- | | apiKey | string | required | Google Maps API key | | route | Route \| null | null | Route to display on the map | | center | LatLng | { lat: 13.7563, lng: 100.5018 } | Initial map center | | zoom | number | 12 | Initial zoom level | | height | string | '500px' | Map container height | | width | string | '100%' | Map container width | | autoFitBounds | boolean | true | Auto-fit bounds when route changes |

Events:

| Event | Payload | Description | | ---------------- | ----------------- | ------------------------------- | | map-ready | google.maps.Map | Emitted when map is initialized | | route-rendered | Route | Emitted when route is rendered | | error | Error | Emitted when an error occurs |

Slots:

| Slot | Description | | --------- | -------------------------------------------- | | loading | Custom loading indicator | | error | Custom error display (receives error prop) |

Exposed Methods:

  • mapInstance: Ref to Google Maps instance
  • renderRoute(route): Manually render a route
  • clearRoute(): Clear current route
  • fitBounds(): Fit map to route bounds

MapControls Component

Customizable map zoom controls.

Props:

| Prop | Type | Default | Description | | ----------------- | ------------------------------ | -------- | ----------------------- | | mapInstance | Ref<google.maps.Map \| null> | required | Map instance reference | | initialZoom | number | 12 | Initial zoom level | | minZoom | number | 1 | Minimum zoom level | | maxZoom | number | 20 | Maximum zoom level | | showZoomLevel | boolean | false | Show current zoom level | | showResetButton | boolean | false | Show reset zoom button |

Events:

| Event | Payload | Description | | ------------- | -------- | ----------------------------- | | zoom-change | number | Emitted when zoom changes | | zoom-in | - | Emitted when zoom in clicked | | zoom-out | - | Emitted when zoom out clicked | | reset | - | Emitted when reset clicked |

Slots:

| Slot | Description | | ----------------- | ------------------------------ | | before-controls | Content before zoom controls | | after-controls | Content after zoom controls | | zoom-in-icon | Custom zoom in button content | | zoom-out-icon | Custom zoom out button content | | reset-icon | Custom reset button content |

useRouteMap Composable

Composable for managing map instance and route rendering.

function useRouteMap(options: UseRouteMapOptions): UseRouteMapReturn;

interface UseRouteMapOptions {
  apiKey: string;
  mapContainer: Ref<HTMLElement | null>;
  center?: LatLng;
  zoom?: number;
  onMapReady?: (map: google.maps.Map) => void;
  onError?: (error: Error) => void;
}

interface UseRouteMapReturn {
  mapInstance: Ref<google.maps.Map | null>;
  isLoading: Ref<boolean>;
  error: Ref<Error | null>;
  renderRoute: (route: Route) => Promise<void>;
  clearRoute: () => void;
  fitBounds: () => void;
}

useMapControls Composable

Composable for managing map zoom controls.

function useMapControls(
  mapInstance: Ref<google.maps.Map | null>,
  options?: UseMapControlsOptions
): UseMapControlsReturn;

interface UseMapControlsOptions {
  initialZoom?: number;
  minZoom?: number;
  maxZoom?: number;
  onZoomChange?: (zoom: number) => void;
}

interface UseMapControlsReturn {
  zoom: Ref<number>;
  canZoomIn: Ref<boolean>;
  canZoomOut: Ref<boolean>;
  zoomIn: () => void;
  zoomOut: () => void;
  setZoom: (level: number) => void;
  resetZoom: () => void;
}

Advanced Usage

Custom Loading State

<RouteMapView :api-key="apiKey" :route="route">
  <template #loading>
    <div class="custom-loader">
      <SpinnerIcon />
      <p>Initializing map...</p>
    </div>
  </template>
</RouteMapView>

Custom Error Handling

<RouteMapView :api-key="apiKey" :route="route">
  <template #error="{ error }">
    <div class="error-card">
      <ErrorIcon />
      <h3>Map Error</h3>
      <p>{{ error.message }}</p>
      <button @click="retry">Retry</button>
    </div>
  </template>
</RouteMapView>

Dynamic Route Updates

<script setup lang="ts">
import { ref, watch } from 'vue';
import { RouteMapView } from '@route-optimization/vue';

const currentRoute = ref<Route | null>(null);

// Watch for route changes from your state management
watch(
  () => store.optimizedRoute,
  (newRoute) => {
    currentRoute.value = newRoute;
  }
);
</script>

<template>
  <RouteMapView :api-key="apiKey" :route="currentRoute" :auto-fit-bounds="true" />
</template>

Type Definitions

This package re-exports all types from @route-optimization/core:

import type { Route, Stop, Vehicle, LatLng, RouteMetrics, StopType } from '@route-optimization/vue';

Bundle Size

  • ES Module: ~7.0 KB (2.3 KB gzipped)
  • CommonJS: ~5.1 KB (1.9 KB gzipped)
  • Includes CSS: ~1.6 KB (0.6 KB gzipped)

Browser Support

  • Modern browsers with ES2020 support
  • Vue 3.3.0 or higher required
  • Google Maps JavaScript API v3

Related Packages

License

MIT

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.