갑자기 다시 넉스트를 하고 있는
시키는 거 걍 다 해야 하는 노예 등장.
넉스트에 이미지 추가도 가능한 텍스트 에디터가 필요했다.
마치 이 티스토리 글쓰기 페이지 같은.... 이런 것 만드는 것이다.
공식 문서는 아래.
환경에 맞게 필요한 패키지들 설치하면 된다.
https://tiptap.dev/docs/editor/getting-started/overview
나는 특별한건 필요 없고, 글씨 정렬이나 볼드체, 글씨 크기, 순번 리스트.. 이 정도만 구현했다.
<template>
<div>
<!-- 툴바 -->
<div class="toolbar" v-if="editor">
<!-- Bold -->
<button @click="editor.chain().focus().toggleBold().run()" :class="{ active: editor.isActive('bold') }">
<i class="mdi mdi-format-bold"></i>
</button>
<!-- Italic -->
<button @click="editor.chain().focus().toggleItalic().run()" :class="{ active: editor.isActive('italic') }">
<i class="mdi mdi-format-italic"></i>
</button>
<!-- Underline -->
<button @click="editor.chain().focus().toggleUnderline().run()" :class="{ active: editor.isActive('underline') }">
<i class="mdi mdi-format-underline"></i>
</button>
<!-- Clear Marks (마크 제거) 버튼 -->
<!-- Clear Marks는 텍스트에 적용된 스타일, 즉 마크를 초기화하는 기능입니다. "마크"는 굵게(bold), 기울임(italic), 밑줄(underline) 등과 같은 텍스트 스타일을 의미합니다. 이 기능을 사용하면 선택된 텍스트나 전체 텍스트에서 모든 스타일을 제거할 수 있습니다.-->
<button @click="editor.chain().focus().unsetAllMarks().run()" title="Clear Marks">
<i class="mdi mdi-eraser"></i>
</button>
<!-- Clear Nodes -->
<!-- Clear Nodes는 노드를 초기화하는 기능입니다. TipTap에서 노드는 텍스트 블록, 헤딩, 리스트, 이미지 등과 같은 구조적인 요소를 말합니다. 예를 들어, 텍스트가 **헤딩(h1, h2, h3)**으로 설정되어 있을 때, 이 노드를 초기화하면 해당 텍스트는 기본적인 단락(paragraph)으로 되돌아갑니다.-->
<button @click="editor.chain().focus().clearNodes().run()" title="Clear Nodes">
<i class="mdi mdi-delete-forever"></i>
</button>
<!-- Paragraph -->
<button @click="editor.chain().focus().setParagraph().run()" :class="{ 'is-active': editor.isActive('paragraph') }" title="Paragraph">
<i class="mdi mdi-format-paragraph"></i>
</button>
<!-- Heading 1 -->
<button @click="editor.chain().focus().toggleHeading({ level: 1 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }" title="H1">
<i class="mdi mdi-format-header-1"></i>
</button>
<!-- Heading 2 -->
<button @click="editor.chain().focus().toggleHeading({ level: 2 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }" title="H2">
<i class="mdi mdi-format-header-2"></i>
</button>
<!-- Heading 3 -->
<button @click="editor.chain().focus().toggleHeading({ level: 3 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }" title="H3">
<i class="mdi mdi-format-header-3"></i>
</button>
<!-- Text Alignment -->
<button @click="editor.chain().focus().setTextAlign('left').run()">
<i class="mdi mdi-format-align-left"></i>
</button>
<button @click="editor.chain().focus().setTextAlign('center').run()">
<i class="mdi mdi-format-align-center"></i>
</button>
<button @click="editor.chain().focus().setTextAlign('right').run()">
<i class="mdi mdi-format-align-right"></i>
</button>
<!-- Bullet List -->
<button @click="editor.chain().focus().toggleBulletList().run()" :class="{ active: editor.isActive('bulletList') }">
<i class="mdi mdi-format-list-bulleted"></i>
</button>
<!-- Ordered List -->
<button @click="editor.chain().focus().toggleOrderedList().run()" :class="{ active: editor.isActive('orderedList') }">
<i class="mdi mdi-format-list-numbered"></i>
</button>
<!-- Insert Image Button -->
<button @click="addImage" >
<i class="mdi mdi-image"></i>
</button>
<!-- Hidden File Input -->
<input
type="file"
accept="image/*"
ref="imageInput"
style="display: none;"
@change="handleImageUpload"
/>
<!-- Undo -->
<button @click="editor.chain().focus().undo().run()">
<i class="mdi mdi-undo"></i>
</button>
<!-- Redo -->
<button @click="editor.chain().focus().redo().run()">
<i class="mdi mdi-redo"></i>
</button>
<button class="color-picker">
<input
type="color"
@input="changeTextColor($event.target.value)"
:value="editor.getAttributes('textStyle').color || '#000000'"
/>
</button>
</div>
<!-- 에디터 본문 -->
<EditorContent v-if="editor" :editor="editor" class="editor-content" />
<!-- 문자 수 표시 -->
<div class="character-count">
{{ characterCountMessage }}
</div>
</div>
</template>
<i class="mdi mdi-format-bold"></i>
위 클래스 같은 경우는 사용하려면
npm install @mdi/font
mid/font 를 설치해줘야 함!
지금 회사에 퍼블리셔도 없어서... 대충 챗지피티한테 이쁘게 만들어달라 함.
내가 사용한 코드는 아래.
<style scoped>
.toolbar {
display: flex;
gap: 12px;
margin-bottom: 16px;
position: relative;
align-items: center;
}
.editor-content {
min-height: 100%;
font-size: 16px;
line-height: 1.5;
outline: none;
white-space: pre-wrap;
}
button {
padding: 8px 12px;
border: none;
border-radius: 4px;
background-color: #f5f5f5;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
position: relative;
transition: background-color 0.2s;
}
button:hover {
background-color: #e6e6e6;
}
button i {
font-size: 20px;
}
.character-count {
margin-top: 8px;
font-size: 14px;
color: #666;
}
.upload-btn i {
font-size: 18px;
}
</style>
이러면 짠!
위와 같은 간단한 에디터가 생성된다.
이미지 업로드는 따로 구현해야 함!
'삼분공부 > Vue' 카테고리의 다른 글
[Nuxt.js] Nuxt 3에서 nitro.devProxy와 운영 환경 API 연동 (1) | 2025.04.14 |
---|---|
[Nuxt] Nuxt3에서 Audio 중복 재생 문제 해결하기 & preload/load 이해하기 (0) | 2025.04.07 |
[Nuxt] meta 태그의 name과 property 차이점 (0) | 2025.04.02 |
[Nuxt.js] page 별로 layout 다르게 적용하는 방법 (0) | 2025.03.11 |
[Nuxt.js] <NuxtLink> 사용하는 이유 ! (0) | 2025.02.06 |