Nuxt Content v2로 사용자 지정 코드 블록을 생성하는 방법

24257 단어 nuxtvuewebdev
코드 블록은 소프트웨어 개발에 관한 블로그에 필수적입니다. 이 문서에서는 다음 기능을 사용하여 Nuxt Content v2에서 사용자 정의 코드 블록 구성 요소를 정의하는 방법을 보여드리고자 합니다.
  • Markdown 파일 내의 코드 블록에 대한 사용자 지정 스타일 지정
  • 언어 이름 표시(사용 가능한 경우)
  • 파일 이름 표시(사용 가능한 경우)
  • "코드 복사"버튼 표시

  • Nuxt 콘텐츠 v2

    Nuxt Content v2은 프로젝트의 /content 디렉토리에서 로컬 파일을 읽는 Nuxt 3 모듈입니다. .md , .yml , .csv.json 파일을 지원합니다. 또한 MDC Syntax 과 함께 Markdown에서 Vue 구성 요소를 사용할 수 있습니다.

    Nuxt 앱 설정

    First, let’s start a new Nuxt Content project with:

    npx nuxi init nuxt-custom-code-blocks -t content
    

    Then we need to install the dependencies in the nuxt-custom-code-blocks folder:

    yarn install
    

    Now we can start the Nuxt content app in development mode:

    yarn dev
    
    A browser window should automatically open for http://localhost:3000 . Alternatively, you can start playing with Nuxt Content in your browser using StackBlitz 또는 CodeSandbox .

    다음StackBlitz sandbox은 이 문서에서 생성한 애플리케이션을 보여줍니다.



    맞춤형 산문 구성요소

    Prose은 Nuxt 콘텐츠의 Markdown 구문에서 출력되는 HTML 태그를 나타냅니다. Nuxt Content는 링크, 제목 수준 등과 같은 각 HTML 태그에 대한 Vue 구성 요소를 제공합니다.

    이러한 Vue 구성 요소를 재정의할 수 있으며, 이는 사용자 지정 코드 블록 구성 요소를 만들기 위해 수행할 작업입니다.

    Prose 구성 요소를 사용자 지정하려면 다음 단계를 수행해야 합니다.
  • 원본 구성 요소 소스를 확인하십시오.
  • 동일한 소품을 사용합니다.
  • components/content/ 디렉토리에서 이름을 동일하게 지정하십시오.

  • 이 예제에서는 Markdown 파일의 코드 블록을 렌더링하기 위해 Nuxt Content의 기본 Vue 구성 요소인 ProseCode 을 재정의하려고 합니다.

    이 구성 요소는 다음 소품을 허용합니다.
  • code : 문자열로 제공된 코드
  • language : 제공된 언어 이름
  • filename : 제공된 파일 이름
  • highlights : 강조 표시된 줄 번호 목록

  • Markdown 파일에서 이러한 값을 설정하는 방법을 살펴보겠습니다.

    js [src/index.js] {1, 2-3}
      const a = 4;
      const b = a + 3;
      const c = a * b;
    


    위의 예에서:
  • jslanguage 소품
  • 에 전달된 값입니다.
  • src/index.jsfilename 소품
  • 에 전달된 값입니다.
  • [1, 2, 3]highlights 소품
  • 에 전달된 값입니다.

    구성 요소를 재정의하기 위해 ProseCode.vue 디렉토리에 components/content를 생성하고 기본 구성 요소에 정의된 것과 정확히 동일한 소품을 사용합니다.

    <template>
      <slot />
    </template>
    
    <script setup lang="ts">
    const props = withDefaults(
      defineProps<{
        code?: string;
        language?: string | null;
        filename?: string | null;
        highlights?: Array<number>;
      }>(),
      { code: '', language: null, filename: null, highlights: [] }
    );
    </script>
    


    이제 이 구성 요소를 원하는 대로 사용자 정의할 수 있습니다.

    스타일 컨테이너

    First, we want to style the container that includes the code. Therefore, we wrap the <slot /> in a div and style it:

    <template>
      <div class="container">
        <slot />
      </div>
    </template>
    
    <style scoped>
    .container {
      background: #1e1e1e;
      position: relative;
      margin-top: 1rem;
      margin-bottom: 1rem;
      overflow: hidden;
      border-radius: 0.5rem;
    }
    </style>
    

    Let’s take a look at our custom code block:


    스타일 코드 블록 컨테이너

    언어 표시

    Next, we want to show the name of the language on the top right, if it is available.

    <template>
      <div class="container">
        <span v-if="languageText" :style="{ background: languageBackground, color: languageColor }" class="language-text" > {{ languageText }} </span> <slot />
      </div>
    </template>
    
    <script setup lang="ts">
    const props = withDefaults(
      defineProps<{
        code?: string;
        language?: string | null;
        filename?: string | null;
        highlights?: Array<number>;
      }>(),
      { code: '', language: null, filename: null, highlights: [] }
    );
    
    const languageMap: Record<
      string,
      { text: string; color: string; background: string }
    > = {
      vue: {
        text: 'vue',
        background: '#42b883',
        color: 'white',
      },
      js: {
        text: 'js',
        background: '#f7df1e',
        color: 'black',
      },
    };
    
    const languageText = computed(() =>
      props.language ? languageMap[props.language]?.text : null
    );
    const languageBackground = computed(() =>
      props.language ? languageMap[props.language]?.background : null
    );
    const languageColor = computed(() =>
      props.language ? languageMap[props.language]?.color : null
    );
    </script>
    
    <style scoped>
    .container {
      background: #1e1e1e;
      padding-top: 1em;
    }
    
    .language-text {
      position: absolute;
      top: 0;
      right: 1em;
      padding: 0.25em 0.5em;
      font-size: 14px;
      text-transform: uppercase;
      border-bottom-right-radius: 0.25em;
      border-bottom-left-radius: 0.25em;
    }
    </style>
    

    We define a map called languageMap that contains the displayed text, the CSS background, and text color for each programming language. We style the span tag that renders the language inside our template based on this map and the provided language prop:


    언어 이름이 있는 코드 블록

    파일 이름 표시

    Next, we want to show the file’s name on the top left, if it is available:

    <template>
      <div class="container">
        <span v-if="filename" class="filename-text">
          {{ filename }}
        </span>
        <slot />
      </div>
    </template>
    
    <style scoped>
    .filename-text {
      position: absolute;
      top: 0;
      left: 1em;
      padding: 0.25em 0.5em;
      color: white;
      font-size: 14px;
    }
    </style>
    

    The result looks like this:


    파일 이름이 있는 코드 블록

    복사 코드 추가 버튼

    Finally, we want to show a button that copies the code to the clipboard. Therefore, we use the useClipboard composable from VueUse :

    <template>
      <div class="container">
        <slot />
        <div class="bottom-container">
          <div class="copy-container">
            <span class="copied-text" v-if="copied">Copied code!</span>
            <button @click="copy(code)">Copy Code</button>
          </div>
        </div>
      </div>
    </template>
    
    <script setup lang="ts">
    import { useClipboard } from '@vueuse/core';
    
    const { copy, copied, text } = useClipboard();
    </script>
    
    <style scoped>
    .bottom-container {
      display: flex;
      justify-content: flex-end;
    }
    
    .copy-container {
      display: flex;
    }
    
    .copied-text {
      margin-right: 1em;
    }
    </style>
    


    언어 및 파일 이름, 코드 복사 버튼, 줄 강조 표시로 최종 결과를 살펴보겠습니다.


    최종 사용자 지정 코드 블록

    결론

    Custom code blocks are essential for my blog as my blog posts contain a lot of code snippets. Features like copy code or line highlighting provide excellent value to my readers, and it is straightforward to add such features by creating a custom code block component in Nuxt Content v2.

    The source code of this demo is available at GitHub 또는 StackBlitz sandbox .

    내 포트폴리오 웹사이트를 다시 작성하면서 발견한 흥미로운 주제에 대해 블로그에 올릴 계획이므로 다음 달에 더 많은Nuxt 3 게시물을 기대할 수 있습니다.

    이 기사가 마음에 드셨다면 저를 팔로우하여 새 블로그 게시물과 더 많은 콘텐츠에 대한 알림을 받으세요.

    또는 (또는 추가로) subscribe to my newsletter .

    좋은 웹페이지 즐겨찾기