
시작하기에 앞서
tiptap Editor
📄 공식 사이트
🕶️ 깃허브 주소


처음에는 공식 tiptap 라이브러리를 사용하려고 했으나 구현이 제대로 되지 않았고 Extension 중에 Color 기능이 내가 만드려고 하는 게시판에 있어서는 사용자 친화적이지 않다고 생각했다. 그래서 그 다음으로 찾았던 라이브러리가 tiptap-vuetify 이다.
tiptap-vuetify
🕶️ 깃허브 주소

마지막 업데이트가 2020년이긴 하지만 디자인도 훨씬 마음에 들고 기능들도 깔끔해서 사용해 보려고 했는데 새로 생성되거나 커스텀된 extension은 없었고 native-extensions를 사용해서 기존 tiptap 라이브러리의 기능을 사용하면 내가 라이브러리를 변경하려는 의도와 맞지 않아서 더 찾아 보기로 했다.
element-tiptap
🕶️ 깃허브 주소


- element-ui 사용
- 12가지 언어 지원
- 글자 수 자동 체크
📦 element-tiptap 설치
1. install the dependency
npm install --save element-tiptap
2. main.js import
import Vue from 'vue';
import ElementUI from 'element-ui';
import { ElementTiptapPlugin } from 'element-tiptap';
// import ElementUI's styles
import 'element-ui/lib/theme-chalk/index.css';
// import this package's styles
import 'element-tiptap/lib/index.css';
// use ElementUI's plugin
Vue.use(ElementUI);
// use this package's plugin
Vue.use(ElementTiptapPlugin, {
/* plugin options */
lang: "ko", // see i18n
spellcheck: true, // can be overwritten by editor prop
});
- lang: ‘ko’로 지정해 놓으면 한국어에 맞춰서 설정된다.
🚀 Usage
<template>
<div>
<el-tiptap v-model="content" :extensions="extensions" />
</div>
</template>
<script>
import {
// necessary extensions
Doc,
Text,
Paragraph,
Heading,
Bold,
Underline,
Italic,
Strike,
ListItem,
BulletList,
OrderedList,
} from 'element-tiptap';
export default {
data () {
// editor extensions
// they will be added to menubar and bubble menu by the order you declare.
return {
extensions: [
new Doc(),
new Text(),
new Paragraph(),
new Heading({ level: 5 }),
new Bold({ bubble: true }), // render command-button in bubble menu.
new Underline({ bubble: true, menubar: false }), // render command-button in bubble menu but not in menubar.
new Italic(),
new Strike(),
new ListItem(),
new BulletList(),
new OrderedList(),
],
// editor's content
content: `
<h1>Heading</h1>
<p>This Editor is awesome!</p>
`,
};
},
},
</script>
- bubble은 각각의 텍스트에 따로 기능창이 뜨는 건데 사용을 안 할 때는 소괄호 자체를 비우면 된다.
- extension은 아래 Props 리스트 중에 선택해서 추가하면 된다.
📔 Props
- Doc
- Text
- Paragraph
- Heading
- Bold
- Italic
- Strike
- Underline
- Link
- Image
- Iframe
- CodeBlock
- Blockquote
- ListItem
- BulletList (use with ListItem)
- OrderedList (use with ListItem)
- TodoItem
- TodoList (use with TodoItem)
- TextAlign
- Indent
- LineHeight
- HorizontalRule
- HardBreak
- TrailingNode
- History
- Table (use with TableHeader, TableCell, TableRow)
- TableHeader
- TableCell
- TableRow
- FormatClear
- TextColor
- TextHighlight
- Preview
- Fullscreen
- SelectAll
- FontType
- FontSize
- CodeView (🆕)
🧶 View
하위에 있는 Editor 컴포넌트에서 content를 html 태그와 같이 가져와야 기능이 제대로 적용된 채로 보이기 때문에 onUpdate 속성을 이용해서 html 태그와 함께 내용을 읽어왔다.
Editor 컴포넌트
<template>
<el-tiptap
ref="tiptapEditor"
:extensions="extensions"
:content="content"
@onUpdate="onUpdate"
/>
</template>
<script>
...
export default {
name: 'Editor',
props: {
content: String,
},
...
methods: {
onUpdate (html) {
this.content = html
},
getContent () {
return this.content
},
},
}
</script>
▶ onUpdate를 사용해서 html 내용을 그대로 가져오면 내용이 변경될 때마다 감지해서 보내주기 때문에 그 값을 그대로 쓰기에는 수십번 데이터 교환이 일어날 것 같았다.
▶ getContent() 메서드를 따로 만들어서 상위 컴포넌트에서 필요할 때 호출해서 사용할 수 있게 했다.
※ onUpdate가 아닌 다른 속성이나 기능으로 html을 다 읽어올 수 있는 게 존재하는지 잘 모르겠다. 다른 에디터는 viewer가 따로 있기도 하던데 내가 찾아본 바로는 tiptap은 viewer가 따로 없는 것 같다.
상위 컴포넌트
<template>
<v-container>
...
<editor
ref="editor"
v-model="content"
/>
...
</v-container>
</template>
<script>
...
methods: {
settingContent () {
this.content = this.$refs.editor.getContent()
},
},
}
</script>
▶ ref를 사용해서 하위 컴포넌트의 메서드를 실행한다.
'JavaScript' 카테고리의 다른 글
sweetalert2 메시지 줄 바꿈(개행) (0) | 2022.03.11 |
---|---|
JavaScript 간단한 함수로 다국어 처리하기 (0) | 2021.11.21 |
jQuery validation plugin(Form validation 사용법) (3) | 2021.11.19 |
자바스크립트 정규표현식(Regular expressions) (0) | 2021.11.16 |