Vize

use-map

Create a reactive Map with typed helpers.

Package @vizejs/composable/use-map
Own the source vize lib pull composable:use-map
Runtime exports useMap
Gzip budget 1280 B

Minimal setup

Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).

vp install @vizejs/composable

Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.

import { useMap } from "@vizejs/composable/use-map";

Try it

Count items in a cart

Keep one counter per key and derive totals from the entries.

Open the interactive example

What to observe: Add Sticker twice and Mug once: the cart lists Sticker × 2 and Mug × 1, with 2 products and 3 items. Empty cart clears both.

update(key, fn) receives the previous value or undefined. entries and size are computed refs; read them with .value when the map object is not destructured.

Compare the initial and interacted states
Count items in a cart: initial state
Initial state
Count items in a cart: state after the verified interactions
After the verified interactions

Copy the example

Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.

<script setup lang="ts">
import { computed } from "vue";
import { useMap } from "@vizejs/composable/use-map";

const products = ["Sticker", "T-shirt", "Mug"];
const cart = useMap<string, number>();
const total = computed(() => cart.entries.value.reduce((sum, [, count]) => sum + count, 0));

function add(product: string) {
  cart.update(product, (count) => (count ?? 0) + 1);
}
</script>

<template>
  <div class="composable-example">
    <p>Count items in a cart, one entry per product.</p>
    <div class="example-actions">
      <button v-for="product in products" :key="product" type="button" @click="() => add(product)">
        Add {{ product }}
      </button>
      <button type="button" @click="() => cart.clear()">Empty cart</button>
    </div>
    <ul aria-label="Cart">
      <li v-for="[product, count] in cart.entries.value" :key="product">
        {{ product }} × {{ count }}
      </li>
    </ul>
    <output aria-live="polite">{{ cart.size.value }} products, {{ total }} items</output>
  </div>
</template>

Runtime contract

Utility Category Stability SSR Hydration Cleanup Targets Host globals Uses
useMap state experimental safe stable none web, server, worker, native, desktop, terminal — —

API

useMap

Create a reactive Map with typed helpers. Key and value types are inferred from the initial entries (useMap([["a", 1]]) is a Map<string, number>); pass type arguments for an initially empty map. Reads through get, has, and map are tracked per key, so an effect reading one key does not re-run when an unrelated key changes. Values are stored as-is (not deeply reactive). Purely synchronous state: safe during server rendering (no host globals, no timers) and nothing to dispose.

function useMap<Key = unknown, Value = unknown>( initial: Iterable<readonly [Key, Value]> = [], ): MapControls<Key, Value>
const counts = useMap<string, number>();
counts.update("clicks", (previous = 0) => previous + 1);

Types

MapControls

Reactive map wrapper returned by useMap.

Member Type Description
map ReadonlyMap<Key, Value> Read-only reactive view of the map. get, has, iteration, and size on this view are tracked per key. Values are stored shallowly.
size ComputedRef<number> Number of entries.
entries ComputedRef<readonly (readonly [Key, Value])[]> Snapshot of the entries in insertion order.
get (key: Key) => Value | undefined Read the value for key. Reactive when read inside an effect.
has (key: Key) => boolean Whether key is present. Reactive when read inside an effect.
set (key: Key, value: Value) => void Store value under key.
delete (key: Key) => boolean Remove key.
clear () => void Remove every entry.
update (key: Key, updater: (previous: Value | undefined) => Value) => Value Replace the value under key with the result of updater.
getOrInsert (key: Key, create: (key: Key) => Value) => Value Return the value under key, inserting create(key) first when absent.
reset () => void Restore the creation-time entries.