PWA

완성! Markdown Editor

그랜파 개발자 2024. 7. 11. 03:57

10. 완성! Markdown Editor

Markdown Editor를 완성하여 봅시다. 이 완성본에는 ChatGPT가 알려준 것들 외에 highlight.js의 편리한 사용을 위하여 vue-markdown-highlight와 이미지 업로드 진행 상태를 보여주기 위한 vue-circular-progress 사용을 위하여 vuetify를 사용합니다

프로젝트를 만들어 봅시다.

1. Firebase 프로젝트 만들기:

우선 Firebase의 Storage를 이용하기 위해서는 Firebase 프로젝트를 만들고 앱을 등록하여야 합니다. Firebase 콘솔에서 프로젝트를 만들고 앱을 등록하였다고 가정하고 진행합니다.

2. Vue 프로젝트 만들기

vue create markdown-editor

? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, PWA, Router, Vuex
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? (y/N) n

3. 프로젝트 디렉토리로 이동

cd markdown-editor

4. 각종 프로그램 설치

npm install firebase

vue add vuetify ? Choose a preset: (Use arrow keys)
Vuetify 2 - Configure Vue CLI (advanced)
> Vuetify 2 - Vue CLI (recommended)
Vuetify 2 - Prototype (rapid development)
Vuetify 3 - Vite (preview)
Vuetify 3 - Vue CLI (preview)

npm install marked highlight.js npm install vue-markdown-highlight -D npm install --save @fortawesome/fontawesome-free

5. configure Firebase:

src 디렉터리에 firebase.js 파일을 만들고 Firebase 구성을 추가합니다.

// src/firebase.js
import { initializeApp } from 'firebase/app';
import { getStorage } from 'firebase/storage';

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_PROJECT_ID.appspot.com",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
  measurementId: "YOUR_MEASUREMENT_ID"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

// Initialize Firebase Storage
const storage = getStorage(app);

export { storage };

6. Markdown Editor 컴포넌트 만들기

src/components 디렉토리에 MarkdownEditor.vue 파일을 만들어 코드 추가하기

7. babel.config.js 수정

babel.config.js 파일을 열어 ‘plugins: ["@babel/plugin-transform-private-methods"]’ 추가

module.exports = {
  presets: ['@vue/cli-plugin-babel/preset'],
  plugins: ["@babel/plugin-transform-private-methods"]
}

8. marked Import 수정

import { marked } from 'marked';

9. index.html에 Font Awesome 포함

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

10. MarkdownEditor.vue

//src/comComponents/MarkdownEditor.vue
<template>
  <div class="markdown-editor">
    <div class="toolbar" >
      <button @click="applyBold" title="Bold"><i class="fas fa-bold"></i></button>
      <button @click="applyItalic" title="Italic"><i class="fas fa-italic"></i></button>
      <button @click="applyHeading1" title="Heading 1"><i class="fas fa-heading"></i><span>1</span></button>
      <button @click="applyHeading2" title="Heading 2"><i class="fas fa-heading"></i><span>2</span></button>
      <button @click="applyHeading3" title="Heading 3"><i class="fas fa-heading"></i><span>3</span></button>
      <button @click="applyHeading4" title="Heading 4"><i class="fas fa-heading"></i><span>4</span></button>
      <button @click="applyLink" title="Link"><i class="fas fa-link"></i></button>
      <button @click="applyImage" title="Image"><i class="fas fa-image"></i></button>
      <button @click="applyList" title="Unordered List"><i class="fas fa-list-ul"></i></button>
      <button @click="applyOrderedList" title="Ordered List"><i class="fas fa-list-ol"></i></button>
      <button @click="applyBlockQuote" title="Block Quote"><i class="fa fa-quote-left"></i></button>      
      <button @click="applyCode" title="Code"><i class="fas fa-code"></i></button>
    </div>

    <div>      
      <input type="file" ref="fileInput" @change="onFileChange" style="display: none;" />
    </div>

    <div v-if="this.uploading" class="full-screen-div">
      <v-progress-circular  :size="150" indeterminate color="grey"></v-progress-circular>
      <p>{{ progress }}%</p>
    </div>
    <textarea v-model="markdown"></textarea>  
    <div v-html="renderedMarkdown" v-highlight class="preview"></div>

  </div>
</template>

<script>
import { ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage';
import { storage } from '../firebase';
import { marked } from 'marked';
import 'highlight.js/styles/default.css';

export default {
  data() {
    return {
      file: null,
      uploading: false,
      progress: 0,
      downloadURL: null,
      markdown: ''
    };
  },
  computed: {
    renderedMarkdown() { 
      return marked(this.markdown); 
    }
  },
  methods: {   
    openFileSelector() {
      this.$refs.fileInput.click();
    },
    onFileChange(event) {     
      this.file = event.target.files[0];
      this.progress = 0;
      this.uploading = false;
      this.downloadURL = null;

      this.uploadImage();
    },
    uploadImage() {
      if (this.file) {
        this.uploading = true; 

        const storageRef = ref(storage, `images/${this.file.name}`);

        let uploadTask = uploadBytesResumable(storageRef, this.file);
        uploadTask.on('state_changed',
          (snapshot) => {
            this.progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
          },
          (error) => {
            console.error('Upload failed', error);
            this.uploading = false;
          },
          () => {
            getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
              this.downloadURL = downloadURL;
              this.uploading = false;

              this.wrapSelection('![', `](${this.downloadURL})`);
            });
          }
        );        
      }
    }, 
    applyBold() {
      this.wrapSelection('**', '**');
    },
    applyItalic() {
      this.wrapSelection('*', '*');
    },
    applyHeading1() {
      this.insertAtStartOfLine('# ');
    },
    applyHeading2() {
      this.insertAtStartOfLine('## ');
    },
    applyHeading3() {
      this.insertAtStartOfLine('### ');
    },
    applyHeading4() {
      this.insertAtStartOfLine('#### ');
    },
    applyLink() {
      const url = prompt('Enter the URL:');
      if (url) {
        this.wrapSelection('[', `](${url})`);
      }
    },
    applyImage() {
      this.openFileSelector();
    },
    applyList() {
      this.insertAtStartOfLine('- ');
    },
    applyOrderedList() {
      this.insertAtStartOfLine('1. ');
    },
    applyBlockQuote() {
      this.insertAtStartOfLine('> ');
    },
    applyCode() {
      this.wrapSelection('```\n', '\n```');
    },
    wrapSelection(before, after) {
      const textarea = this.$el.querySelector('textarea');
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const text = textarea.value;
      const selectedText = text.substring(start, end);
      const newText = text.substring(0, start) + before + selectedText + after + text.substring(end);
      this.markdown = newText;
      this.$nextTick(() => {
        textarea.setSelectionRange(start + before.length, end + before.length);
        textarea.focus();
      });
    },
    insertAtStartOfLine(insertText) {
      const textarea = this.$el.querySelector('textarea');
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const text = textarea.value;
      const before = text.substring(0, start);
      const after = text.substring(end);
      const startOfLine = before.lastIndexOf('\n') + 1;
      const newText = before.substring(0, startOfLine) + insertText + before.substring(startOfLine) + after;
      this.markdown = newText;
      this.$nextTick(() => {
        textarea.setSelectionRange(start + insertText.length, start + insertText.length);
        textarea.focus();
      });
    }
  }
};
</script>

<style scoped>
.markdown-editor {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
.toolbar {
  display: flex;
  justify-content: flex-start;
  background: #f5f5f5;
  padding: 10px;
  border-bottom: 1px solid #ddd;
}
.toolbar button {
  background: none;
  border: none;
  margin-right: 10px;
  cursor: pointer;
}
.toolbar button span {
  font-size: 12px;
  vertical-align: super;
  margin-left: 2px;
}
textarea {
  flex: 1;
  padding: 10px;
  font-size: 16px;
  line-height: 1.5;
  border: none;
  border-right: 1px solid #ddd;
  resize: none;
  outline: none;
}
.preview {
  flex: 1;
  padding: 10px;
  line-height: 1.2;
  overflow: auto;
  background: #fff;
}
.full-screen-div {
  width: 100%;
  height: 100%;
  margin: 20px;
  place-items: center;
  text-align: center;
}
</style>

11. App.vue를 수정

Markdown Editor 컴포넌트를 App.vue에 포함

<template>
  <div id="app">
    <MarkdownEditor />
  </div>
</template>

<script>
import MarkdownEditor from '@/components/MarkdownEditor.vue';

export default {
  name: 'app',
  components: {
    MarkdownEditor
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin-top: 0px;
}
</style>

12. 개발 서버에서 프로젝트 실행

npm run serve

12. Failed to resolve directive: highlight

아래 ChatGPT에게 물었습니다. 참조

ChatGPT에게 물었습니다.

1. vuetify가 뭐지?

What is vuetify?

Vuetify is a popular open-source UI (User Interface) library for Vue.js, a progressive JavaScript framework. Vuetify provides developers with a comprehensive set of tools to build rich and responsive web applications with a consistent design and user experience. Here are some key features and aspects of Vuetify:
Vuetify는 진보적인 JavaScript 프레임워크인 Vue.js용 인기 오픈 소스 UI(사용자 인터페이스) 라이브러리입니다. Vuetify는 개발자에게 일관된 디자인과 사용자 경험을 갖춘 풍부하고 반응성이 뛰어난 웹 애플리케이션을 구축할 수 있는 포괄적인 도구 세트를 제공합니다. Vuetify의 주요 기능과 측면은 다음과 같습니다.

 

1. Material Design: Vuetify is built on Google's Material Design principles, providing a modern and visually appealing design system out of the box. This ensures a consistent and professional look and feel for applications.
  머티리얼 디자인: Vuetify는 Google의 머티리얼 디자인 원칙을 기반으로 구축되어 즉시 사용 가능한 현대적이고 시각적으로 매력적인 디자인 시스템을 제공합니다. 이를 통해 애플리케이션에 대한 일관되고 전문적인 모양과 느낌이 보장됩니다.

 

2. Rich Component Library: Vuetify includes a wide range of pre-built components, such as buttons, forms, tables, modals, carousels, and more. These components are highly customizable and can be easily integrated into any Vue.js application.
  풍부한 구성 요소 라이브러리: Vuetify에는 버튼, 양식, 테이블, 모달, 캐러셀 등과 같은 사전 구축된 광범위한 구성 요소가 포함되어 있습니다. 이러한 구성 요소는 사용자 정의가 가능하며 모든 Vue.js 애플리케이션에 쉽게 통합될 수 있습니다.

 

3. Responsive Design: Vuetify components are designed to be fully responsive, allowing applications to adapt seamlessly to different screen sizes and devices.
  반응형 디자인: Vuetify 구성 요소는 완벽하게 반응하도록 설계되어 애플리케이션이 다양한 화면 크기와 장치에 원활하게 적응할 수 있습니다.

 

4. Customization: Developers can customize the look and feel of Vuetify components using various props, slots, and themes. Vuetify also supports custom themes, allowing for easy branding and design changes.
  사용자 정의: 개발자는 다양한 소품, 슬롯 및 테마를 사용하여 Vuetify 구성 요소의 모양과 느낌을 사용자 정의할 수 있습니다. Vuetify는 또한 사용자 정의 테마를 지원하므로 쉽게 브랜딩 및 디자인 변경이 가능합니다.

 

5. Accessibility: Vuetify adheres to accessibility standards, making it easier to create applications that are usable by people with disabilities.
  접근성: Vuetify는 접근성 표준을 준수하므로 장애인이 사용할 수 있는 애플리케이션을 더 쉽게 만들 수 있습니다.

 

6. Ease of Use: Vuetify is designed to be easy to use, even for developers who are new to Vue.js. Its extensive documentation and examples help developers quickly get started and understand how to use the components effectively.
  사용 용이성: Vuetify는 Vue.js를 처음 접하는 개발자라도 쉽게 사용할 수 있도록 설계되었습니다. 광범위한 문서와 예제는 개발자가 빠르게 시작하고 구성 요소를 효과적으로 사용하는 방법을 이해하는 데 도움이 됩니다.

 

7. Community and Ecosystem: Vuetify has a large and active community, providing support, contributing to the library, and creating additional plugins and tools. The ecosystem around Vuetify includes a variety of resources, such as tutorials, templates, and third-party integrations.
  커뮤니티 및 생태계: Vuetify는 지원을 제공하고, 라이브러리에 기여하고, 추가 플러그인과 도구를 만드는 크고 활동적인 커뮤니티를 보유하고 있습니다. Vuetify 주변 생태계에는 튜토리얼, 템플릿, 타사 통합과 같은 다양한 리소스가 포함되어 있습니다.

 

In summary, Vuetify is a powerful and flexible UI library for Vue.js that helps developers build beautiful, responsive, and accessible web applications quickly and efficiently, leveraging the principles of Material Design.
요약하면 Vuetify는 개발자가 머티리얼 디자인 원칙을 활용하여 아름답고 반응성이 뛰어나며 액세스 가능한 웹 애플리케이션을 빠르고 효율적으로 구축하는 데 도움이 되는 강력하고 유연한 Vue.js용 UI 라이브러리입니다.

2. vue-markdown-highlight 가 뭐지?

What is vue-markdown-highlight?

vue-markdown-highlight is a Vue.js component that integrates syntax highlighting for Markdown content. It allows developers to easily render Markdown content with syntax highlighting for code blocks, which can be particularly useful for documentation, blogs, and any application that displays code snippets.
vue-markdown-highlight는 Markdown 콘텐츠에 대한 구문 강조를 통합하는 Vue.js 구성 요소입니다. 이를 통해 개발자는 코드 블록에 대한 구문 강조 기능을 사용하여 Markdown 콘텐츠를 쉽게 렌더링할 수 있으며, 이는 문서, 블로그 및 코드 조각을 표시하는 모든 애플리케이션에 특히 유용할 수 있습니다.

 

Here are some key features and aspects of vue-markdown-highlight:

다음은 vue-markdown-highlight의 몇 가지 주요 기능과 측면입니다.

 

1. Markdown Rendering: It parses and renders Markdown content, converting it into HTML. This includes standard Markdown elements like headings, lists, links, images, and more.
마크다운 렌더링: 마크다운 콘텐츠를 구문 분석하고 렌더링하여 HTML로 변환합니다. 여기에는 제목, 목록, 링크, 이미지 등과 같은 표준 Markdown 요소가 포함됩니다.

 

2. Syntax Highlighting: It integrates with syntax highlighting libraries, such as Prism.js or Highlight.js, to apply syntax highlighting to code blocks within the Markdown content. This makes the code easier to read and visually appealing.
구문 강조: Prism.js 또는 Highlight.js와 같은 구문 강조 라이브러리와 통합되어 Markdown 콘텐츠 내의 코드 블록에 구문 강조를 적용합니다. 이렇게 하면 코드를 읽기 쉽고 시각적으로 매력적으로 만들 수 있습니다.

 

3. Customization: Developers can customize the rendering and highlighting behavior. This might include choosing different themes for syntax highlighting or configuring how certain Markdown elements are rendered.
사용자 정의: 개발자는 렌더링 및 강조 표시 동작을 사용자 정의할 수 있습니다. 여기에는 구문 강조를 위해 다양한 테마를 선택하거나 특정 Markdown 요소가 렌더링되는 방식을 구성하는 것이 포함될 수 있습니다.

 

4. Ease of Use: vue-markdown-highlight is designed to be easy to integrate into Vue.js applications. It provides a straightforward API for rendering Markdown content with syntax highlighting.
사용 편의성: 'vue-markdown-highlight'는 Vue.js 애플리케이션에 쉽게 통합되도록 설계되었습니다. 구문 강조를 사용하여 Markdown 콘텐츠를 렌더링하기 위한 간단한 API를 제공합니다.

 

Plugin Support: It can support various Markdown-it plugins to extend the functionality of the Markdown parser, allowing for additional features like footnotes, custom containers, or tables.
플러그인 지원: 다양한 Markdown-it 플러그인을 지원하여 Markdown 파서의 기능을 확장하여 각주, 사용자 정의 컨테이너 또는 표와 같은 추가 기능을 허용할 수 있습니다.

 

Example Usage 사용 예

 

To use vue-markdown-highlight in a Vue.js project, you typically follow these steps:
Vue.js 프로젝트에서 vue-markdown-highlight를 사용하려면 일반적으로 다음 단계를 따르세요.

 

1. Installation: First, you need to install the package using npm or yarn.
설치: 먼저 npm 또는 Yarn을 사용하여 패키지를 설치해야 합니다

npm install vue-markdown-highlight

 

 

2. Import and Use: Next, you need to import the component and use it in your Vue components.
가져오기 및 사용: 다음으로 구성 요소를 가져와 Vue 구성 요소에서 사용해야 합니다.

 

// main.js or a similar entry file
import Vue from 'vue';
import VueMarkdownHighlight from 'vue-markdown-highlight';
import 'vue-markdown-highlight/dist/vue-markdown-highlight.css';

Vue.use(VueMarkdownHighlight);

 

 

3. Component Usage: Then you can use the vue-markdown-highlight component in your templates.
구성 요소 사용: 그러면 템플릿에서 vue-markdown-highlight 구성 요소를 사용할 수 있습니다.

 

<template>
  <vue-markdown>
    # Hello World
    ```javascript
    console.log('Hello, world!');
    ```
  </vue-markdown>
</template>

 

This is a basic overview, and you might need to refer to the documentation for more advanced usage and customization options.
이는 기본 개요이며, 고급 사용법 및 사용자 정의 옵션에 대해서는 설명서를 참조해야 할 수도 있습니다.

 

Benefits

 

  • Enhanced Readability: Code snippets in Markdown are syntax-highlighted, making them easier to read and understand.
    가독성 향상: Markdown의 코드 조각은 구문이 강조 표시되어 더 쉽게 읽고 이해할 수 있습니다.
  • Seamless Integration: Easy to integrate into Vue.js projects with minimal configuration.
    원활한 통합: 최소한의 구성으로 Vue.js 프로젝트에 쉽게 통합할 수 있습니다.
  • Customizable: Flexibility to customize the rendering and theming according to the project's requirements.
    사용자 정의 가능: 프로젝트 요구 사항에 따라 렌더링 및 테마를 유연하게 사용자 정의할 수 있습니다.
  • Overall, vue-markdown-highlight is a useful tool for Vue.js developers who need to render Markdown content with syntax-highlighted code blocks, providing a better user experience for displaying documentation and code examples.
    전반적으로 vue-markdown-highlight는 구문 강조 코드 블록으로 Markdown 콘텐츠를 렌더링해야 하는 Vue.js 개발자에게 유용한 도구로, 문서 및 코드 예제를 표시하기 위한 더 나은 사용자 경험을 제공합니다.

 

3. Failed to resolve directive: highlight

If you're encountering the error "Failed to resolve directive: highlight" in a Vue.js application, it likely means that Vue is unable to find the directive you're trying to use. This is often due to not properly registering the directive in your Vue application.
Vue.js 애플리케이션에서 "Failed to resolve directive: highlight" 오류가 발생하는 경우 Vue가 사용하려는 지시문을 찾을 수 없다는 의미일 가능성이 높습니다. 이는 Vue 애플리케이션에 지시문을 제대로 등록하지 않았기 때문에 발생하는 경우가 많습니다.

 

Here’s a step-by-step guide to properly set up and use a custom directive for syntax highlighting in a Vue.js application:
다음은 Vue.js 애플리케이션에서 구문 강조를 위한 사용자 정의 지시문을 올바르게 설정하고 사용하기 위한 단계별 가이드입니다.

Step 1: Install Highlight.js

First, you need to install Highlight.js, a syntax highlighter.
먼저 구문 강조 도구인 Highlight.js를 설치해야 합니다.

npm install highlight.js

 

Step 2: Create the Highlight Directive

 

Create a custom directive to handle syntax highlighting using Highlight.js.
Highlight.js를 사용하여 구문 강조를 처리하는 사용자 지정 지시문을 만듭니다.

 

In Vue 3

 

1. Create a new file for your directive, e.g., highlight.js.
지시어에 대한 새 파일(예: highlight.js)을 만듭니다.

 

// src/directives/highlight.js
import hljs from 'highlight.js';
import 'highlight.js/styles/default.css'; // You can change the style to any other available theme

export default {
  beforeMount(el) {
    let blocks = el.querySelectorAll('pre code');
    blocks.forEach((block) => {
      hljs.highlightElement(block);
    });
  },
  updated(el) {
    let blocks = el.querySelectorAll('pre code');
    blocks.forEach((block) => {
      hljs.highlightElement(block);
    });
  },
};

 

2. Register the directive globally in your main application file, typically main.js or main.ts.
기본 애플리케이션 파일(일반적으로 main.js 또는 main.ts)에 지시문을 전역적으로 등록합니다.

 

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import highlight from './directives/highlight';

const app = createApp(App);

app.directive('highlight', highlight);

app.mount('#app');

 

3. Use the directive in your component.
구성 요소에서 지시어를 사용하십시오.

 

<template>
  <div>
    <pre>
      <code v-highlight>
        const message = 'Hello, World!';
        console.log(message);
      </code>
    </pre>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
};
</script>

 

In Vue 2

 

1. Create a new file for your directive, e.g., highlight.js.
지시어에 대한 새 파일(예: highlight.js)을 만듭니다.

// src/directives/highlight.js
import hljs from 'highlight.js';
import 'highlight.js/styles/default.css'; // You can change the style to any other available theme

const highlight = {
  bind(el) {
    let blocks = el.querySelectorAll('pre code');
    blocks.forEach((block) => {
      hljs.highlightBlock(block);
    });
  },
  componentUpdated(el) {
    let blocks = el.querySelectorAll('pre code');
    blocks.forEach((block) => {
      hljs.highlightBlock(block);
    });
  },
};

export default highlight;

 

2. Register the directive globally in your main application file, typically main.js.
기본 애플리케이션 파일(일반적으로 main.js)에 지시문을 전역적으로 등록합니다.

// main.js
import Vue from 'vue';
import App from './App.vue';
import highlight from './directives/highlight';

Vue.directive('highlight', highlight);

new Vue({
  render: (h) => h(App),
}).$mount('#app');

 

3. Use the directive in your component.
구성 요소에서 지시어를 사용하십시오.

<template>
  <div>
    <pre>
      <code v-highlight>
        const message = 'Hello, World!';
        console.log(message);
      </code>
    </pre>
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
};
</script>

 

Explanation

  • Directive Definition: The custom directive highlight uses Highlight.js to apply syntax highlighting to code blocks inside pre elements.
    지시문 정의: 사용자 지정 지시문 highlight는 하이라이트.js를 사용하여 pre 요소 내부의 코드 블록에 구문 강조를 적용합니다.
  •  
  • Registration: The directive is registered globally using app.directive in Vue 3 or Vue.directive in Vue 2.
    등록: 지시문은 Vue 3의 'app.directive' 또는 Vue 2의 'Vue.directive'를 사용하여 전역적으로 등록됩니다.
  •  
  • Usage: The v-highlight directive is applied to the code elements in the template to enable syntax highlighting.
    사용법: v-highlight 지시어는 구문 강조를 활성화하기 위해 템플릿의 code 요소에 적용됩니다.

This should resolve the "Failed to resolve directive: highlight" error and enable syntax highlighting in your Vue.js application.
이렇게 하면 "지시문 해결 실패: 강조" 오류가 해결되고 Vue.js 애플리케이션에서 구문 강조가 활성화됩니다.