How to pass data into quasar tiptap editor from parent component in vuejs?

1.7k views Asked by At

I'm a little confused how to use this as a component in my application. Specifically, I am confused how to properly pass data from my parent component into the <quasar-editor /> from https://github.com/donotebase/quasar-tiptap.

My code below will pass the data from episode.keyLessons in my parent component into the editor. However, when I try and type in the editor, the spacebar key does not register. If the cursor is in the <h1> section at the top and any key is pressed, the cursor immediately jumps down to the <p> section of the editor without me clicking there.

What am I doing wrong?

What I have tried:

Editor.vue

<template>
  <div>
    <quasar-tiptap v-bind="options" @update="onUpdate" />
  </div>
</template>

<script>
import { QuasarTiptap, RecommendedExtensions } from "quasar-tiptap";
import "quasar-tiptap/lib/index.css";

export default {
  name: "Editor",
  props: ['value'],
  data() {
    return {
      options: {
        content: '',
        editable: true,
        extensions: [
          ...RecommendedExtensions
          // other extenstions
          // name string, or custom extension
        ],
        toolbar: [
          "add-more",
          "separator",
          "bold",
          // other toolbar buttons
          // name string
        ]
      },
      json: "",
      html: ""
    };
  },
  components: {
    QuasarTiptap
  },
  methods: {
    onUpdate({ getJSON, getHTML }) {
      this.json = getJSON();
      this.html = getHTML();
      this.$emit('update', this.html)
    }
  },
  watch: {
    value: {
      handler(newVal, oldVal) {
        this.options.content = newVal;
        console.log(`value changed: ${newVal}`);
      },
      immediate: true
    }
  },
  mounted() {
    // set language dynamically
    this.$o.lang.set("en-us");
  }
};
</script>

Parent.vue

<template> 
   <Editor v-model="episode.keyLessons" @update="update" />
</template>

<script>
data: () => ({
   episode: {
      keyLessons: null,
   }
}),
methods: {
   update(value) {
         this.episode.keyLessons = value;
       },
}
</script>
1

There are 1 answers

1
Andreas On BEST ANSWER

When you type something you are also resetting the content and that is probably the cause of the weird behavior. It's best to let tiptap handle the updates and only set the content of tiptap if the content (value) changes from the outside (parent component). In most cases you only want to set the content initially.

Here's how I recommend that you do it:

export default {
  name: "Editor",
  props: ['value'],
  data() {
    return {
      valueChangedFromEditor: false,
      options: {
        content: '',
        editable: true,
        extensions: [
          ...RecommendedExtensions
          // other extenstions
          // name string, or custom extension
        ],
        toolbar: [
          "add-more",
          "separator",
          "bold",
          // other toolbar buttons
          // name string
        ]
      },
      json: "",
      html: ""
    };
  },
  components: {
    QuasarTiptap
  },
  methods: {
    onUpdate({ getJSON, getHTML }) {
      this.valueChangedFromEditor = true;
      this.json = getJSON();
      this.html = getHTML();
      this.$emit('update', this.html)
    }
  },
  watch: {
    value: {
      handler(newVal, oldVal) {
        // Only update if the value changed from parent component.
        if (!this.valueChangedFromEditor) {
          this.options.content = newVal;
          console.log(`value changed: ${newVal}`);
        }
        this.valueChangedFromEditor = false;
      },
      immediate: true
    }
  },
  mounted() {
    // set language dynamically
    this.$o.lang.set("en-us");
  }
};