How to reuse your Trix WYSIWYG editor with Vue?
Tags: vue, javascript, trix
Published: 2020-02-13 08:13:40

---
title: How to reuse your Trix WYSIWYG editor with Vue?
published: true
description: How  to reuse the Trix editor with VueJS
tags: vue, javascript, trix
---
When adding a WYSIWYG editor to your site, have you considered:

1) Which library to use?
2) How to implement one?
3) What if I have more than 2 editors I have to add?
4) Could I make them reusable?

*Yes you can.*

Here I am using the [Trix](https://trix-editor.org/) editor from [Basecamp](https://basecamp.com/).

Have a look at the doc and install the library before getting started! 

Before making it reusable, let's quickly set the editor up first.

##Getting Started

First, let's add the editor tag like what the doc has mentioned: 

```vue
<template>
   <div>
       <input id="x" type="hidden" name="content">
       <trix-editor input="x"></trix-editor>
   </div>
</template>
```
Now you've got a nice editor. But it would be great to store the text you've typed in somewhere. Let's create a two-way binding on the form input:

```vue
<template>
   <div>
       <input id="x" type="hidden" name="content" v-model="trixText"> <!-- new code here -->
       <trix-editor input="x"></trix-editor>
   </div>
</template>

<script>
import Trix from 'trix';
export default {
   data() {
      return {
          trixText: '' // new code here
      }
   }
}
</script>
```

## Listen to the changes on the Trix editor

From the doc:

>The editor emits several events which you can use to observe and respond to changes in editor state.
More of that can be found [here](https://github.com/basecamp/trix#observing-editor-changes).

Here we will be using the `trix-change` listener.

```vue
<template>
   <div>
       <input id="x" type="hidden" name="content" v-model="trixText">>
       <trix-editor input="x"></trix-editor>
   </div>
</template>

<script>
export default {
   data() {
      return {
          trixText: ''
      }
   },
   methods: {
       setTextToTrix: function() {
           this.trixText = document.getElementById("x").value; 
       }
   }
   mounted() {
       document.addEventListener("trix-change", this.setTextToTrix); // Listen to the changes on the editor
   }
}
</script>
```
And remove the event listener once done. 

```vue
<!-- TrixComponent.vue -->
<script>
export default {
 ..
  mounted() {
    document.addEventListener("trix-change", this.setTextToTrix);
  },
  beforeDestroy: function() {
    document.removeEventListener("trix-change", this.setTextToTrix); // New code here
  }
};
</script>

```

### Make it reusable
So now you've got your basic editor set up! It's time to make it reusable.

The secret to make the trix-editor reusable:

>The `id` on the tags
```vue
<input id="x" type="hidden" name="content" v-model="trixBody"> <!-- notice the id? -->
<trix-editor ref="trix" input="x"></trix-editor> <!-- notice the id? -->
```
That means we can create a unique `id` for each component that is using `TrixComponent.vue`.

To demonstrate this, let's have 2 components: `ComponentA.vue` and `ComponentB.vue` using the same editor that you just created. 

And let's work on `ComponentA.vue` first.

```vue
<!-- ComponentA.vue -->

<template>
  <div class="component-a">
    <h3>Component A</h3>
    <h6>
      Text:
      <span v-html="textA"></span> <!-- Data received will be in HTML format -->
    </h6>
    <TrixComponent></TrixComponent> <!-- TrixComponent -->
  </div>
</template>

<script>
import TrixComponent from "./TrixComponent";
export default {
  components: {
    TrixComponent
  },
  data() {
    return {
      textA: "",
    };
  },
  methods: {
  }
};
</script>
```
We can pass the id as props from `ComponentA.vue` to `TrixComponent.vue`.

```vue
<!-- ComponentA.vue -->
<template>
  <div class="component-a">
    <h3>Component A</h3>
    <h6>
      Text:
      <span v-html="textA"></span>
    </h6>
    <TrixComponent :id="id"></TrixComponent> <!-- pass the id here -->
  </div>
</template>

<script>
import TrixComponent from "./TrixComponent";
export default {
  components: {
    TrixComponent
  },
  data() {
    return {
      id: "A" // Here we have an id 'A'
    };
  },
  methods: {
  }
};
</script>
```
And we can assign the `props(id)` to the the input & the trix-editor.
```vue
<!-- TrixComponent.vue -->
<template>
  <div>
    <input :id="id" type="hidden" name="content" v-model="trixText"> <!-- Set the id according to the props -->
    <trix-editor :input="id"></trix-editor> <!-- Set the id according to the props --> 
  </div>
</template>

<script>
export default {
  props: ["id"], // Receive the id from the parent component
  data() {
    return {
      trixText: ""
    };
  },
  methods: {
    setTextToTrix(e) {
      this.trixText = document.getElementById(this.id).value; // REMEMBER TO UPDATE THE ID HERE TOO!
    },
  },
  mounted() {
    document.addEventListener("trix-change", this.setTextToTrix);
  },
  beforeDestroy: function() {
    document.removeEventListener("trix-change", this.setTextToTrix);
  },
};
</script>

```

## Getting data back from `TrixComponent.vue`
We will emit the data back from `TrixComponent.vue` to its parent component, which is `ComponentA.vue`

```vue
<!-- TrixComponent.vue -->
<template>
  <div>
    <input :id="id" type="hidden" name="content" v-model="trixText">
    <!-- updated here -->
    <trix-editor :input="id"></trix-editor>
  </div>
</template>

<script>
export default {
  props: ["id"],
  data() {
    return {
      trixText: ""
    };
  },
  methods: {
    setTextToTrix(e) {
      this.trixText = document.getElementById(this.id).value;
    },
    emitDataBackToComponent() {
      this.$emit("dataFromTrix", this.trixText); // Emit the data back to the parent component
    }
  },
  mounted() {
    document.addEventListener("trix-change", this.setTextToTrix);
  },
  beforeDestroy: function() {
    document.removeEventListener("trix-change", this.setTextToTrix);
  },
  updated() {
    this.emitDataBackToComponent(); // Fire the event whenever there's an update
  }
};
</script>

```

And `ComponentA.vue` will then be able to receive the data from `TrixComponent.vue`
```vue
<!-- ComponentA.vue -->
<template>
  <div class="component-a">
    <h3>Component A</h3>
    <h6>
      Text:
      <span v-html="textA"></span>
    </h6>
    <TrixComponent :id="id" @dataFromTrix="getDataFromTrix"></TrixComponent> <!-- Receive the data back -->
  </div>
</template>

<script>
import TrixComponent from "./TrixComponent";
export default {
  components: {
    TrixComponent
  },
  data() {
    return {
      textA: "",
      id: "A"
    };
  },
  methods: {
    getDataFromTrix: function(data) {
      this.textA = data; // Assign the data back to the the variable
    }
  }
};
</script>

```

It will be the same logic for `ComponentB.vue`: just pass a different id (maybe `id: 'B'`?) to `TrixComponent.vue`.

That's it! 
You've now created a reusable trix editor :)

Here is the [code example](https://codesandbox.io/s/nifty-shannon-d6l8b).

Happy coding 😊