NHN이 제공하는 toast ui 에디터를 vue에 붙여보고자 한다. 기본적인 마크다운 에디터는 물론 syntex highlight 기능, 드래그앤드랍 이미지 업로드 등의 플러그인과 훅을 지원하니 게시판 형태의 프로젝트를 진행할 때 사용하기 좋다.
$ npm i @toast-ui/editor --save
$ npm install @toast-ui/editor-plugin-code-syntax-highlight
2버전 이후부터는 플러그인은 별도 설치가 필요하게 업데이트 되었기 때문에 플러그인 역시 설치해주어야 한다.
그 외 차트 그리기 등 다양한 플러그인은 공식 홈페이지를 참조하길 바란다.
editor.vue
)<template>
<div id="editor"/>
<button id="submit">submit</button>
</template>
다음과 같이 에디터 클래스가 적용될 div를 잡아주어야 한다.
dependancy
import 'codemirror/lib/codemirror.css'; // codemirror 스타일
import '@toast-ui/editor/dist/toastui-editor.css'; // Editor's Style
import Editor from '@toast-ui/editor';
import 'highlight.js/styles/github.css'; // code block highlight 스타일
// toast ui 설치 시 highlight js 역시 자동으로 설치된다.
import codeSyntaxHightlight from '@toast-ui/editor-plugin-code-syntax-highlight';
import hljs from 'highlight.js';
mounted hook
mounted() {
const editor = new Editor({
el: document.querySelector("#editor"),
initialEditType: "markdown",
previewStyle: "vertical",
height: "500px",
plugins: [[codeSyntaxHightlight, { hljs }]],
hooks: {
// 이미지 드래그앤 드랍 시 작동할 콜백 함수를 정의한다.
// 드래그인 드랍 시 스토리지 저장 방법은 파이어베이스 포스팅 참조
addImageBlobHook: (blob, callback) => {}
}
const btn = document.querySelector("#submit")
btn.addEventListener("click", () => {
const editContent = editor.getMarkdown()
this.$emit("submitContent",editContent)
})
})
}
ArticleCreate.vue
<div class="editor">
<Editor @submitContent="submitArticle" />
</div>
<script>
import Editor from "@/components/Editor.vue";
...
methods: {
submitArticle(data) {
this.content.content = data;
var preview = validateMarkdown(data);
const params = {
nickname: this.$store.state.nickname,
title: this.content.title,
content: this.content.content,
keyword: this.content.keywords,
preview: preview,
ispublic: this.content.ispublic
};
// 이후 백앤드로 비동기 요청을 위한 코드를 작성한다.
}
</script>
articleDetail.vue
)뷰어에서 주의해야 할 점은 DB에서 게시글을 불러오는 요청은 비동기 요청이라는 것이다. 따라서 뷰어를 불러오는 시점에 내용이 아직 들어오지 않았다면 반드시 에러가 발생한다.
이를 방지하기 위해서는 (1) 비동기로 데이터를 불러오고 해당 데이터가 완전히 DOM의 데이터에 붙은 이후에 (2) 뷰어를 마운트 해야 한다.
template
<template>
<div v-if='article'>
<div id="viewer"/>
</div>
</template>
script
import '@toast-ui/editor/dist/toastui-editor-viewer.css';
import 'highlight.js/styles/github.css';
import Viewer from '@toast-ui/editor/dist/toastui-editor-viewer';
import codeSyntaxHightlight from '@toast-ui/editor-plugin-code-syntax-highlight';
import hljs from 'highlight.js';
mounted: {
getViewer() {
this.getArticle().then((res) => {
new Viewer({
el: document.querySelector('#viewer'),
// 표시하고자 하는 내용은 여기에 들어간다.
initialValue: res,
plugins: [[codeSyntaxHightlight, { hljs }]],
});
});
},
}