WYSIWYG mit Nuxt und TypeScript

Auf der Suche nach einem WYSIWYG Editor für vue.js stößt man sehr schnell und sehr häufig auf TipTap. Eine Implementierung in vue.js mit JavaScript ist sehr einfach. Allerdings stößt man mit Nuxt und TypeScript auf einige Probleme. Folgende Schritte müssen für die Nutzung erfolgen.

1. Pakete installieren

    "tiptap": "^1.30.0",
    "tiptap-vuetify": "^2.24.0",

2. nuxt.config.js bearbeiten

Dieser Schritt muss natürlich nur bei nuxt erfolgen.

plugins: [{ src: '~/plugins/TiptapVuetify', mode: 'client' }],
  build: {
    transpile: ['vuetify/lib', "tiptap-vuetify"]
  }

3. Das Plugin implementieren

Dieses Plugin nutzt vuetify. Aus der Einfachheit heraus habe ich diese Datei als .js Datei erstellt.

import Vue from 'vue'
import { TiptapVuetifyPlugin } from 'tiptap-vuetify'
import 'tiptap-vuetify/dist/main.css'

export default ({ app }) => {
  Vue.use(TiptapVuetifyPlugin, {
    vuetify: app.vuetify,
    iconsGroup: 'mdi'
  });
};

4. Typedefinitions anlegen

Eine häufige Falle bei Abhängigkeiten und TypeScript sind die fehlenden type Definitions. Diese müssen angelegt werden. Dafür erzeugen wir uns eine neue Datei tiptap-vuetify.d.ts. Diese Beinhaltet die Komponente, alle Extensions und das Plugin.

import Vue from "vue";

export class TiptapVuetifyPlugin {}
export class Underline {}
export class Bold {}
export class Strike {}
export class TiptapVuetify extends Vue {}
export class Italic {}

5. Erzeuge eine extra Komponente für den Editor

Wichtig für nuxt ist, dass diese Klasse mit ClientOnly gewrappt wird. Die Komponente nutzt vue-property-decorator. Eine aus meiner Sicht tolle Erweiterung die Komponenten schöner zu erscheinen.

<template>
  <ClientOnly>
    <tiptap-vuetify :extensions="extensions" :value="value" @input="$emit('input', arguments[0])" />

    <template #placeholder> Loading...</template>
  </ClientOnly>
</template>

<script lang="ts">
import { Prop, Vue } from 'vue-property-decorator'
import Component from 'vue-class-component'
import { Underline, Bold, Italic, Strike, TiptapVuetify } from 'tiptap-vuetify'

@Component({ components: { TiptapVuetify } })
export default class WEditor extends Vue {

  private extensions = [
    Underline,
    Strike,
    Italic,
    Bold
  ];

  @Prop()
  private value!: string
}
</script>

Sofern diese Komponente implementiert wird, kann der Text mit v-model gebunden werden. Das Ergebnis dieses Strings ist ein HTML Code, welcher gut auf der Webseite angezeigt werden kann.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert