문의사항, 공지사항 등등 <textarea>로 하면 줄바꿈이나 굵은 글씨 같은 건 저장이 안 된다고 해서 텍스트 에디터를 사용하게 되었다.

원래 Froala Editor를 쓰려고 했는데 무료 버전이 어디까지 되는지 가늠하기가 어려워서 그냥 오픈 소스인 Quill을 사용해보려고 한다. 원래 후보에 다음 에디터도 있었는데 이건 너무 옛날 UI라 ㅋㅋㅋ 레트로한 프로젝트에 쓰면 괜찮을지도 모르겠다.

Quill은 요금 걱정을 할 필요가 없고 Vue나 React 같은 프레임워크에 넣어서 사용하기도 좋다고 한다. 공식 사이트 설명에 따르면 간단하게 만들 수도 있고 필요하면 확장 기능도 쉽게 추가할 수 있다.

다른 사람들이 Quill을 활용해서 만든 모듈도 있는 것 같은데 간단한 기능만 필요해서 그냥 공식 문서를 보고 사용했다.

Quill 공식 문서: https://quilljs.com/docs/configuration/

Vue 3.0 프로젝트에 사용했다.

NPM으로 Quill을 추가한다. 공식 문서 'Download' 페이지로 가면 CDN과 소스코드를 가져오는 방법도 있다.

npm install quill@1.3.6

따로 CSS를 작성하기엔 시간이 없어서 그냥 기본 테마를 넣었다. 테마는 텍스트 입력칸만 있는 Bubble과 글자 굵기 등을 조절할 수 있게 툴바가 달린 Snow가 있다. 다음 스크립트를 index.html <head>태그 안에 넣어 Snow 테마의 CSS를 추가한다.

<link rel="stylesheet" href="//cdn.quilljs.com/1.3.6/quill.snow.css">

ref로 연결되는 <div>를 하나 만들어서 quill 에디터 설정을 넣으면 된다.

<script setup>
import { ref, onMounted } from 'vue';
import Quill from 'quill';
const editor = ref(null);
let quill;

const initializeEditor = () => {
  quill = new Quill(editor.value, {
    modules: {
      toolbar: [
        [{ header: [1, 2, false] }],
        ['bold', 'italic', 'underline'],
        [{ color: [] }, { background: [] }],
        ['link', 'image'],
      ],
    },
    placeholder: '내용을 입력해주세요',
    theme: 'snow',
  });
};

onMounted(() => {
  initializeEditor();
});
</script>

<template>
  <div ref="editor"></div>
</template>

게시판으로 치면 딱 본문만 입력할 수 있는 템플릿이 만들어지기 때문에 제목이나 작성일 등 다른 정보들도 저장하고 싶으면 따로 input을 추가해야 한다.

toobar에 여러 기능을 넣을 수 있는데 [ ]로 감싸서 아이콘끼리 묶을 수 있고, {'기능이름': '옵션1', '옵션2'}와 같이 작성해서 드롭다운리스트를 만들 수 있다.

컨트롤 역할
'bold' 글자 굵게
'italic' 기울이기
'underline' 밑줄
'strike' 취소선
'link' 링크 추가
'image' 이미지 추가
'blockquote' 인용글 <blockquote>
'code-block' 코드 블럭 <pre>
'header': 1
'header': [1, 2, false]
해당 텍스트를 header 태그로 변경. 1: <h1>, 2: <h2> …
false: <p> (기본으로 붙은 태그, 선택지에 'Normal'로 나타난다.
'size': 'small'
'size': [ 'small', false, 'large', 'huge']
글자 크기 조절
'color': [] 글자색 설정 -드롭다운으로 팔레트가 나타난다.
[] 안에 '#555', '#121212' 이런 식으로 입력해서 선택지를 제한할 수 있다.
'background': [] 배경색 설정 -드롭다운으로 팔레트가 나타난다.
[] 안에 색 선택지를 제한할 수 있다.
'font': [] 폰트 선택 - sans serif, serif, monospace
'align': [] 단락 정렬 선택
'list': 'ordered' 순서가 있는 리스트 만들기 <ol>
'list': 'bullet' 순서가 없는 리스트 만들기 <ul>
'indent': '-1' 내어쓰기
'indent': '+1' 들여쓰기
'script': 'sub' 아래 첨자 <sub>
'script': 'super' 위 첨자 <sup>
'direction': 'rtl' 요소 방향을 오른쪽에서 왼쪽으로 (css 'direction: rtl' 추가
['clean'] 적용된 포맷 지우기

기능에 대해서는 공식 문서의 'TOOLBAR' 페이지에도 설명되어 있다.

Quill로 작성한 문서의 내용을 가져오거나 따로 변수에 저장하고 싶다면 다음과 같이 입력하면 된다.

const myText = quill.root.innerHTML;

저장한 데이터를 그냥 바로 표시해버리면 <br/>, <p>같은 태그들까지 전부 하나의 텍스트처럼 인식된다. 이를 스크립트 형태로 표시하기 위해 Vue의 'v-html' 디렉티브를 사용한다.

<div v-html="myText"></div>

해당 <div>안에 myText의 내용이 바로 추가되기 때문에 따로 더 감싸거나 할 필요는 없다.