어드민 - Article 추가 화면 (Toast UI Editor 추가)

손대중·2022년 7월 4일
1

Toast UI Editor - @toast-ui/editor 를 설치하자.

yarn add @toast-ui/editor

그럼 import 구문을 통해 @toast-ui/editor 를 사용할 수 있다.

@toast-ui/editor 자세한 사용법은 아래 링크를 참조~

일단 난 AdminArticle.svelte 에서 직접 사용하기 보다는 wrapper - ToastUIEditor.svelte 를 하나 만들어서 사용함.

  • ToastUIEditor.svelte

    <div bind:this={editor} ></div>
    
    <script>
        import { onMount } from 'svelte';
        import '@toast-ui/editor/dist/toastui-editor.css';
        import '@toast-ui/editor/dist/theme/toastui-editor-dark.css';
    
        import Editor from '@toast-ui/editor';
    
        let editorInstance;
    
        let editor;
    
        onMount(() => {
            editorInstance = new Editor({
                el: editor,
                height: '500px',
                initialEditType: 'markdown',
                previewStyle: 'vertical',
                theme: 'dark',
                hideModeSwitch: true
            });
        });
    
    		// 부모 컴포넌트에서 호출할 함수들
        export function getHTML() {
            editorInstance.setMarkdown(editorInstance.getMarkdown().trim());
            return editorInstance.getHTML();
        }
    
        export function reset() {
            editorInstance.reset();
        }
    </script>
    
    <style>
        :global(.toastui-editor-toolbar) {
            overflow-x: scroll;
        }
    </style>

코드상 주의할 점 & 특이점은 아래와 같다.

  • new Editor(...) 사용시 document 에 있는 element 를 넘겨줘야 함.
  • 부모 component 에서 자식 component 의 함수를 호출해야 함 (editor 내용을 가져오기 & reset)
    • .svelte 파일 내 <script> ... </script> 구문 안에서 export 의미
      • export default 는 무조건 svelte component 그 자체로 명시적으로 사용 X
      • export let ... 은 부모 컴포넌트로부터 넘겨받은 props
      • export function ... 은 instance 의 메소드로 참조 가능 -> 부모 component 에서 접근 가능
        • 자식 component
          <script>
          	export funtion test () {...}
          </script>
        • 부모 component
          <Child bind:this={child}></Child>
          <script>
          	...
              let child;
              ...
              onMount(() => {
                  child.test();
              });
          </script>
    • ToastUIEditor.svelte 의 경우 export function ... 으로 부모 컴포넌트에서 자식 컴포넌트의 메서드를 직접 호출하는게 좋아 보임
      • editor 의 내용을 계속 참조하고 있기 보다는 필요할때만 딱 가져오는게 좋아 보임.
  • .toastui-editor-toolbar 의 style 에 overflow-x: scroll 을 추가한건 resize 될때마다 editor 의 toolbar 가 영역을 뚫고 노출되는 현상이 있어서...

AdminArticle.svelte 의 수정은 아래와 같다.

  • AdminArticle.svelte

    ...
    <div class="card-container">
        <h3>제목 & 본문 입력</h3>
        <Card variant="outlined">
            <Content>
                <Textfield bind:value={title} label="제목" required>
                    <HelperText slot="helper">제목을 입력해주세용.</HelperText>
                </Textfield>
    
                <h4>본문</h4>
                <ToastUIEditor bind:this={editor}></ToastUIEditor>
            </Content>
        </Card>
    </div>
    ...
    <script>
        ...
        import ToastUIEditor, { getHTML } from '../external-wrapper/ToastUIEditor.svelte';
        
        let editor;
        ...
        const addArticle = () => {
            if (!parent || parent.children.length > 0) {
                alert('가장 깊은 자식 메뉴를 선택해 주세요...');
                return;
            }
    
            if (!title) {
                alert('제목을 입력해주세요...');
                return;
            }
    
            const content = editor.getHTML();
    
            if (!content) {
                alert('본문을 입력해주세요...');
                return;
            }
    
            alert(`'잇힝~' ${parent} ${editor.getHTML()}`);
        }
    </script>
    ...

생각보다는 쉽게 적용했음. 걍 이거 쓰면 될듯~.

이제는 실제로 API 호출하는 부분이 남았다~.

2개의 댓글

comment-user-thumbnail
2022년 8월 30일

여러 에디터를 적용하다가.
한 2틀 헤메다 찾았네요.
필요한 기능 이렇게 공개해주셔서 감사합니다.

1개의 답글