코드 복사 버튼 만들기

2023년 6월 7일

intro

코드 블록의 코드를 복사하는 버튼을 만들려고 한다.
구현할 환경은 Nuxt.js를 기반으로, Nuxt-content, NuxtTailwind, tailwindcss/typography 모듈들을 이용한다.

Nuxt.js 설치

terminal
npx nuxi@latest init my-app

Nuxt-content

terminal
yarn add --dev @nuxt/content

Nuxt content는 .md, .yml, .csv, .json 파일을 구문 분석하고, 애플리케이션을 위한 데이터 계층을 생성해 준다. 또 마크다운에서 Vue에 컴포넌트를 사용할 수 있게 해준다.

NuxtTailwind

terminal
yarn add -D @nuxtjs/tailwindcss

Nuxt에서 Tailwind CSS를 쉽게 사용하게 해준다.

@tailwindcss/typography

terminal
npm install -D @tailwindcss/typography

Tailwind의 공식 플러그인으로 마크다운에서 렌더링 되는 HTML에 defaultCSS를 입혀준다.

구조

structure
- components
  - content
    - ProseCode.vue
- content
  - post.md   
- pages
  - index.vue
- app.vue
- nuxt.config.ts
- tailwind.config.js

code

nuxt.config.ts

nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  modules: [
    '@nuxt/content',
    '@nuxtjs/tailwindcss'
  ],
  content:{
    highlight:{
        preload:['vue'],
        theme: 'dracula',
    } 
  },
})

tailwind.config.js

tailwind.config.js
export default {
    plugins: [
        require('@tailwindcss/typography'),
      ],
}

app.vue

app.vue
<template>
  <div>
    <NuxtPage class="mx-auto max-w-7xl px-20"/>
  </div>
</template>

pages/index.vue

pages/index.vue
<template>
    <div>
        <ContentDoc path="post" class="prose min-w-full" />
    </div>
</template>

content/post.md

content/post.md
    # 제목

    ```js
    function main() {
        console.log("Hello, world!");
    }
    ```


복사기능이 없는 상태

스크린샷 2023-06-07 오후 9 18 38

현재 페이지의 코드 블록의 코드를 복사하려면 코드 부분을 드래그해서 복사해야 한다. 불편하기에 복사 버튼을 만들고 싶다.
코드 블록에 복사하는 버튼을 만들려면, nuxt content의 Prose Components 중 코드 블록을 다루는 컴포넌트인 ProseCode.vue를 덮어 쓰기 해야 한다. 자세한 내용은 nuxt content 공식 홈페이지를 참조

components/content/ProseCode.vue

components/content/ProseCode.vue
<script lang="ts">
import { defineComponent } from '#imports'

export default defineComponent({
  props: {
    code: {
      type: String,
      default: ''
    }
  },
  methods: {
    clickCopyBtn() {
        window.navigator.clipboard.writeText(this.$props.code);
    }
  }
})
</script>


<template>
    <div class="relative">
        <button class="absolute top-2 right-2 text-gray-100 font-bold text-sm hover:text-white rounded-md px-1.5 py-0.5 hover:bg-gray-500" @click="clickCopyBtn">copy</button>
        <slot />
    </div>
</template>

<style>
pre code .line {
  display: block;
  min-height: 1rem;
}
</style>

props.code: Prose Components의 ProseCode.vue가 호출될 때 전달받는 값 중 하나, 코드 블록의 코드에 해당되는 값이다. (마크다운 형식의 파일에서 작성한 코드 블록)
Clipboard API의 window.navigator.clipboard.writeText("복사할 텍스트")으로 코드 블록의 코드 props.code를 복사한다.


복사하기 버튼(copy)의 동작

ezgif com-video-to-gif


댓글