Creando un Editor Markdown con Vue.JS

Editor markdown con vuejs

Iniciar un proyecto con vue.js es muy fácil. En esta oportunidad vamos a crear un pequeño proyecto donde vamos a crear un Editor Markdown. Cuando vallamos creando nuestro archivo, de un lado vamos a ir vendo el resultado.

Instalación

Aunque podemos iniciar un proyecto súper fácil con el CLI de Vue, en esta oportunidad, vamos a utilizar los CDN, para no requerir ningún programa externo.

Vamos a crear nuestro archivo index.html

<html>
  ...
  <body>
    <div id="app"></div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
    </script>
  </body>
</html>

Importante la instrucción <div id=»app»></div>

Instancia de Vue

Todas las aplicaciónes de Vue comienzan con una instancia. vamos a colocar en nuestra stiqueta <script> lo siguiente:

var vm = new Vue({
  el: '#app',
  data: {}
  // more options
}

Las instancias de Vue reciben como parámetro un objeto donde podemos establecer opciones.

  • el: esta propiedad, indica cual va a ser el elemento html sobre el cual deseamos aplicar la instancia. En nuestro caso el elemento que tiene id=»app»
  • data: hace referencia a datos que podemos utilizar en el DOM y en nuestro script de vue. De manera que cuando hagamos cambios en nuestros datos, se vea reflejado en el DOM.

Existen otras propiedades (opciones) que podemos implementar que por su puesto vamos a ver más adelante.

Creando el proyecto

Vamos a darle inicio al proyecto, pero antes necesitaremos algunas cositas.

Implementando librerías

Necesitamos implementar algunas librerías que permiten que la magía sea. Vamos a colocar los siguientes CDN al final de la etiqueta </body>, puede ser antes o después de nuestro CDN de Vue.

<!-- ... vue cdn -->
<script src="https://unpkg.com/marked@0.3.6"></script>
<script src="https://unpkg.com/lodash@4.16.0"></script>
<!-- ... instancia vue -->

Añadiendo el editor y el visor

<div id="app">
  <textarea :value="input" @input="update"></textarea>
  <div v-html="compiledMarkdown"></div>
</div>

Como vemos, colocamos dentro de nuestro elemento padre un textarea y un div, en el textarea, vamos a ir escribiendo nuestro código markdown, y en el div vamos a ver el resultado.

  • :value : este atributo de html, hace referencia al valor del textarea, y su función es parecida a la propiedad value de un input html, los dos puntos («:») al inicio de la propiedad, indica que vamos a utilizar una variable de nuestra data que estará en nuestra instancia.
  • @input: los atributos que comienzan en arroba, son eventos, y su valor es lo que conocemos con el callback que ejecuta ese evento, update es el nombre de la función, pero el evento @input lo que hace es ejecutarse cada vez que el :value cambia.
  • v-html: Esta propiedad se utiliza cuando queremos formatear un texto html entro de un elemento html, en este caso compiledMarkdown es una funcion que retorna el html de nuestro textarea pero compilado.

Añadiendo la lógica

Antes de todo, vamos a cambiar un poco nuestra instancia, y vamos a colocar algunas opciones:

{
  // ...
  computed:{
  
  },
  methods:{

  }
}
  • computed: las propiedades computed son funciones, pero no deben ser tratadas como sí, si no más bien como variables que tienen una funcionalidad. Pudiesen llamarse filtros.
  • methods: Los métodos son funciones. Creo que está bastante claro el nombre.

También quiero dale un valor inicial a nuestro editor:

{
  //...
  input: '# Hello, World!'
  //...
}

Ahora, necesitamos que cuando se escriba en el textarea, se actualice en nuestra variable input. Recordemos la instrucción @input=»update».

{
  // ...
  methods:{
    update: _.debounce(function (e) {
      this.input = e.target.value
    }, 300)
  } 
}

Como vemos, actualizamos nuestra propiedad input, y se le aplica como un delay para que no se actualice inmediatamente en nuestro visor.

Ahora necesitamos mostrarlo en el visor. Recordemos v-html=»compiledMarkdown»

{
  // ...
  computed:{
    compiledMarkdown: function () {
      return marked(this.input, { sanitize: true })
    }
  },
  // ...
}

Cada vez que actualizamos nuestra variable input, utilizamos nuestro compiledMarkdown y aplicamos la función marked de nuestras librerías para que nos retorne el valor en html del valor de nuestro input.

Añadiendo estilos

Podemos agregar la etique de estilos para que se vea mucho mejor.

html, body, #editor {
  margin: 0;
  height: 100%;
  font-family: 'Helvetica Neue', Arial, sans-serif;
  color: #333;
}

textarea, #editor div {
  display: inline-block;
  width: 49%;
  height: 100%;
  vertical-align: top;
  box-sizing: border-box;
  padding: 0 20px;
}

textarea {
  border: none;
  border-right: 1px solid #ccc;
  resize: none;
  outline: none;
  background-color: #f6f6f6;
  font-size: 14px;
  font-family: 'Monaco', courier, monospace;
  padding: 20px;
}

code {
  color: #f66;
}

Puedes ver un preview de este código en la pagina oficial de vuejs.

Ver más sobre