PageKit — der selbst gehostete GrapesJS-Website-Builder, als Quellcode. Early Access sichern

GrapesJS + Vue 3

GrapesJS Vue: Baue einen visuellen Editor mit Vue 3

Integrieren Sie den Open-Source-Visual Editor GrapesJS in Vue 3- und Nuxt-Anwendungen, um visuelle Seiteneditoren, CMS-Editoren, Landingpage-Builder, E-Mail-Editoren und White-Label-Bearbeitungserlebnisse zu erstellen.

Vue 3Composition APITypeScriptOpen SourceHTML & CSSErweiterbar
Wo der Editor sitzt

Vue treibt deine Anwendung an. GrapesJS steuert die Bearbeitung.

Die Aufteilung ist es wert, vor jeglichem Code benannt zu werden. Deine Vue-Anwendung besitzt Routing, Benutzer, Berechtigungen und Daten. GrapesJS besitzt den Canvas und alles, was eine Person darin bearbeitet. Die beiden treffen sich an einem DOM-Knoten und einem Speicheraufruf.

  1. Vue 3 application
  2. GrapesJS editor
  3. HTML + CSS + project data
  4. Your API / CMS / SaaS

Nichts in dieser Kette erfordert Vue, um zu wissen, wie der Editor funktioniert, und nichts erfordert, dass GrapesJS weiß, dass er in einer Vue-App ist. Deshalb ist die Integration kurz.

Kurze Antwort

Kann man GrapesJS mit Vue verwenden?

Ja. GrapesJS ist framework-agnostisch und kann direkt in Vue-3-Anwendungen integriert werden. Man kann den Editor mit Vue-Lebenszyklus-Hooks initialisieren, die Editor-Instanz in einem Composable oder einer Komponente speichern, GrapesJS-Ereignisse mit der Vue-Anwendung verbinden und Projektdaten über das eigene Backend speichern.

Zwei Möglichkeiten, es zu tun.

Direkte Integration

Importiere Grapesjs, rufe grapesjs.init() in onMounted() auf, ruf editor.destroy() in onUnmounted() auf. Keine zusätzlichen Abhängigkeiten, nichts zwischen dir und der Editor-API.

Eine Vue-orientierte Schicht

Packen Sie diesen Lebenszyklus in Ihrem eigenen Composable – oder einem Community-Paket – ein, damit Komponenten eine Vue-förmige API statt einer imperativen erhalten. Nützlich, wenn mehr als ein Bildschirm einen Editor montiert.

GrapesJS veröffentlicht einen offiziellen Framework-Wrapper, @grapesjs/react, für React. Es gibt kein äquivalentes Vue-Paket aus dem GrapesJS-Projekt, daher ist jeder Vue-Wrapper, den du auf npm findest, ein Community-Projekt. Überprüfe die Vue- und GrapesJS-Peer-Bereiche, bevor du ihn einsetzt.

Die Arbeitsteilung

Was ist GrapesJS für Vue?

Vue 3 ist ein Anwendungsframework. GrapesJS ist eine visuelle Bearbeitungs-Engine. Sie lösen verschiedene Probleme, und die Integration ist sauber, gerade weil sie sich nicht überlappen.

Dein Vue-Code
  • Routing
  • Authentifizierung
  • Berechtigungen
  • Anwendungs-UI
  • API und Datenschicht
In GrapesJS
  • Canvas
  • Drag & drop
  • Component tree
  • Block Manager
  • Style Manager
  • Device Manager
  • UndoManager
  • Commands
  • Serialization
Plugin oder Adapter
  • Asset Manager
  • Storage Manager
  • Rich Text Editor
  • Export

Fünf davon gehören dir. Der Rest existiert bereits, und die beiden übrigen sind Konfiguration und nicht Konstruktion.

Schritt 1

GrapesJS in Vue 3 installieren

Eine Abhängigkeit. GrapesJS liefert seine eigenen TypeScript-Definitionen aus, daher gibt es kein separates @types-Paket hinzuzufügen.

npm install grapesjs

Importiere das Stylesheet

Der Editor ist ohne ihn unstilisiert. In einem Vite- oder Nuxt-Projekt kann man ihn aus der Komponente oder dem Composable importieren, der den Editor erstellt; in einer App mit globalem Stylesheet importiert man ihn stattdessen einmal dorthin.

Was die Integration benötigt

  • Ein DOM-Element für den Canvas, erreichbar über eine Template-Ref
  • grapesjs.init(), der nach diesem existierenden Element aufgerufen wird
  • editor.destroy() wird aufgerufen, wenn die Komponente verschwindet
  • Das GrapesJS-Stylesheet wurde irgendwo geladen
  • Browser-only Ausführung – siehe Abschnitt Nuxt
Schritt 2

Ein Beispiel für ein minimales funktionierendes Vue 3

Kopiere das in eine Komponente und es läuft. Alles nach diesem Abschnitt ist eine Ergänzung, keine Neuschreibung.

VisualEditor.vueVUE
<template>
  <div ref="editorContainer" class="editor-shell"></div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, shallowRef, ref } from 'vue';
import grapesjs, { type Editor } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';

// A template ref: the name matches the ref="" attribute above.
const editorContainer = ref<HTMLDivElement | null>(null);

// shallowRef, not ref — see "Performance" further down the page.
const editor = shallowRef<Editor | null>(null);

onMounted(() => {
  if (!editorContainer.value) return;

  editor.value = grapesjs.init({
    container: editorContainer.value,
    height: '100%',
    fromElement: false,
    storageManager: false,
  });
});

onUnmounted(() => {
  editor.value?.destroy();
  editor.value = null;
});
</script>

<style scoped>
.editor-shell {
  height: 100vh;
}
</style>

Drei Dinge, die es wert sind, zu bemerken

  1. Der Template-Referenzname entspricht dem Attribut ref="" – so bindet Vue sie in <script setup>.

  2. Der Editor lebt in shallowRef, nicht in ref. Vue würde sonst den gesamten Editor-Objektgraphen laufen lassen, was ihn reaktiv macht.

  3. fromElement ist falsch, daher beginnt GrapesJS mit den Komponenten, die du weitergibst, und nicht mit dem Markup, das im Container war.

Lebenszyklus

GrapesJS mit dem Vue 3 Composition API

Die gesamte Integration ist eine Lebenszyklus-Kartierung. Vue zeigt an, wann der DOM-Knoten existiert und wann er kurz davor ist zu verschwinden; GrapesJS benötigt genau diese beiden Momente.

VueGrapesJS
onMounted()
grapesjs.init()
Das Containerelement existiert jetzt und nur jetzt. Eine frühere Initialisierung ergibt GrapesJS einen Nullcontainer.
onUnmounted()
editor.destroy()
Entfernt Listener, das Canvas-iframe und den Editor-DOM. Das Überspringen von Listen leakt bei jeder Routenänderung.
ref()
Behälterelement
Eine Vorlagenreferenz ist der Griff, an dem GrapesJS montiert ist.
shallowRef()
Editor-Instanz
Hält die Instanz, ohne dass sie stark reaktiv wird.

Lies es von oben bis unten, das ist der gesamte Vertrag zwischen den beiden Bibliotheken.

Weder onMounted noch onUnmounted laufen auf dem Server, weshalb ein einfaches Vue-SPA nichts Zusätzliches benötigt. Eine servergerenderte App benötigt einen zusätzlichen Schutz – der Abschnitt Nuxt behandelt das.

Wiederverwendbar

Erstellen Sie ein wiederverwendbares useGrapesJS Composable

Sobald ein zweiter Bildschirm einen Editor braucht, verschiebe den Lebenszyklus in ein Composable. Die Komponente sagt dann, was sie will, nicht wie der Editor verdrahtet ist.

useGrapesJS.tsTS
// composables/useGrapesJS.ts
import { onMounted, onUnmounted, shallowRef, type Ref } from 'vue';
import grapesjs, { type Editor, type EditorConfig } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';

type EditorOptions = Omit<EditorConfig, 'container'>;

export function useGrapesJS(
  container: Ref<HTMLElement | null>,
  options: EditorOptions = {},
) {
  const editor = shallowRef<Editor | null>(null);

  const init = (): Editor | undefined => {
    if (editor.value || !container.value) return;

    editor.value = grapesjs.init({
      container: container.value,
      height: '100%',
      fromElement: false,
      storageManager: false,
      ...options,
    });

    return editor.value;
  };

  const destroy = (): void => {
    editor.value?.destroy();
    editor.value = null;
  };

  onMounted(init);
  onUnmounted(destroy);

  return { editor, init, destroy };
}

Sie nutzen

EditorScreen.vueVUE
<template>
  <div ref="editorContainer" class="editor-shell"></div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useGrapesJS } from '~/composables/useGrapesJS';

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

const { editor } = useGrapesJS(editorContainer, {
  blockManager: {
    blocks: [
      {
        id: 'hero',
        label: 'Hero',
        category: 'Sections',
        content: '<section>…</section>',
      },
    ],
  },
});
</script>

Was dir das Composable einbringt

  • Eine Integration zu warten, statt einer pro Bildschirm
  • Konfiguration an einem einzigen Ort
  • Editor-Setup, das eigenständig getestet werden kann
  • Mehrere Editoren in einer App ohne Copy-Paste
  • Ereignisbehandlung, die über Komponenten hinweg geteilt wird
  • Bauteile, die als Vue lesen, nicht als DOM-Sanitäranlagen

Widerstehe es, das weiter auszubauen, als nötig. Ein Composable, das jedes GrapesJS-Modul in eine reaktive Fassade umhüllt, ist eine zweite API zum Lernen und eine zweite Sache, die man synchron halten muss.

Reaktivität

Verbindung von GrapesJS-Ereignissen mit Vue

GrapesJS verwaltet den Editor-Zustand. Vue verwaltet den Anwendungszustand. Ereignisse sind die Naht: Abonniere die wenigen, die deine Benutzeroberfläche tatsächlich widerspiegelt, und schreibe sie in gewöhnliche Referenzen.

editor-events.tsTS
import { onMounted, ref, shallowRef } from 'vue';
import type { Editor, Component } from 'grapesjs';

const isReady = ref(false);
const isDirty = ref(false);
const saveState = ref<'idle' | 'saving' | 'saved' | 'error'>('idle');
const selectedName = ref<string | null>(null);

function bindEditorEvents(editor: Editor): void {
  editor.on('load', () => {
    isReady.value = true;
  });

  editor.on('component:selected', (component: Component) => {
    selectedName.value = component?.getName?.() ?? null;
  });

  editor.on('component:update', () => {
    isDirty.value = true;
  });

  editor.on('storage:start:store', () => {
    saveState.value = 'saving';
  });

  editor.on('storage:end:store', () => {
    saveState.value = 'saved';
    isDirty.value = false;
  });

  editor.on('storage:error', () => {
    saveState.value = 'error';
  });
}
EventWas deine Benutzeroberfläche damit macht
loadBlende den Ladezustand aus, sobald das Projekt im Canvas steht
component:selectedZeigen Sie, welches Element in Ihrer eigenen Werkzeugleiste ausgewählt ist
component:updateMarkiere das Dokument als verschmutzt, aktiviere die Speichern-Schaltfläche
storage:start:storeZeigen Sie eine Speicheranzeige
storage:end:storeZeigt gerettet, räumt die schmutzige Flagge weg
storage:errorDecke einen Fehler auf, auf den der Nutzer reagieren kann

Spiegele das, was du anzeigst, nicht das, was der Editor enthält. Das Kopieren des Komponentenbaums in einen Vue-Store liefert dir zwei Quellen der Wahrheit und einen Synchronisationsfehler.

Nuxt & SSR

Verwendung von GrapesJS mit Nuxt

GrapesJS basiert auf Browser-DOM-APIs, daher sollte die Editor-Initialisierung nur im Browserkontext erfolgen. In Nuxt bedeutet das, den Editor aus dem Server-Rendering fernzuhalten – alles andere ist die gleiche Integration, die du bereits hast.

pages/editor.vueVUE
<!-- pages/editor.vue -->
<template>
  <ClientOnly>
    <VisualEditor />

    <template #fallback>
      <p class="editor-placeholder">Loading the editor…</p>
    </template>
  </ClientOnly>
</template>
components/VisualEditor.client.vueVUE
<!-- components/VisualEditor.client.vue -->
<template>
  <div ref="editorContainer" class="editor-shell"></div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useGrapesJS } from '~/composables/useGrapesJS';

// Reached only in the browser: the .client suffix keeps this
// component out of the server render, and onMounted never runs
// on the server anyway.
const editorContainer = ref<HTMLElement | null>(null);
const { editor } = useGrapesJS(editorContainer);
</script>

Zwei richtige Optionen

<ClientOnly>

Wickle den Editor dort, wo er verwendet wird. Der Rückfall-Slot gibt dem Server etwas zum Rendern, sodass kein leerer Frame vor der Hydration vorhanden ist.

Eine .client-Komponente

Die eigene Benennungskonvention von Nuxt: Eine Komponente, deren Dateiname auf .client endet, wird nur im Browser dargestellt. Nützlich, wenn der Editor an mehreren Stellen verwendet wird.

Beides ist gültig und kombiniert sich. Keines von beiden ist von GrapesJS vorgeschrieben – was GrapesJS verlangt, ist einfach, dass init() dort läuft, wo das Dokument existiert.

Architektur

Wo die Grenze verläuft

SSR rendert die Anwendungsshell. GrapesJS läuft im Browser. Die Benennung dieser Grenze macht eine Nuxt-Integration vorhersehbar, statt eine Quelle für Hydrationsfehler.

  1. Nuxt-Anwendung
  2. SSR / Anwendungsshell
  3. Client-exklusiver visueller Editor
  4. GrapesJS
  5. API / CMS / Datenbank

Der Editor-Bildschirm ist keine Seite, die man für SEO serverrendert – es ist ein authentifiziertes Werkzeug. Die erstellten Seiten sind das, was man rendert und indexiert, und das sind reines HTML und CSS.

Baue einen kompletten Vue-Seitenbauer
Entscheidung

Brauchst du einen Vue-Wrapper für GrapesJS?

Nein. Direkte Integration ist eine vollständige, unterstützte Methode zur Nutzung von GrapesJS, und genau das tun die Beispiele auf dieser Seite. Ein Wrapper ist eine Bequemlichkeit, keine Voraussetzung.

HerangehensweiseAm besten fürKompromiss
Direkter GrapesJSMaximale KontrolleMan schreibt den Lebenszyklus selbst – etwa fünfzehn Zeilen.
Vue-Wrapper / IntegrationEine stärker auf Vue ausgerichtete APIEine Abhängigkeit zwischen dir und der Editor-API vom Veröffentlichungsplan einer anderen Person.
Eigenes ComposableIntegration wiederverwendbarer AnwendungenDeine Pflege – aber es ist die oben gezeigte Datei, und sie wird nicht veraltet.

Was tatsächlich veröffentlicht wird

Es lohnt sich, vor der Einführung etwas zu überprüfen, denn die Suchergebnisse für diese Frage sind älter als die beschriebenen Pakete.

Offizieller React-Wrapper
@grapesjs/react 2.0.0, MIT, veröffentlicht von den GrapesJS-Maintainern.
Offizieller Vue-Wrapper
Keine. Das GrapesJS-Projekt veröffentlicht kein Vue-Paket.
Community-Vue-Paket
vue-grapesjs 0.1.0 ist ein Drittprojekt, zuletzt veröffentlicht als 2022-05-23, mit Peer-Bereichen vue@^2.6.6 und grapesjs@^0.14.55 — Vue 2 und einem deutlich älteren GrapesJS.

Habe es mit dem npm-Register bei 2026-09-02 abgeglichen. Wenn du ein neueres Vue-Paket findest, lies zuerst dessen peerDependencies: Dieses einzelne Feld zeigt an, ob es Vue 3 und ein aktuelles GrapesJS anvisiert.

Für Vue 3 ist heute das Composable oben der Wrapper. Es umfasst gut zwanzig Zeilen, nutzt die GrapesJS-API direkt und kann keinem Release hinterherhinken, von dem du abhängst.

Über die Integration hinaus

Baue einen Vue Page Builder mit GrapesJS

Das Mounten des Editors ist der erste Nachmittag. Ein Seitenbauer, dem deine Nutzer vertrauen, ist der Rest der Arbeit, und es ist hauptsächlich die Konfiguration der Module, die GrapesJS bereits offenlegt.

  • Canvas

    Die editierbare Oberfläche und ihre Gerätebreiten.

  • Components

    Die Typen, die deine Nutzer einordnen können, und deren Eigenschaften.

  • Blocks

    Die Palette, von der sie ziehen.

  • Style Manager

    Welche CSS-Eigenschaften sind offen und wem?

  • Asset Manager

    Bilder und Medien aus deinem Lager.

  • Storage Manager

    Wo Projektdaten geladen und gespeichert werden.

  • Commands

    Benannte Aktionen, die an deine eigene Benutzeroberfläche gebunden werden können.

  • Device Manager

    Reaktionsschnelle Breakpoints für Bearbeitung und Ausgabe.

  • Plugins

    Alles oben ist verpackt und wiederverwendbar.

Lerne, wie man einen kompletten Vue-Seitengenerator baut
Was du bauen kannst

Was kann man mit GrapesJS und Vue bauen?

Derselbe Editor-Core, anders konfiguriert. Jeder dieser Blöcke ist ein anderer Satz von Blöcken, ein anderes Speicherziel und ein anderer Veröffentlichungsschritt.

Ausgabe

Was speichert und generiert GrapesJS?

Drei Dinge, die leicht zu vermischen und teuer zu vermischen sind. Das am ersten Tag richtig zu machen, macht ein Dokument auch ein Jahr später wieder bearbeitbar.

Projektdaten

Der editierbare Zustand des GrapesJS-Projekts – Seiten, Komponenten, Stile, Assets. Lies es mit editor.getProjectData(), stelle es mit editor.loadProjectData() wieder her. Das ist das, was man erhalten muss.

HTML

Das gerenderte Markup, von editor.getHtml(). Generiere es jedes Mal, wenn du veröffentlichst. Es ist Ausgabe, kein Quellcode.

CSS

Die Stile, die der Editor erstellt hat, stammen aus editor.getCss(). Gleiche Regel: generiert, nicht als Wahrheitsquelle gespeichert.

  1. User edits
  2. GrapesJS project data
  3. Your API / database
  4. HTML + CSS
  5. Preview / publish

Speichere editierbare Projektdaten. Generiere HTML und CSS, wenn du rendern oder veröffentlichen musst.

Nur das gerenderte HTML zu speichern, ist ein Fehler, der später nicht mehr rückgängig gemacht werden kann. Man kann HTML immer aus Projektdaten regenerieren; man kann Projektdaten aus HTML nicht zuverlässig wiederherstellen.

publish.tsTS
// Editable state — store this, it is what the editor reloads.
const projectData = editor.getProjectData();

// Rendered output — regenerate this whenever you publish.
const html = editor.getHtml();
const css = editor.getCss();

await fetch(`/api/projects/${projectId}/publish`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ projectData, html, css }),
});

// Sanitize `html` on the server before it is served to anyone.
Persistenz

Speichere GrapesJS-Projekte in deiner Vue-Anwendung

GrapesJS ist egal, was dein Backend ist. Ein Speicheradapter besteht aus zwei asynchronen Funktionen – eine, die Projektdaten zurückgibt, eine, die sie akzeptiert – sodass der Editor mit der bereits vorhandenen API kommuniziert.

  1. Vue
  2. GrapesJS storage
  3. REST API
  4. Backend
  5. Database
storage.tsTS
import grapesjs, { type ProjectData } from 'grapesjs';

// Wherever your app keeps it — a route param, a prop, a store.
const projectId = props.projectId;

const editor = grapesjs.init({
  container: editorContainer.value!,
  fromElement: false,
  storageManager: {
    type: 'app-api',
    autosave: true,
    stepsBeforeSave: 10,
  },
  // Registered as a plugin so the adapter exists before
  // GrapesJS performs its first load.
  plugins: [
    (ed) => {
      ed.Storage.add('app-api', {
        async load(): Promise<ProjectData> {
          const res = await fetch(`/api/projects/${projectId}`);
          if (!res.ok) {
            throw new Error(`Load failed: ${res.status}`);
          }
          return await res.json();
        },

        async store(data: ProjectData) {
          const res = await fetch(`/api/projects/${projectId}`, {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ projectData: data }),
          });
          if (!res.ok) {
            throw new Error(`Save failed: ${res.status}`);
          }
        },
      });
    },
  ],
});

Was der Adapter abdeckt

load()
Hol das Projekt, wenn der Editor geöffnet wird.
store()
Senden Sie Projektdaten an Ihren Endpunkt.
autosave
Feuert nach einer festgelegten Anzahl von Änderungen, über stepsBeforeSave.
Project JSON
Der serialisierte Zustand – das, was du versiegelst.
Versioning
Behalten Sie vorherige Payloads serverseitig, um Rollback zu unterstützen.
Publishing
Ein separater Endpunkt, der die Ausgabe rendert und bereinigt.

Die Registrierung des Adapters über das Plugin-Array ist wichtig: Es garantiert, dass der Speicher existiert, bevor GrapesJS erstmals geladen wird.

Medien

Assets in deiner Vue-Anwendung verwalten

Der Asset Manager ist eine Benutzeroberfläche über einem Endpunkt. Zeigt man ihn auf seinen eigenen und jede bestehende Regel – Authentifizierung, Validierung, Quoten, CDN – gilt weiterhin.

assets.tsTS
// Fetched from your own API before the editor is created.
const assets = await fetch('/api/assets').then((res) => res.json());

const editor = grapesjs.init({
  container: editorContainer.value!,
  assetManager: {
    assets,

    // Uploads go to your endpoint, with your auth and
    // your validation.
    upload: '/api/assets',
    uploadName: 'files',
    multiUpload: true,
    autoAdd: true,
    headers: { Authorization: `Bearer ${token.value}` },
    credentials: 'same-origin',

    // Reject what the backend would reject anyway,
    // before the round trip.
    beforeUpload: (files: File[]) => {
      const limit = 5 * 1024 * 1024;
      const tooBig = files.some((f) => f.size > limit);
      if (tooBig) {
        toast.error('Images must be under 5 MB');
        return false;
      }
    },
  },
});
upload
Dein Endpunkt; uploadName ist das Formularfeld, auf das es postet.
assets
Setze den Manager mit URLs, die deine API bereits kennt.
headers / credentials
Mit jedem Upload gesendet, sodass deine bestehende Authentifizierung weiterhin angewendet wird.
beforeUpload
Lehnt clientseitige Ablehnung ab; dein Server validiert trotzdem.
Storage & CDN
GrapesJS sieht nie, wo die Bytes landen – es speichert die zurückgegebene URL.
Asset URLs
Was schließlich im veröffentlichten HTML landet, dient ihnen aus einem dauerhaften Ursprung.
Dein Wortschatz

Erstellen Sie benutzerdefinierte GrapesJS-Komponenten für Vue-Anwendungen

Ein benutzerdefinierter Komponententyp ist der Weg, wie der Editor dein Produkt lernt. Er bekommt ein eigenes Einstellungspanel, eigene Drop-Regeln und einen eigenen Block in der Palette.

pricing-card.tsTS
import type { Editor } from 'grapesjs';

export function pricingCardPlugin(editor: Editor): void {
  editor.Components.addType('pricing-card', {
    isComponent: (el) => el.dataset?.gjsType === 'pricing-card',
    model: {
      defaults: {
        tagName: 'section',
        attributes: { 'data-gjs-type': 'pricing-card' },
        // Traits become the settings panel for this component.
        traits: [
          { type: 'text', name: 'plan', label: 'Plan name' },
          { type: 'text', name: 'price', label: 'Price' },
          { type: 'checkbox', name: 'featured', label: 'Featured' },
        ],
        components: `
          <h3 data-gjs-type="text">Starter</h3>
          <p data-gjs-type="text">$0 / month</p>
          <a href="#">Choose plan</a>
        `,
      },
    },
  });

  editor.Blocks.add('pricing-card', {
    label: 'Pricing card',
    category: 'Marketing',
    content: { type: 'pricing-card' },
  });
}

// Pass it to the editor like any other plugin:
// grapesjs.init({ container, plugins: [pricingCardPlugin] })

Typische erste fünf

  • Hero
  • Pricing card
  • Product card
  • Form
  • Navigation

Benutzerdefinierte Komponenten sind auch, wie du den Editor einschränkst. Das Setzen von Dropable oder Draggable auf einem Typ verhindert, dass ein Nutzer eine Preiskarte in einer Navigationsleiste ablegt, und Traits geben ihm ein beschriftetes Feld statt einer rohen CSS-Kontrolle.

Das sind GrapesJS-Komponententypen, keine Vue-Komponenten. Der Canvas rendert DOM; deine Vue-Komponenten rendern deine Anwendung darum herum.

Ökosystem

Erweitern Sie Ihren Vue-Editor mit GrapesJS-Plugins

Ein Plugin ist eine Funktion, die den Editor empfängt – dieselbe Funktionssignatur, egal ob sie von npm, GJS.Market oder deinem eigenen Repository stammt. Keiner von ihnen interessiert sich dafür, dass die Host-Anwendung Vue ist.

plugins.tsTS
import grapesjs from 'grapesjs';
import basicBlocks from 'grapesjs-blocks-basic';
import { pricingCardPlugin } from '~/editor/pricing-card';

const editor = grapesjs.init({
  container: editorContainer.value!,
  plugins: [
    // Options go through a wrapper function: `pluginsOpts`
    // is keyed by string, so it only reaches plugins that
    // were passed to `plugins` by name.
    (ed) => basicBlocks(ed, { flexGrid: true }),
    pricingCardPlugin,
  ],
});

Bauen vs. übernehmen

Den visuellen Editor selbst bauen oder GrapesJS verwenden?

Kein Argument, dass Bauen falsch ist – sondern eine Bestandsaufnahme dessen, was Bauen bedeutet. Jede Reihe ist ein Subsystem, das existiert, egal ob man es geplant hat oder nicht.

LeistungsfähigkeitBau dich selbst aufGrapesJS
CanvasBauEnthalten
Drag & dropBauEnthalten
ComponentsBauEnthalten
BlocksBauEnthalten
Style ManagerBauEnthalten
Asset ManagerBauErweiterbar
Storage ManagerBauErweiterbar
PluginsBaue ein Ökosystem aufPlugin-Architektur
Vue integrationNativFramework-agnostisch

Vue gibt dir das Anwendungs-Framework. GrapesJS gibt dir die visuelle Bearbeitungs-Engine.

Warum baust du den Editor nicht komplett mit Vue-Komponenten?

Denn Vue-Komponenten sind Anwendungsbausteine, und ein visueller Editor braucht noch etwas anderes: Canvas-Management, einen Komponentenbaum mit Drop-Regeln, Auswahl- und Hover-Zustand, eine Style-Schicht, die echtes CSS schreibt, Geräteswitching, Rückgängig machen und neu machen, Asset-Management, Serialisierung, benannte Befehle und einen Erweiterungspunkt für das Ganze. Das kannst du in Vue bauen – es ist einfach ein anderes Projekt als das, das du dir vorgenommen hast.

Vue + GrapesJS sind ein anderes Konzept als allein Vue-Komponenten.

In Produktion

Produktionsarchitektur für GrapesJS + Vue

Wie der Editor in einer echten Anwendung sitzt, sobald es Nutzer, Berechtigungen und mehr als ein Projekt gibt.
  1. Vue / Nuxt

    Deine Nuxt- oder Vue-Anwendung: die Shell, die Sitzung und wer welches Projekt öffnen darf.

    • Application UI
    • Authentication
    • Users
    • Permissions
  2. GrapesJS

    Der Editor, montiert auf einem Bildschirm. Er erhält ein Projekt und gibt ein Projekt aus.

    • Canvas
    • Components
    • Blocks
    • Styles
    • Assets
  3. Application API

    Deine eigenen Routen. GrapesJS ruft sie über die von dir geschriebenen Speicher- und Asset-Adapter auf.

  4. Backend

    Wo Projekte, Medien, Nutzer und Versionen tatsächlich existieren – unverändert vom darüberliegenden Editor.

    • Projects
    • Assets
    • Users
    • Versions

Der Editor ist ein Blatt in diesem Baum, nicht die Wurzel. Alles darüber ist Code, den du sowieso geschrieben hättest.

Leistung

Leistungsüberlegungen

  • Mach den Editor nicht tief reaktiv

    Das ist der, der tatsächlich beißt. shallowRef oder eine einfache modulbezogene Variable – niemals ref() um die Editor-Instanz herum. Vue würde einen sehr großen Objektgraphen laufen lassen und Effekte auf internen Churn erneut ausführen.

  • Initialisieren nur bei Bedarf

    Erstelle den Editor auf dem Bildschirm, der bearbeitet, nicht in einem Layout oder einem Store, den jede Route mountet.

  • Lazy-Load den Editor

    GrapesJS ist ein umfangreiches Bundle. Lade es in einem eigenen asynchronen Abschnitt, damit Routen, die nie bearbeiten, nie dafür bezahlen.

  • Halte Updates aus dem globalen Zustand heraus

    Das Pushen jedes component:update in einen Store verwandelt jeden Tastendruck in ein anwendungsweites Rendering.

  • Paginate große Asset-Sammlungen

    Seeden Sie den Asset-Manager von einem paged-Endpunkt aus, anstatt Tausende von URLs in den Editor zu schicken.

  • Halte die Komponentenbäume handhabbar

    Sehr tiefgründige Dokumente kosten mehr zum Rendern, Serialisieren und Differenzieren. Struktur fördert sich selbst, wenn deine Blöcke das tun.

Sicherheit

Sicherheitsaspekte

Ein visueller Editor ist ein System, das vom Nutzer erstelltes HTML akzeptiert. Behandeln Sie es so.

Veröffentlichtes HTML bereinigen
Desinfizieren Sie auf dem Server zur Veröffentlichungszeit, bevor einem Besucher etwas serviert wird.
Uploads validieren
Typ, Größe und Inhalt – Kundenseitenkontrollen sind UX, keine Durchsetzung.
Speicherendpunkte authentifizieren
Laden und speichern sind gewöhnliche API-Routen und benötigen eine gewöhnliche Authentifizierung.
Erzwingen von Berechtigungen serverseitig
Das Ausblenden eines Panels im Editor ist kein Autorisierungsmodell.
Projektdaten validieren
Es kommt von einem Kunden und kann alles sein. Überprüfe es, bevor du es lagerst.
Vertraue niemals dem Editor-Status
Alles, was der Browser über das Editierte sendet, ist eine Behauptung, keine Tatsache.
Schützen Sie Veröffentlichungs-Endpunkte
Die Veröffentlichung verändert, was die Öffentlichkeit sieht; Preisbegrenzung und Genehmigung entsprechend.
Fehlerbehebung

Häufige Fehler bei GrapesJS + Vue

Fast jedes Integrationsproblem, das für diese Kombination gemeldet wurde, gehört zu diesen sieben.

Initialisierung vor der Montage

Symptom

Der Container ist null oder der Editor rendert ins Nichts.

Fix

Erstelle den Editor innerhalb von onMounted(). Die Vorlagenreferenz hat vorher kein Element.

Das Aufräumen vergessen

Symptom

Das Gedächtnis wächst und abgestandene Zuhörer feuern nach dem Verlassen der Route.

Fix

Ruf editor.destroy() in onUnmounted() an und lösche die Referenz.

Den gesamten Editor tief reaktiv machen

Symptom

Der Editor wirkt träge; Vue-Devtools stocken.

Fix

Halte die Instanz in shallowRef oder komplett außerhalb der Vue-Reaktivität.

Initialisierung von GrapesJS während SSR

Symptom

Das Dokument ist nicht definiert oder es gibt eine Flüssigkeitsminderung auf dem Editor-Weg.

Fix

Rendere den Editor nur als Client – <ClientOnly>, eine .client-Komponente oder beides.

Editor-Zustand mit Anwendungszustand mischen

Symptom

Zwei Quellen der Wahrheit und Bearbeitungen, die bei der Navigation verschwinden.

Fix

Lass GrapesJS das Projekt übernehmen; spiegele nur die wenigen Werte, die deine Benutzeroberfläche anzeigt.

Den CSS-Import vergessen

Symptom

Der Editor lädt, aber die Panels sind ungestaltet und unbrauchbar.

Fix

Importiere Grapesjs/dist/css/grapes.min.css oder nimm sie in dein globales Stylesheet auf.

Kopieren veralteter Wrapper-Beispiele

Symptom

Typfehler oder eine Integration, die auf Vue 2 Lebenszyklus-Hooks basiert.

Fix

Überprüfen Sie peerDependencies, bevor Sie einen Wrapper verwenden. Mehrere populäre Beispiele stammen aus der Zeit vor Vue 3.

Bei Vue 2 verwendet dieselbe Integration mounted() und beforeDestroy() anstelle von onMounted() und onUnmounted(); die GrapesJS-Seite bleibt unverändert. Neue Arbeiten sollten Vue 3 anvisieren – alles auf dieser Seite geht davon aus.

Bevor du verschiffst

Vue + GrapesJS Produktionscheckliste

Die Reihenfolge entspricht ungefähr der Reihenfolge, die diese Seite eingeführt hat.

  1. GrapesJS installieren
  2. Initialisieren nach der Halterung
  3. Zerstören beim Absteigen
  4. Importiere das GrapesJS CSS
  5. SSR / Client-only Ausführung übernehmen
  6. Entscheide dich über direkte Integration vs. Wrapper
  7. Erstelle ein wiederverwendbares Composable, wo es nützlich ist
  8. Verbinden Sie die Editor-Events, die Ihre Benutzeroberfläche widerspiegelt
  9. Speicher konfigurieren
  10. Assets konfigurieren
  11. Fügen Sie benutzerdefinierte Komponenten hinzu
  12. Füge die Plugins hinzu, die dein Produkt benötigt
  13. Berechtigungen serverseitig implementieren
  14. Veröffentlichte Inhalte säubern
  15. Test-responsives Schneiden
  16. Teste die Produktionsversion
FAQ

GrapesJS und Vue: Häufig gestellte Fragen

Kann ich GrapesJS mit Vue 3 verwenden?

Ja. GrapesJS ist eine framework-agnostische Bibliothek, die in ein DOM-Element rendert, also funktioniert es in Vue 3 ohne Adapter. Initialisiere es in onMounted() und zerstöre es in onUnmounted().

Wie installiere ich GrapesJS in Vue?

Führe npm Install Grapesjs aus. Das Paket enthält eigene TypeScript-Definitionen. Du musst auch das Stylesheet laden, entweder indem du grapesjs/dist/css/grapes.min.css importierst oder es in deinen globalen CSS einbaust.

Wie initialisiere ich GrapesJS in Vue 3?

Erstellen Sie eine Template-Ref auf dem Container-Element und rufen Sie dann grapesjs.init({ container: containerRef.value }) innerhalb von onMounted() auf. Das Element existiert vor dem Mount nicht, daher gibt eine frühere Initialisierung GrapesJS nichts zum Rendern.

Kann ich GrapesJS mit dem Composition API verwenden?

Ja, und es ist der empfohlene Weg. onMounted() und onUnmounted() werden direkt auf grapesjs.init() und editor.destroy() abgebildet, und die gesamte Integration passt in ein einziges Composable.

Kann ich GrapesJS mit <script setup> verwenden?

Ja. Jedes Beispiel auf dieser Seite verwendet <script setup lang="ts">. Eine mit ref() deklarierte Vorlagenreferenz bindet automatisch das passende Attribut ref="".

Funktioniert GrapesJS mit Nuxt?

Ja. Die Integration ist identisch mit dem einfachen Vue 3; die einzige Neuerung ist, dass der Editor mit <ClientOnly> oder einer .Client-Komponente aus dem Server-Rendering herausgehalten wird.

Funktioniert GrapesJS mit Nuxt SSR?

Ja, mit dem Editor, der nur clientbasiert gerendert wird. GrapesJS benötigt Browser-DOM-APIs, daher kann es während eines Serverrenderings nicht laufen – aber die Seiten, die es erzeugt, sind einfaches HTML und CSS, und genau diese sind das, was man serverrendert und indexiert.

Brauche ich einen Vue-Wrapper für GrapesJS?

Nein. Direkte Integration ist ein vollständiger Ansatz und genau das, was die hier genannten Beispiele verwenden. GrapesJS veröffentlicht einen offiziellen React-Wrapper, aber kein Vue-Äquivalent, sodass jeder Vue-Wrapper auf npm ein Community-Projekt ist – überprüfen Sie vor der Einführung dessen Vue- und GrapesJS-Peer-Bereiche.

Kann ich GrapesJS mit TypeScript verwenden?

Ja. GrapesJS liefert TypeScript-Definitionen im Paket, sodass der Editor-Typ und das Konfigurationsobjekt ohne zusätzliche @types Abhängigkeit getypt werden.

Kann ich GrapesJS-Projekte in meinem Vue-Backend speichern?

Ja. Registriere einen Speicheradapter mit editor.Storage.add(), der load() und store() implementiert. Beides sind gewöhnliche asynchrone Funktionen, sodass sie jede bereits vorhandene API aufrufen können.

Kann ich benutzerdefinierte Komponenten mit GrapesJS erstellen?

Ja. editor.Components.addType() definiert einen Komponententyp mit eigenen Eigenschaften und Drop-Regeln, und editor.Blocks.add() fügt ihn in die Palette ein. So lernt der Editor den Wortschatz deines Produkts.

Kann ich GrapesJS-Plugins mit Vue verwenden?

Ja. Ein GrapesJS-Plugin ist eine Funktion, die die Editor-Instanz empfängt und daher vom Framework, das es hostet, nicht beeinflusst wird. Gib Plugins im Plugins-Array von grapesjs.init() weiter.

Kann ich mit GrapesJS einen Vue-Seitengenerator erstellen?

Ja – das ist der häufige Fall. Das Einbinden des Editors ist der kurze Teil; der Rest besteht darin, Blöcke, Speicher, Assets und Berechtigungen darum herum zu konfigurieren.

Baue deinen Vue Visual Editor mit GrapesJS

Integrieren Sie die visuelle Bearbeitungs-Engine in Ihre Vue- oder Nuxt-Anwendung, behalten Sie die Kontrolle über Ihre Daten und Ausgaben und erweitern Sie den Editor um die Plugins, die Ihr Produkt benötigt.

Baue deine Anwendung mit Vue 3. Füge visuelle Bearbeitung mit GrapesJS hinzu.

Lesen Sie weiter

Verwandte Leitfäden