# Vue integration

Let Vue supply the container and create and release Editor with component lifecycle.

Vue owns the page and interface; Editor owns editable content. A minimal integration needs an element reference and two lifecycle hooks, without copying the document into Vue state.

## Start with one component

Create Editor in `onMounted`, using the element reference, and destroy it in `onBeforeUnmount`. This single-file example is runnable; installation and a walkthrough are in [your first editor](/en/build/project).

### tutorial/editor.vue

```vue
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from "vue";
import { Editor } from "@quirekit/core";
import { StarterKit } from "@quirekit/starter-kit";
import { DomViewExtension } from "@quirekit/dom-view";
import "@quirekit/pm-view/style/prosemirror.css";

const props = withDefaults(defineProps<{
  /** Language of the initial example text; changing it does not replace edits. */
  locale?: "zh-CN" | "en";
}>(), { locale: "zh-CN" });
const element = ref<HTMLElement>();
let editor: Editor | undefined;

onMounted(() => {
  editor = new Editor({
    element: element.value,
    mode: "dom",
    extensions: [StarterKit, DomViewExtension],
    content: props.locale === "en" ? "<p>My first QuireKit editor.</p>" : "<p>我的第一个 QuireKit 编辑器。</p>",
  });
});
onBeforeUnmount(() => editor?.destroy());
</script>

<template><div ref="element" class="p-qk-surface" /></template>

```

A local variable holds the instance. Use `shallowRef<Editor>()` when templates or other components need it; internal document and view objects do not need deep reactivity.

## Let Vue manage interface state

For a Bold button, subscribe to Editor events and synchronize only the required boolean into Vue. Click handlers run commands rather than editing a second document and writing it back.

See the [toolbar tutorial](/en/build/commands). Replace content explicitly when genuinely opening another document.

## Nuxt and asynchronous loading

The server has no mounted element, so create DOM-backed Editor after browser mounting. Use a client component or `ClientOnly` for browser-specific capabilities. If asynchronous imports finish after unmount, do not create the instance.

Locale changes should update controls without replacing content, and theme changes should preserve undo history. For an existing paginated interface, see [Classic Vue integration](/en/classic/quick-start).
