> **本文回答**：自定义 DOM 作为 Marker —— 纯图标 / 图+文 / Vue / React / 复杂卡片。

## 一、纯图标（CSS 背景图）

```html
<style>
  .m-pin {
    width: 32px; height: 32px;
    background: url("/icons/pin.png") center/cover no-repeat;
    cursor: pointer;
  }
</style>
```

```js
const el = document.createElement("div");
el.className = "m-pin";
new vjmap.Marker({ element: el, anchor: "bottom" })
  .setLngLat([lng, lat]).addTo(map);
```

## 二、图 + 文（父 div 包两个子 div）

```html
<style>
  .m-wrap { text-align: center; cursor: pointer; }
  .m-icon {
    width: 32px; height: 32px; margin: 0 auto;
    background: url("/icons/pin.png") center/cover no-repeat;
  }
  .m-text {
    font-size: 12px; color: #fff; background: rgba(0, 0, 0, 0.6);
    padding: 2px 6px; border-radius: 3px; margin-top: 2px;
  }
</style>
```

```js
const wrap = document.createElement("div");
wrap.className = "m-wrap";

const icon = document.createElement("div");
icon.className = "m-icon";

const text = document.createElement("div");
text.className = "m-text";
text.textContent = "站点 A";

wrap.appendChild(icon);
wrap.appendChild(text);

new vjmap.Marker({ element: wrap, anchor: "bottom" })
  .setLngLat([lng, lat]).addTo(map);
```

## 三、复杂卡片

```js
const el = document.createElement("div");
el.innerHTML = `
  <div style="background:#fff;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.15);
              padding:8px 12px;font-size:12px;min-width:120px">
    <div style="font-weight:bold">站点 A</div>
    <div style="color:#666">当前状态：正常</div>
    <div style="color:#0af">温度 26℃</div>
  </div>
`;
new vjmap.Marker({ element: el, anchor: "bottom" })
  .setLngLat([lng, lat]).addTo(map);
```

## 四、Vue 3 组件作为 Marker

```vue
<!-- MyPin.vue -->
<template>
  <div class="pin" :style="{ background: color }">
    {{ label }}
  </div>
</template>
<script setup>
defineProps(["color", "label"]);
</script>
<style scoped>
.pin { padding: 4px 8px; color: #fff; border-radius: 4px; cursor: pointer; }
</style>
```

使用：

```js
import { createApp } from "vue";
import MyPin from "./MyPin.vue";

function createVuePin(props) {
  const container = document.createElement("div");
  createApp(MyPin, props).mount(container);
  return container;
}

const el = createVuePin({ color: "#f00", label: "Site A" });
const marker = new vjmap.Marker({ element: el, anchor: "bottom" })
  .setLngLat([lng, lat]);
marker.addTo(map);
```

**注意**：组件销毁时要同时 `marker.remove()`，否则 DOM 残留。

## 五、React 组件作为 Marker

```jsx
// MyPin.jsx
export function MyPin({ color, label }) {
  return <div style={{ background: color, padding: 4, borderRadius: 4 }}>{label}</div>;
}
```

```jsx
import ReactDOM from "react-dom/client";

const container = document.createElement("div");
ReactDOM.createRoot(container).render(<MyPin color="#f00" label="Site A"/>);

const marker = new vjmap.Marker({ element: container, anchor: "bottom" })
  .setLngLat([lng, lat]);
marker.addTo(map);
```

卸载时：

```js
marker.remove();
// 可选：
// reactRoot.unmount();
```

## 六、动态更新 Marker 内容（不重建）

```js
const label = document.createElement("div");
label.textContent = "0℃";
const marker = new vjmap.Marker({ element: label }).setLngLat([lng, lat]);
marker.addTo(map);

setInterval(() => {
  label.textContent = `${(Math.random() * 30).toFixed(1)}℃`;
}, 1000);
```

直接改 DOM 内容，不用重建 Marker。

## 七、拖拽时实时更新

```js
marker.setDraggable(true);
marker.on("drag", () => {
  const ll = marker.getLngLat();
  console.log("dragging to", ll);
});
marker.on("dragend", () => {
  console.log("dropped at", marker.getLngLat());
});
```

## 八、克隆 Marker 作为 hover 指示

```js
const clone = marker.getElement().cloneNode(true);
clone.style.transform = "scale(1.2)";
const hoverMarker = new vjmap.Marker({ element: clone })
  .setLngLat(marker.getLngLat());
hoverMarker.addTo(map);
```

## 九、常见坑

1. **`element` 没设 width/height** → Marker 不可见；必须显式 CSS 尺寸。
2. **点击穿透** → 元素的 pointer-events 被全局 CSS 禁用；Marker 建议 `pointer-events: auto`。
3. **组件数据变了但没更新**：Vue/React 管理的 DOM，改 props 时组件会重绘；但 Marker 的 lngLat 要单独 setLngLat。
4. **Vue 3 响应式在 Marker 里断链**：Marker 只拿 DOM 节点，不进入 Vue 的 diff。用函数式 props 往组件里推数据。
