Vue 3 Toast UI 사용해보기

nhn에서 만든 Toast UI Editor를 vue에 붙이는 작업을 해보겠습니다.

npm install --save @toast-ui/vue-editor

vue 3은 지원하지 않아서 오류 발생합니다.

그래서 아래와 같이 setup 했습니다.

npm install --save @toast-ui/editor

npm install @toast-ui/editor-plugin-color-syntax --save

npm install @toast-ui/editor-plugin-code-syntax-highlight

CustomToastEditor.vue

<template>
	<div id="editor"/>
</template>
<script lang="ts">
  import {uploadReceiptBoardImage} from '@/api/managerApi';
  import '@toast-ui/editor/dist/toastui-editor.css'; // Editor's Style
  import Editor from '@toast-ui/editor';
  import 'highlight.js/styles/github.css';
  import 'tui-color-picker/dist/tui-color-picker.css';
  import '@toast-ui/editor-plugin-color-syntax/dist/toastui-editor-plugin-color-syntax.css';
  import colorSyntax from '@toast-ui/editor-plugin-color-syntax';
   
  let editor;
    
export default {
    name: 'CustomToastEditor',
    props: {
      initialValue: {
        type: String,
        required: false,
      },
      initialHeight: {
        type: String,
        required: false,
      },
    },
    mounted() {
      console.log('onMounted');

      editor = new Editor({
        el: document.querySelector('#editor'),
        previewStyle: 'vertical',
        height: this.initialHeight,
        initialEditType: 'wysiwyg',
        initialValue: this.initialValue,
        plugins: [colorSyntax],
        hooks: {
          // 이미지 드랍 또는 등록 시 작동할 콜백 함수
          addImageBlobHook: (blob, callback) => {
            uploadReceiptBoardImage(blob).then(response => {
              callback(response.data, '');
            });
          },
        },
      });
    },
    methods: {
      getEditorContent() {
        return editor.getHTML();
      },
    },
</script>

editor options은 https://nhn.github.io/tui.editor/latest/ToastUIEditorCore를 참고해주세요.

addImageBlobHook으로 호출되는 백엔드 부분은 아래와 같이 구현

@PostMapping("/board/image")
public ResponseEntity<String> saveBoardImage(@RequestParam("uploadFile") MultipartFile uploadFile) {

    // 이미지를 서버에 저장한 다음 view path를 리턴한다.
    return ResponseEntity.ok()
        .body(this.uploadService.saveReceiptBoardImage(uploadFile));
}

test.vue

<template>
  <div>
  	<custom-toast-editor :initial-value="results.editorContent" :initial-height="'500px'" ref="editor" />
  </div>
  <div>
    <v-btn flat class="my-btn-green" prepend-icon="mdi-magnify" @click="saveBtn"> 저장 </v-btn>
  </div>
</template>

<script lang="ts">
  import {defineComponent} from 'vue';
  import CustomToastEditor from '@/components/common/CustomToastEditor.vue';
  export default defineComponent({
    name: 'NoticeModifyModal',
    components: {CustomToastEditor},
    mounted() {
      console.log('onMounted');
    },
    methods: {
      saveBtn() {
        this.results.editorContent = this.$refs.editor.getEditorContent();
        console.log(this.results.editorContent);
        // 저장 로직
      },
    },
    data() {
      return {
        results: {},
      };
    },
  });  
</script>

댓글남기기