<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Leteu Dev</title>
        <link>https://leteu.dev</link>
        <description>Leteu 개발 블로그</description>
        <lastBuildDate>Tue, 18 Nov 2025 11:57:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>ko</language>
        <copyright>&lt;a target="_blank" href="https://creativecommons.org/licenses/by/4.0/"&gt;CC BY 4.0&lt;/a&gt; | © 2022-2025. leteu. All rights reserved.</copyright>
        <item>
            <title><![CDATA[[Mac] MacOS 무료 추천 앱 리스트 - Aldente, MonitorControl, Maccy, Mac Fan Control, runcat]]></title>
            <link>https://leteu.dev/posts/macos-recommend-app</link>
            <guid>https://leteu.dev/posts/macos-recommend-app</guid>
            <pubDate>Tue, 20 Jan 1970 21:36:15 GMT</pubDate>
            <description><![CDATA[<h2 id="maccy" tabindex="-1">Maccy <a class="header-anchor" href="#maccy" aria-label="Permalink to &quot;Maccy&quot;">&ZeroWidthSpace;</a></h2>
<p>진짜 <strong>G.O.A.T</strong><br>
제일 많이 사용하는 거 같다.</p>
<p>윈도에는 <code>클립보드</code>라는 이전에 복사해 뒀던 history를 보여주고 바로 붙여 넣을 수 있는 기능이 있다.<br>
그 클립보드 기능을 추가해 주는 프로그램이다.</p>
<blockquote>
<p><a href="https://maccy.app" target="_blank" rel="noreferrer">Maccy</a></p>

      <div>
        <a
          href="https://maccy.app"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Maccy - macOS clipboard manager</div>
            <div class="url-embed__desc">Clipboard manager for macOS which does one job - keep your copy history at hand. Lightweight. Open source. No fluff.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://maccy.app</span>
            </div>
          </div>
          
        </a>
      </div></blockquote>
<p>기본적으로 무료이고 공식 사이트에서 다운로드하려면 기부해야만 하는 거 같다(?)<br>
<a href="https://github.com/p0deje/Maccy" target="_blank" rel="noreferrer">maccy github</a>에 <code>Releases</code>에서 다운받거나 <code>brew</code> 써서 받으면 될 거 같다.</p>
<blockquote>
<p>brew 명령어</p>
</blockquote>
<div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span>brew install maccy</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p><img src="/images/macos-recommend-app/maccy-1.png" alt="maccy 설명 이미지"></p>
<p>저장하고 있을 항목 개수를 설정해 줄 수도 있고 단축키 또한 변경할 수 있어서 나는 아래처럼 변경해서 사용하고 있다.</p>
<div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span>command ⌘ + shift ⇧ + v</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>일반 복사는 <code>command + v</code>로 똑같이 사용하고 클립보드에서 들고 오고 싶을 땐 <code>shift</code>만 추가로 더 눌러주고 쓴다.<br>
색상 코드를 복사하면 왼쪽에 미리보기 형태로 색상을 보여주고 이미지를 복사하면 복사한 이미지 또한 미리보기로 보여준다.</p>
<h2 id="aldente" tabindex="-1">Aldente <a class="header-anchor" href="#aldente" aria-label="Permalink to &quot;Aldente&quot;">&ZeroWidthSpace;</a></h2>
<p>이 프로그램은 배터리 관련이라서 MacBook 사용자만 봐도 된다.</p>
<p>리튬이온 배터리는 20~80%만 사용할 때 베터리에 부담이 제일 적다고 한다.<br>
80 위로 충전하면 수명이 빨리 소모된다는 것이다.<br>
하지만 나처럼 하루 종일 책상에 올려다 놓고 일하는 사람들은 계속 충전을 해주고 있어야 하는 데 수시로 배터리 체크하면서 충전 했다, 안 했다하는 건 매우 귀찮은 일이다.</p>
<blockquote>
<p><a href="https://apphousekitchen.com/" target="_blank" rel="noreferrer">Aldente github</a></p>

      <div>
        <a
          href="https://apphousekitchen.com/"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #050515"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Home - AppHouseKitchen</div>
            <div class="url-embed__desc">It needs AlDente.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://apphousekitchen.com/</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://apphousekitchen.com/wp-content/uploads/2024/12/AHK-blaugruen-weiss-1000px.png" alt="" /></div>
        </a>
      </div></blockquote>
<p><code>알덴테</code>를 사용하면 맥북의 베터리를 80%까지만 충전되도록 제한을 걸어줄 수 있다.<br>
무료 버전과 pro 버전 2가지가 있는데 80% 제한만 걸어두는 건 무료 버전에서도 지원하고 pro 버전에서는 이것저것 기능이 추가 된다.<br>
그중 제일 맘에 드는 기능은 메뉴 막대의 aldente의 icon을 MacOS 기본 베터리 아이콘처럼 변경해 주는 기능이 있다.</p>
<blockquote>
<p>원래 icon
<img src="/images/macos-recommend-app/aldente-1.png" alt="원래 icon 이미지"></p>
</blockquote>
<blockquote>
<p>네이티브 배터리 icon 이미지
<img src="/images/macos-recommend-app/aldente-2.png" alt="네이티브 배터리 icon 이미지"></p>
</blockquote>
<p>또한 pro 버전에서는 아래 이미지처럼 이것저것 정보를 알려준다.<br>
(<s>볼 일이 없긴 하다</s>)
<img src="/images/macos-recommend-app/aldente-3.png" alt="aldente info 이미지"></p>
<p>위에서 설명해 준 기능 말고도 <code>베터리 교정 모드</code>나 <code>과열 방지 모드</code> 맥세이프 led 제어 등등 다양한 기능이 있으니 한번 구경해보면 좋을 거 같다.</p>
<div class="danger custom-block"><p class="custom-block-title">DANGER</p>
<p>지금도 그런지는 모르겠는데 앱에서 <strong>제한을 풀지 않고 앱을 지워버리면</strong> 충전 제한이 <strong>80%로 고정된 채로 살아야</strong> 한다는 걸 본 적이 있었는데 조심해서 나쁠 건 없으니 지우기 전엔 <strong>제한을 풀고 지우자</strong></p>
</div>
<h2 id="monitorcontrol" tabindex="-1">MonitorControl <a class="header-anchor" href="#monitorcontrol" aria-label="Permalink to &quot;MonitorControl&quot;">&ZeroWidthSpace;</a></h2>
<p>맥에서 사용하는 모니터마다 밝기를 따로따로 관리해 줄 수 있는 프로그램이다.<br>
모니터에 포커싱하고 있을 때 밝기 조절 단축키를 사용하면 그 모니터만 줄어든다.</p>
<blockquote>
<p><a href="https://github.com/MonitorControl/MonitorControl" target="_blank" rel="noreferrer">MonitorControl</a></p>

      <div>
        <a
          href="https://github.com/MonitorControl/MonitorControl"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #1e2327"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">GitHub - MonitorControl/MonitorControl: 🖥 Control your display's brightness & volume on your Mac as if it was a native Apple Display. Use Apple Keyboard keys or custom shortcuts. Shows the native macOS OSDs.</div>
            <div class="url-embed__desc">🖥 Control your display&#39;s brightness &amp; volume on your Mac as if it was a native Apple Display. Use Apple Keyboard keys or custom shortcuts. Shows the native macOS OSDs. - MonitorControl/Moni...</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://github.com/MonitorControl/MonitorControl</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://opengraph.githubassets.com/8c05f536888dd0a0d88f6840dce2003f1a3f66102e5bcd625e0b3d9d5f4f95bd/MonitorControl/MonitorControl" alt="" /></div>
        </a>
      </div></blockquote>
<p><img src="/images/macos-recommend-app/monitor-control-1.png" alt="MonitorControl menu bar image"></p>
<p>맥북 쓰면서 모니터 밝기 조절하면 맥북 화면만 줄어들거나 둘 다 같이 줄어들어서 모니터가 굉장히 어두워질 수 있는데 이거 쓰고 나서는 편안해졌다.</p>
<h2 id="macs-fan-control" tabindex="-1">Macs Fan Control <a class="header-anchor" href="#macs-fan-control" aria-label="Permalink to &quot;Macs Fan Control&quot;">&ZeroWidthSpace;</a></h2>
<p>air는 팬이 없으니 넘겨도 된다.</p>
<blockquote>
<p><a href="https://crystalidea.com/macs-fan-control" target="_blank" rel="noreferrer">Macs Fan Control</a></p>

      <div>
        <a
          href="https://crystalidea.com/macs-fan-control"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Macs Fan Control - control fans on Apple computers, also on Windows via Boot Camp</div>
            <div class="url-embed__desc">Control fans on Apple computers, also on Windows via Boot Camp. Monitoring of fan speed and temperature sensors. Solve fan noise and overheating problems, iMac HDD replacement</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://crystalidea.com/macs-fan-control</span>
            </div>
          </div>
          
        </a>
      </div></blockquote>
<p>맥에 있는 쿨러의 속도를 조절할 수 있게 해주는 프로그램이다.
<img src="/images/macos-recommend-app/macs-fan-control-1.png" alt="Macs Fan Control menu bar image"></p>
<p>혼자 너무 시끄럽게 돌고 있길래 찾아보고 설치해서 쓰고 있다.
보통 4000 정도로 해두면 시끄럽지도 않고 cpu가 시원해하는 거 같지만, 무거운 프로그램을 돌릴 때는 최고속도로 하거나 5500 정도로 설정해서 사용하고 있다.</p>
<p>pro 버전이 따로 있어서 돈을 내면 프로필을 저장해두고 사용할 수 있지만 나는 4000 고정이어서 무료 버전으로 잘 쓰고 있다.</p>
<h2 id="runcat" tabindex="-1">runcat <a class="header-anchor" href="#runcat" aria-label="Permalink to &quot;runcat&quot;">&ZeroWidthSpace;</a></h2>
<p>이번에 소개하는 프로그램 중에 제일 쓸모없다.<br>
하지만 이쁘다. 그래서 쓴다.</p>
<blockquote>
<p><a href="https://kyome.io/runcat/index.html?lang=en" target="_blank" rel="noreferrer">runcat</a></p>

      <div>
        <a
          href="https://kyome.io/runcat/index.html?lang=en"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">RunCat</div>
            <div class="url-embed__desc">Cat living in the menubar.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://kyome.io/runcat/index.html?lang=en</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://kyome.io/runcat/images/og_thumbnail.png" alt="" /></div>
        </a>
      </div></blockquote>
<p><img src="/images/macos-recommend-app/runcat-1.gif" alt="runcat menu bar image"></p>
<p>이렇게 고양이가 뛰어다니고 cpu 사용량에 따라서 속도가 빨라진다.</p>
<p><img src="/images/macos-recommend-app/runcat-2.png" alt="runcat menu bar info image"></p>
<p>그냥 mac의 시스템 현황 같은 거도 보여주고 runner 변경 또한 가능하니 다운받아서 맘에 드는 거로 사용하면 좋을 거 같다.
이모티콘 사듯이 runner를 따로 사서 쓸 수도 있다.</p>
]]></description>
            <content:encoded><![CDATA[<h2 id="maccy" tabindex="-1">Maccy <a class="header-anchor" href="#maccy" aria-label="Permalink to &quot;Maccy&quot;"></a></h2>
<p>진짜 <strong>G.O.A.T</strong><br>
제일 많이 사용하는 거 같다.</p>
<p>윈도에는 <code>클립보드</code>라는 이전에 복사해 뒀던 history를 보여주고 바로 붙여 넣을 수 있는 기능이 있다.<br>
그 클립보드 기능을 추가해 주는 프로그램이다.</p>
<blockquote>
<p><a href="https://maccy.app" target="_blank" rel="noreferrer">Maccy</a></p>

      <div>
        <a
          href="https://maccy.app"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Maccy - macOS clipboard manager</div>
            <div class="url-embed__desc">Clipboard manager for macOS which does one job - keep your copy history at hand. Lightweight. Open source. No fluff.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://maccy.app</span>
            </div>
          </div>
          
        </a>
      </div></blockquote>
<p>기본적으로 무료이고 공식 사이트에서 다운로드하려면 기부해야만 하는 거 같다(?)<br>
<a href="https://github.com/p0deje/Maccy" target="_blank" rel="noreferrer">maccy github</a>에 <code>Releases</code>에서 다운받거나 <code>brew</code> 써서 받으면 될 거 같다.</p>
<blockquote>
<p>brew 명령어</p>
</blockquote>
<div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span>brew install maccy</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p><img src="/images/macos-recommend-app/maccy-1.png" alt="maccy 설명 이미지"></p>
<p>저장하고 있을 항목 개수를 설정해 줄 수도 있고 단축키 또한 변경할 수 있어서 나는 아래처럼 변경해서 사용하고 있다.</p>
<div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span>command ⌘ + shift ⇧ + v</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>일반 복사는 <code>command + v</code>로 똑같이 사용하고 클립보드에서 들고 오고 싶을 땐 <code>shift</code>만 추가로 더 눌러주고 쓴다.<br>
색상 코드를 복사하면 왼쪽에 미리보기 형태로 색상을 보여주고 이미지를 복사하면 복사한 이미지 또한 미리보기로 보여준다.</p>
<h2 id="aldente" tabindex="-1">Aldente <a class="header-anchor" href="#aldente" aria-label="Permalink to &quot;Aldente&quot;"></a></h2>
<p>이 프로그램은 배터리 관련이라서 MacBook 사용자만 봐도 된다.</p>
<p>리튬이온 배터리는 20~80%만 사용할 때 베터리에 부담이 제일 적다고 한다.<br>
80 위로 충전하면 수명이 빨리 소모된다는 것이다.<br>
하지만 나처럼 하루 종일 책상에 올려다 놓고 일하는 사람들은 계속 충전을 해주고 있어야 하는 데 수시로 배터리 체크하면서 충전 했다, 안 했다하는 건 매우 귀찮은 일이다.</p>
<blockquote>
<p><a href="https://apphousekitchen.com/" target="_blank" rel="noreferrer">Aldente github</a></p>

      <div>
        <a
          href="https://apphousekitchen.com/"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #050515"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Home - AppHouseKitchen</div>
            <div class="url-embed__desc">It needs AlDente.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://apphousekitchen.com/</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://apphousekitchen.com/wp-content/uploads/2024/12/AHK-blaugruen-weiss-1000px.png" alt="" /></div>
        </a>
      </div></blockquote>
<p><code>알덴테</code>를 사용하면 맥북의 베터리를 80%까지만 충전되도록 제한을 걸어줄 수 있다.<br>
무료 버전과 pro 버전 2가지가 있는데 80% 제한만 걸어두는 건 무료 버전에서도 지원하고 pro 버전에서는 이것저것 기능이 추가 된다.<br>
그중 제일 맘에 드는 기능은 메뉴 막대의 aldente의 icon을 MacOS 기본 베터리 아이콘처럼 변경해 주는 기능이 있다.</p>
<blockquote>
<p>원래 icon
<img src="/images/macos-recommend-app/aldente-1.png" alt="원래 icon 이미지"></p>
</blockquote>
<blockquote>
<p>네이티브 배터리 icon 이미지
<img src="/images/macos-recommend-app/aldente-2.png" alt="네이티브 배터리 icon 이미지"></p>
</blockquote>
<p>또한 pro 버전에서는 아래 이미지처럼 이것저것 정보를 알려준다.<br>
(<s>볼 일이 없긴 하다</s>)
<img src="/images/macos-recommend-app/aldente-3.png" alt="aldente info 이미지"></p>
<p>위에서 설명해 준 기능 말고도 <code>베터리 교정 모드</code>나 <code>과열 방지 모드</code> 맥세이프 led 제어 등등 다양한 기능이 있으니 한번 구경해보면 좋을 거 같다.</p>
<div class="danger custom-block"><p class="custom-block-title">DANGER</p>
<p>지금도 그런지는 모르겠는데 앱에서 <strong>제한을 풀지 않고 앱을 지워버리면</strong> 충전 제한이 <strong>80%로 고정된 채로 살아야</strong> 한다는 걸 본 적이 있었는데 조심해서 나쁠 건 없으니 지우기 전엔 <strong>제한을 풀고 지우자</strong></p>
</div>
<h2 id="monitorcontrol" tabindex="-1">MonitorControl <a class="header-anchor" href="#monitorcontrol" aria-label="Permalink to &quot;MonitorControl&quot;"></a></h2>
<p>맥에서 사용하는 모니터마다 밝기를 따로따로 관리해 줄 수 있는 프로그램이다.<br>
모니터에 포커싱하고 있을 때 밝기 조절 단축키를 사용하면 그 모니터만 줄어든다.</p>
<blockquote>
<p><a href="https://github.com/MonitorControl/MonitorControl" target="_blank" rel="noreferrer">MonitorControl</a></p>

      <div>
        <a
          href="https://github.com/MonitorControl/MonitorControl"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #1e2327"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">GitHub - MonitorControl/MonitorControl: 🖥 Control your display's brightness & volume on your Mac as if it was a native Apple Display. Use Apple Keyboard keys or custom shortcuts. Shows the native macOS OSDs.</div>
            <div class="url-embed__desc">🖥 Control your display&#39;s brightness &amp; volume on your Mac as if it was a native Apple Display. Use Apple Keyboard keys or custom shortcuts. Shows the native macOS OSDs. - MonitorControl/Moni...</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://github.com/MonitorControl/MonitorControl</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://opengraph.githubassets.com/8c05f536888dd0a0d88f6840dce2003f1a3f66102e5bcd625e0b3d9d5f4f95bd/MonitorControl/MonitorControl" alt="" /></div>
        </a>
      </div></blockquote>
<p><img src="/images/macos-recommend-app/monitor-control-1.png" alt="MonitorControl menu bar image"></p>
<p>맥북 쓰면서 모니터 밝기 조절하면 맥북 화면만 줄어들거나 둘 다 같이 줄어들어서 모니터가 굉장히 어두워질 수 있는데 이거 쓰고 나서는 편안해졌다.</p>
<h2 id="macs-fan-control" tabindex="-1">Macs Fan Control <a class="header-anchor" href="#macs-fan-control" aria-label="Permalink to &quot;Macs Fan Control&quot;"></a></h2>
<p>air는 팬이 없으니 넘겨도 된다.</p>
<blockquote>
<p><a href="https://crystalidea.com/macs-fan-control" target="_blank" rel="noreferrer">Macs Fan Control</a></p>

      <div>
        <a
          href="https://crystalidea.com/macs-fan-control"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Macs Fan Control - control fans on Apple computers, also on Windows via Boot Camp</div>
            <div class="url-embed__desc">Control fans on Apple computers, also on Windows via Boot Camp. Monitoring of fan speed and temperature sensors. Solve fan noise and overheating problems, iMac HDD replacement</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://crystalidea.com/macs-fan-control</span>
            </div>
          </div>
          
        </a>
      </div></blockquote>
<p>맥에 있는 쿨러의 속도를 조절할 수 있게 해주는 프로그램이다.
<img src="/images/macos-recommend-app/macs-fan-control-1.png" alt="Macs Fan Control menu bar image"></p>
<p>혼자 너무 시끄럽게 돌고 있길래 찾아보고 설치해서 쓰고 있다.
보통 4000 정도로 해두면 시끄럽지도 않고 cpu가 시원해하는 거 같지만, 무거운 프로그램을 돌릴 때는 최고속도로 하거나 5500 정도로 설정해서 사용하고 있다.</p>
<p>pro 버전이 따로 있어서 돈을 내면 프로필을 저장해두고 사용할 수 있지만 나는 4000 고정이어서 무료 버전으로 잘 쓰고 있다.</p>
<h2 id="runcat" tabindex="-1">runcat <a class="header-anchor" href="#runcat" aria-label="Permalink to &quot;runcat&quot;"></a></h2>
<p>이번에 소개하는 프로그램 중에 제일 쓸모없다.<br>
하지만 이쁘다. 그래서 쓴다.</p>
<blockquote>
<p><a href="https://kyome.io/runcat/index?lang=en" target="_blank" rel="noreferrer">runcat</a></p>

      <div>
        <a
          href="https://kyome.io/runcat/index?lang=en"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">RunCat</div>
            <div class="url-embed__desc">Cat living in the menubar.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://kyome.io/runcat/index?lang=en</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://kyome.io/runcat/images/og_thumbnail.png" alt="" /></div>
        </a>
      </div></blockquote>
<p><img src="/images/macos-recommend-app/runcat-1.gif" alt="runcat menu bar image"></p>
<p>이렇게 고양이가 뛰어다니고 cpu 사용량에 따라서 속도가 빨라진다.</p>
<p><img src="/images/macos-recommend-app/runcat-2.png" alt="runcat menu bar info image"></p>
<p>그냥 mac의 시스템 현황 같은 거도 보여주고 runner 변경 또한 가능하니 다운받아서 맘에 드는 거로 사용하면 좋을 거 같다.
이모티콘 사듯이 runner를 따로 사서 쓸 수도 있다.</p>
<hr>
<p>다른 잘 쓰고 있는 앱들이 많긴 한데 이번 포스트랑은 잘 안 맞는 거 같아서 나중에 따로 올려야 할 거 같다.
<code>Obsidian</code>이라든지 <code>iTerm2</code>라던지….</p>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[Vitepress] Vitepress footnote tooltip]]></title>
            <link>https://leteu.dev/posts/vitepress-footnote-tooltip</link>
            <guid>https://leteu.dev/posts/vitepress-footnote-tooltip</guid>
            <pubDate>Tue, 20 Jan 1970 21:29:16 GMT</pubDate>
            <content:encoded><![CDATA[<p>Vitepress에서 각주 기능을 넣고 확인해보니 tooltip처럼 뿅하고 나오는게 없길래 그냥 하나 만들었다.
이게 정답인지 아닌지는 모르겠지만 나는 마음에 든다.</p>
<p><a href="#_3-완성된-코드">완성 코드 바로가기</a></p>
<h2 id="_1-markdown-it-footnote" tabindex="-1">1. markdown-it-footnote <a class="header-anchor" href="#_1-markdown-it-footnote" aria-label="Permalink to &quot;1. markdown-it-footnote&quot;"></a></h2>
<p>우선 vitepress는 <code>markdown-it</code>를 통해 markdown을 html로 변환해주고 있다.<br>
그래서 각주를 달려고 하면 <code>markdown-it-footnote</code>이라는 확장 패키지를 통해 각주 기능을 추가 할 수 있다.</p>
<h2 id="_1-1-설치" tabindex="-1">1-1. 설치 <a class="header-anchor" href="#_1-1-설치" aria-label="Permalink to &quot;1-1. 설치&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> i</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> markdown-it-footnote</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># or</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> markdown-it-footnote</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># or</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> i</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -D</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> markdown-it-footnote</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># or</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bun</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> markdown-it-footnote</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -d</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p>사용중인 패키지 매니저 사용해서 적절하게 설치해준다.</p>
<h2 id="_1-2-적용-및-사용" tabindex="-1">1-2. 적용 및 사용 <a class="header-anchor" href="#_1-2-적용-및-사용" aria-label="Permalink to &quot;1-2. 적용 및 사용&quot;"></a></h2>
<p><code>&lt;vitepress root&gt;/.vitepress/config.mts</code>에 가보면 vitepress의 기본적인 설정을 해줄수있다.</p>
<div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> footnote </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'markdown-it-footnote'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  markdown: {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    config</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">md</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      md.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(footnote)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    },</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p>이렇게 <code>markdown-it</code> 라이브러리에 <code>footnote</code> 기능을 사용하도록 해줄 수 있다.</p>
<div class="language-md vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">hello[</span><span style="--shiki-light:#032F62;--shiki-light-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline">^1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">[</span><span style="--shiki-light:#032F62;--shiki-light-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline">^1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]: </span><span style="--shiki-light:#24292E;--shiki-light-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline">world</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>hello<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
<p>이렇게 사용해 줄 수 있다.<br>
하지만 각주 하나 보겠다고 아래 내렸갔다가 위로 다시 올라갔다가 url에는 이상한 id값 계속 붙고...<br>
지저분하다.</p>
<h2 id="_2-툴팁-제작" tabindex="-1">2. 툴팁 제작 <a class="header-anchor" href="#_2-툴팁-제작" aria-label="Permalink to &quot;2. 툴팁 제작&quot;"></a></h2>
<p>기본적으로 툴팁이 있어야 붙이든 말든 하기 때문에 codepen에서 적당히 이쁜 툴팁을 찾아왔다.<br>
맘에 안들면 다른거 찾아와서 똑같이 따라하면 된다.<br>
나는 아래 링크의 tooltip을 사용해서 하려고 한다.</p>
<p><a href="https://codepen.io/tutsplus/pen/WROvdG" target="_blank" rel="noreferrer">tutsplus - CSS Tooltip Magic</a></p>
<h3 id="_2-1-tooltip-component" tabindex="-1">2-1. Tooltip Component <a class="header-anchor" href="#_2-1-tooltip-component" aria-label="Permalink to &quot;2-1. Tooltip Component&quot;"></a></h3>
<p>각주는 그대로 놔두고 뭔가 추가로 붙여주기만 하면 될거같아서 slot에는 각주를 넣고 그 각주에 tooltip만 붙여주면 될거같다.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-y4Qv_" id="tab-ilXqgg2" checked><label data-title="FootnoteTooltip.vue" for="tab-ilXqgg2">FootnoteTooltip.vue</label><input type="radio" name="group-y4Qv_" id="tab-2iWXMha" ><label data-title="theme/index.ts" for="tab-2iWXMha">theme/index.ts</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> props</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineProps</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  footnote: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    type: [Number, String],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    required: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">style</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"scss"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">style</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  enhanceApp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({ </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">app</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">router</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">siteData</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    app.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'FootnoteTooltip'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, FootnoteTooltip)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">} </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">satisfies</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> Theme</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></div></div>
<p>FootnoteTooltip 컴포넌트를 만들어준 뒤 어디서든 사용하기 위해서 <code>.vitepress/theme/index.ts</code> 전역 컴포넌트로 지정해줬다.<br>
컴포넌트 이름이 너무 긴거 같으면 맘대로 바꿔넣어두면 된다.</p>
<p><code>&lt;style&gt;</code> 태그에 <code>scope</code> 달아두면 컴포넌트 안에서만 쓸 수 있으니까 지워야한다.</p>
<p><code>&lt;template&gt;</code> 부분은 각주를 그대로 받아서 사용할거라 default slot만 추가해서 마무리 한다.</p>
<p><code>prop</code>으로는 굳이 각주를 다 안가지고 와도 문서 하단에 뿌려둘것이기 때문에 굳이 전문을 가지고 오지말고 각주 번호나 이름을 가져오면 될거같다.</p>
<h3 id="_2-2-본문-각주-바로가기에-data-tooltip-추가" tabindex="-1">2-2. 본문 각주 바로가기에 data-tooltip 추가 <a class="header-anchor" href="#_2-2-본문-각주-바로가기에-data-tooltip-추가" aria-label="Permalink to &quot;2-2. 본문 각주 바로가기에 data-tooltip 추가&quot;"></a></h3>
<p>각주의 변환된 html 코드를 확인해 보니 아래와 같은 형태인것을 알 수 있다.</p>
<div class="language-html vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">a</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  href</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"#fn1"</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"fnref1"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  >[1]&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">a</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">...</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">li</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"fn1"</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  class</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"footnote-item"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">p</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    world</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">a</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      href</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"#fnref1"</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      class</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"footnote-backref"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      >↩︎&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">a</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">p</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">li</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div><p>본문에 써지는 <code>&lt;a&gt;</code>태그의 id는 <code>#fnref + footnote</code><br>
하단에 써지는 <code>&lt;li&gt;</code>태그의 id는 <code>#fn + footnote</code></p>
<p>와 같은 형태인 것을 확인 할 수 있었다.</p>
<p>그래서 li의 텍스트를 긁어와서 a에 <code>dataset.tooltip</code>으로 넣어주면 나중에 스타일 붙일때 사용할 수 있을거 같다.<br>
아래는 위에서 설명한 내용에 대한 코드다.</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { nextTick, onMounted } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> props</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineProps</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  footnote: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    type: [Number, String],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    required: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">onMounted</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  nextTick</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // &#x3C;li> 태그 들고오고</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> fn</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getElementById</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">`fn${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">props</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">footnote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">}`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // &#x3C;a> 태그 들고와서</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> fnref</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getElementById</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">`fnref${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">props</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">footnote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">}`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // &#x3C;li> 클론 하나 만들어 준 뒤</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> fnClone</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fn.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">querySelector</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'p'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">cloneNode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> HTMLElement</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 뒤에 붙는 화살표 지워주고</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    fnClone.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">removeChild</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(fnClone.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">querySelector</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'a'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // &#x3C;a> 태그에 data-tooltip에 넣어준다.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    fnref.dataset.tooltip </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fnClone.innerText</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  })</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div><h3 id="_2-3-스타일-붙이기" tabindex="-1">2-3. 스타일 붙이기 <a class="header-anchor" href="#_2-3-스타일-붙이기" aria-label="Permalink to &quot;2-3. 스타일 붙이기&quot;"></a></h3>
<p>코드펜에서 찾은 맘에 드는 툴팁을 아래 코드처럼 <code>[data-tooltip]</code>에 적절하게 적용시켜 준다.</p>
<div class="language-css vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">[</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">data-tooltip</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">] {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  /* 여기에 뭔가 하면 각주에 적용될거다 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h2 id="_3-완성된-코드" tabindex="-1">3. 완성된 코드 <a class="header-anchor" href="#_3-완성된-코드" aria-label="Permalink to &quot;3. 완성된 코드&quot;"></a></h2>
<div class="language-md vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">hello&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">FootnoteTooltip</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> footnote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"2"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>[</span><span style="--shiki-light:#032F62;--shiki-light-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline">^2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">FootnoteTooltip</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">[</span><span style="--shiki-light:#032F62;--shiki-light-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline">^2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]: </span><span style="--shiki-light:#24292E;--shiki-light-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline">world</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>hello<FootnoteTooltip footnote="2"><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></FootnoteTooltip></p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-SDL75" id="tab-wVv3YR3" checked><label data-title="FootnoteTooltip.vue" for="tab-wVv3YR3">FootnoteTooltip.vue</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { nextTick, onMounted } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> props</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineProps</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  footnote: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    type: [Number, String],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    required: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">onMounted</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  nextTick</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> fn</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getElementById</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">`fn${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">props</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">footnote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">}`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> fnref</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getElementById</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">`fnref${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">props</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">footnote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">}`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> fnClone</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fn.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">querySelector</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'p'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">cloneNode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> HTMLElement</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    fnClone.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">removeChild</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(fnClone.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">querySelector</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'a'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    fnref.dataset.tooltip </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> fnClone.innerText</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  })</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">style</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"scss"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">[data-tooltip] {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  position: relative; /* opinion 1 */</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;::before,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;::after {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    text-transform: none; /* opinion 2 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    font-size: 0.9em; /* opinion 3 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    line-height: 1;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    user-select: none;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    pointer-events: none;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    position: absolute;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    display: none;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    opacity: 0;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;::before {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    content: '';</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    border: 5px solid transparent; /* opinion 4 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    z-index: 1001; /* absurdity 1 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;::after {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    content: attr(data-tooltip); /* magic! */</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    /* most of the rest of this is opinion */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    font-family: Helvetica, sans-serif;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    text-align: center;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    /*</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      Let the content set the size of the tooltips</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      but this will also keep them from being obnoxious</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    min-width: 3em;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    white-space: nowrap;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    padding: 1ch 1.5ch;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    border-radius: 0.3ch;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    box-shadow: 0 1em 2em -0.5em rgba(0, 0, 0, 0.35);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    background: #555;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    color: #fff;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    z-index: 1000; /* absurdity 2 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;:hover::before,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;:hover::after {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    display: block;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    animation: tooltips-vert 300ms ease-out forwards;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    left: 50%;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    transform: translate(-50%, -0.5em);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;::before {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    bottom: 100%;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    border-bottom-width: 0;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    border-top-color: #555;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x26;::after {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    bottom: calc(100% + 5px);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/* don't show empty tooltips */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">[data-tooltip='']::before,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">[data-tooltip='']::after {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  display: none !important;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/* KEYFRAMES */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">@keyframes tooltips-vert {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  to {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    opacity: 1;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    transform: translate(-50%, 0);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">@keyframes tooltips-horz {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  to {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    opacity: 1;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    transform: translate(0, -50%);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">style</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br><span class="line-number">90</span><br><span class="line-number">91</span><br><span class="line-number">92</span><br><span class="line-number">93</span><br><span class="line-number">94</span><br><span class="line-number">95</span><br><span class="line-number">96</span><br><span class="line-number">97</span><br><span class="line-number">98</span><br><span class="line-number">99</span><br><span class="line-number">100</span><br><span class="line-number">101</span><br><span class="line-number">102</span><br><span class="line-number">103</span><br><span class="line-number">104</span><br><span class="line-number">105</span><br><span class="line-number">106</span><br><span class="line-number">107</span><br><span class="line-number">108</span><br><span class="line-number">109</span><br><span class="line-number">110</span><br></div></div></div></div>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>world <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>world <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[ci cd] Docker compose로 Vitepress 배포하기]]></title>
            <link>https://leteu.dev/posts/deploy-vitepress-with-docker-compose</link>
            <guid>https://leteu.dev/posts/deploy-vitepress-with-docker-compose</guid>
            <pubDate>Tue, 20 Jan 1970 21:29:11 GMT</pubDate>
            <content:encoded><![CDATA[<div class="info custom-block"><p class="custom-block-title">INFO</p>
<p>이 포스트는 아래 링크의 포스트에 연결되는 내용이니 혹시나 안 보고 왔으면 보고 오도록<br>
<a href="/posts/deploy-vitepress-with-docker">[ci cd] Docker로 Vitepress 배포하기</a></p>
</div>
<p>이번 포스트는 이전에 너무 길게 적어서 짧게 쓰고 넘어가려고 한다.</p>
<h2 id="_1-도커-컴포즈-작성" tabindex="-1">1. 도커 컴포즈 작성 <a class="header-anchor" href="#_1-도커-컴포즈-작성" aria-label="Permalink to &quot;1. 도커 컴포즈 작성&quot;"></a></h2>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-uz8vW" id="tab-ezYZfDh" checked><label data-title="docker-compose.yml" for="tab-ezYZfDh">docker-compose.yml</label></div><div class="blocks">
<div class="language-yml vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">yml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">version</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"> # docker compose가 구버전인 사람만 붙여주면 된다. 난 최신 버전써서 안붙여도 된다.</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">blog</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">services</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">  docs</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">    build</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">.</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">    container_name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">blog</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">    ports</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'8080:80'</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">    stdin_open</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">    tty</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div></div></div>
<h3 id="_1-1-version" tabindex="-1">1-1. version <a class="header-anchor" href="#_1-1-version" aria-label="Permalink to &quot;1-1. version&quot;"></a></h3>
<p>이전에 <code>docker-compose.yml</code> 작성해 봤다고 하는 사람들은 <code>version</code> 왜 안 적어도 되냐고 할 수도 있다.<br>
최신 버전의 <code>docker compose</code>에서는 없어졌다. 이제 안 적어도 된다.</p>
<h3 id="_1-2-name" tabindex="-1">1-2. name <a class="header-anchor" href="#_1-2-name" aria-label="Permalink to &quot;1-2. name&quot;"></a></h3>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ps</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>했을 때 나오는 <code>docker compose</code>의 이름이다.</p>
<h3 id="_1-3-services" tabindex="-1">1-3. services <a class="header-anchor" href="#_1-3-services" aria-label="Permalink to &quot;1-3. services&quot;"></a></h3>
<p>원래 같았으면 services에 다른 docker파일에 있는 이것저것 다 한 번에 띄우고 한 네트워크로 묶겠지만 우리는 정적파일 배포하는 nginx 컨테이너 하나밖에 없기 때문에 이 밑에 하나만 할 거다.</p>
<p>서비스 이름은 마음대로 지어도 되는데 나는 그래도 문서니까 <code>docs</code>라고 이름 붙여뒀다.</p>
<h4 id="_1-3-1-build" tabindex="-1">1-3-1. build <a class="header-anchor" href="#_1-3-1-build" aria-label="Permalink to &quot;1-3-1. build&quot;"></a></h4>
<p>빌드는 Dockerfile의 위치를 나타내게 된다.<br>
다른 곳에 올려뒀으면 <code>image</code>라고 적어서 외부 저장소의 이미지를 바로 작성해 두거나 로컬에서 빌드한 이미지를 사용하겠지만<br>
나는 이미 빌드하는 것조차 귀찮기 때문에 그냥 <code>docker compose</code>가 알아서 내 dockerfile 가지고 혼자 이미지 만들어서 띄웠으면 좋겠기에 현재 경로인 <code>. (점)</code>으로 적어뒀다.</p>
<h4 id="_1-3-2-container-name" tabindex="-1">1-3-2. container_name <a class="header-anchor" href="#_1-3-2-container-name" aria-label="Permalink to &quot;1-3-2. container_name&quot;"></a></h4>
<p>안 적어줘도 알아서 아무 이름 붙여다 두는데, 나중에 exec 하거나 할 때 그거 검색해서 찾고 그러는 거 귀찮아서 미리 <code>blog</code>라고 고정해 뒀다.<br>
맘에 드는 거로 바꿔서 작성해 둬도 된다. 오늘은 안 쓸 거니까</p>
<h4 id="_1-3-3-ports" tabindex="-1">1-3-3. ports <a class="header-anchor" href="#_1-3-3-ports" aria-label="Permalink to &quot;1-3-3. ports&quot;"></a></h4>
<p><code>docker run</code> 할 때 <code>-p</code> 옵션 줘서 하던 그거다.<br>
모르겠으면 이전글 다시 보고 오는 게 좋을 거 같다.</p>
<h4 id="_1-3-4-stdin-open-tty" tabindex="-1">1-3-4. stdin_open &amp; tty <a class="header-anchor" href="#_1-3-4-stdin-open-tty" aria-label="Permalink to &quot;1-3-4. stdin_open &amp; tty&quot;"></a></h4>
<p>가끔 컨테이너 내부에 들어가서 확인하거나 할 때가 있을 수도 있는데 그렇게 하려면 이거 적어둬야 한다.</p>
<h2 id="_2-실행" tabindex="-1">2. 실행 <a class="header-anchor" href="#_2-실행" aria-label="Permalink to &quot;2. 실행&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> up</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -d</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># 구버전일 경우</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker-compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> up</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -d</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>뒤에 붙여주는 <code>-d</code> 옵션은 뒤에서 알아서 혼자 돌고 있으라는 소리다.<br>
더 정확하고 자세히 알고 싶다면 <code>docker compose</code> 공식 문서를 보자</p>
<h2 id="_3-업데이트" tabindex="-1">3. 업데이트 <a class="header-anchor" href="#_3-업데이트" aria-label="Permalink to &quot;3. 업데이트&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> up</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -d</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --build</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># 구버전일 경우</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker-compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> up</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -d</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --build</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p><code>--build</code> 옵션은 위에서 말한 공식 문서 한 번이라도 보고 왔으면 알 텐데 모르겠으면 진짜 한 번만 보러 가라.<br>
해당 명령어가 실패하면 기존에 돌고 있던 컨테이너가 그대로 돌고 있을 것이고 성공하면 업데이트가 바로 된다.<br>
일단 내가 작성한 dockerfile 기준으론 이렇게만 적어도 업데이트가 될 텐데 다른 상황인 사람들은 <a href="#_4-중단">down</a>한번 해주고 다시 <a href="#_2-실행">up</a> 해주면 될 거다.</p>
<h2 id="_4-중단" tabindex="-1">4. 중단 <a class="header-anchor" href="#_4-중단" aria-label="Permalink to &quot;4. 중단&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> down</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># 구버전일 경우</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker-compose</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> down</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h2 id="마치며" tabindex="-1">마치며 <a class="header-anchor" href="#마치며" aria-label="Permalink to &quot;마치며&quot;"></a></h2>
<p><code>docker run</code> 해가 지고 이것저것 옵션 붙여가면서 꾸역꾸역 실행하는 거보다는 <code>docker compose</code> 파일 하나 작성해 두고 실행하면 편하고 좋은 거 같다.<br>
<s>팀원들 알려줄 때도 명령어 한 줄만 알려줘도 돼서 편하고</s></p>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[ci cd] Docker로 Vitepress 배포하기]]></title>
            <link>https://leteu.dev/posts/deploy-vitepress-with-docker</link>
            <guid>https://leteu.dev/posts/deploy-vitepress-with-docker</guid>
            <pubDate>Tue, 20 Jan 1970 21:29:10 GMT</pubDate>
            <content:encoded><![CDATA[<p>블로그를 Tistory에서 직접 사이트 만들어서 하고 싶은 마음이 들었다.<br>
하지만 역시 처음부터 다 하는 건 귀찮을 거 같아서 vitepress라는 vue 개발팀에서 만든 ssg<FootnoteTooltip footnote="1"><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></FootnoteTooltip>툴에 테마만 좀 변경하고 추가해서 쓰면 쉽겠다 싶어서 뚝딱뚝딱 만들었다.<br>
만들고 나니 배포해야 하는데 Ubuntu 서버에 nginx니 node니, 설치해서 쓰고 싶진 않아서<FootnoteTooltip footnote="2"><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></FootnoteTooltip> 포스트도 쓸 겸 해서 이번에도 docker로 배포하고 작성해 본다.</p>
<h2 id="_1-vitepress-build" tabindex="-1">1. vitepress build <a class="header-anchor" href="#_1-vitepress-build" aria-label="Permalink to &quot;1. vitepress build&quot;"></a></h2>
<p>이 부분 넘겨도 되는데 안 넘겼으면 좋겠다.<br>
아래 명령어를 통해 markdown 파일들을 정적 파일로 빌드 해줄 수 있다.</p>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">vitepress</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> build</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>혹은 처음 세팅할 때 package.json에 script 추가하기를 선택하여 빌드 명령어 등을 추가했다면 아래 명령어로도 사용 가능하다.</p>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">&#x3C;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">사용한 패키지 매니저</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> run docs:build</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">## ex)</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> docs:build</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>이렇게 빌드하고 나면 <code>.vitepress/dist</code> 폴더에 정적 파일들이 담겨서 나오게 된다.</p>
<h2 id="_2-dockerfile-build-stage-작성" tabindex="-1">2. Dockerfile - build stage 작성 <a class="header-anchor" href="#_2-dockerfile-build-stage-작성" aria-label="Permalink to &quot;2. Dockerfile - build stage 작성&quot;"></a></h2>
<div class="info custom-block"><p class="custom-block-title">INFO</p>
<p>dockerfile 작성 설명 별로 안 궁금하고 바로 완성된 코드만 보고 싶다면?</p>
<blockquote>
<p><a href="#_4-완성된-dockerfile">여기 클릭</a></p>
</blockquote>
</div>
<p>위에서 해줬던 빌드는 사실 Docker 컨테이너 내부에서 실행되어도 상관이 없기 때문에 Dockerfile에서 빌드하는 부분을 작성해 준다.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># Build</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">FROM</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> node:20-alpine </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> build</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">ENV</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> PNPM_HOME=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"/pnpm"</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">ENV</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> PATH=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"$PNPM_HOME:$PATH"</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> corepack enable</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">WORKDIR</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /app</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> . .</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> apk --no-cache add git</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> pnpm run docs:build</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p><code>build stage</code>로 하는 이유는 냅다 모든 과정을 다 이미지로 구워 버리면 이미지의 용량이 쓸데없이 커지게 된다.<br>
build 후 dist 폴더만 <code>deploy stage</code>로 옮긴 후 <code>deploy stage</code>만 이미지로 구워서 쓸 예정이다.</p>
<h3 id="_2-1-from" tabindex="-1">2-1. FROM <a class="header-anchor" href="#_2-1-from" aria-label="Permalink to &quot;2-1. FROM&quot;"></a></h3>
<p>docs:build를 실행시켜야하기 때문에 node가 있는 컨테이너에서 작업을 해야 한다.<br>
그래서 <code>node:20-apline</code><FootnoteTooltip footnote="3"><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></FootnoteTooltip>을 base image로 사용하여 <code>build stage</code>를 만들어준다.</p>
<h3 id="_2-2-env" tabindex="-1">2-2. ENV <a class="header-anchor" href="#_2-2-env" aria-label="Permalink to &quot;2-2. ENV&quot;"></a></h3>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">ENV</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> PNPM_HOME=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"/pnpm"</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">ENV</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> PATH=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"$PNPM_HOME:$PATH"</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> corepack enable</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>이 3줄짜리 코드는 <code>node:20-alpine</code>에서 pnpm을 사용하기 위해 작성했다.<br>
관련 내용은 <a href="https://pnpm.io/docker" target="_blank" rel="noreferrer">여기</a>서 확인이 가능하다.</p>

      <div>
        <a
          href="https://pnpm.io/docker"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Working with Docker | pnpm</div>
            <div class="url-embed__desc">It is impossible to create reflinks or hardlinks between a Docker container and the host filesystem during build time.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://pnpm.io/docker</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://pnpm.io/img/ogimage.png" alt="" /></div>
        </a>
      </div><h3 id="_2-3-workdir" tabindex="-1">2-3. WORKDIR <a class="header-anchor" href="#_2-3-workdir" aria-label="Permalink to &quot;2-3. WORKDIR&quot;"></a></h3>
<p>컨테이너 내부의 어느 경로에서 작업을 할지 정하는 부분이다.<br>
보통 <code>/app</code>에서 한다.</p>
<h3 id="_2-4-copy" tabindex="-1">2-4. COPY <a class="header-anchor" href="#_2-4-copy" aria-label="Permalink to &quot;2-4. COPY&quot;"></a></h3>
<p>컨테이너에 Dockerfile이 위치한 곳의 파일을 복사해 갈 때 사용한다.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> &#x3C;외부 경로> &#x3C;컨테이너 내부 경로></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># vitepress 위치가 루트에 있다면</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> . .</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># vitepress 위치가 `docs` 폴더에 있다면</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ./docs .</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>나는 <code>COPY . .</code> 이라고 작성했으니 있는 파일 다 들고 가라고 한 것이다.<br>
여기서 불필요한 파일(ex. node_module, dist, README.md, ... )은 굳이 들고 갈 필요가 없으니 <code>.gitignore</code> 파일을 만들어 주듯이 <code>.dockerignore</code>을 통해 제외해 준다.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-bUmcC" id="tab-r0Q6pLg" checked><label data-title=".dockerignore" for="tab-r0Q6pLg">.dockerignore</label></div><div class="blocks">
<div class="language-txt vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">txt</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span>node_modules</span></span>
<span class="line"><span>*.log</span></span>
<span class="line"><span>.DS_Store</span></span>
<span class="line"><span>.idea</span></span>
<span class="line"><span>.temp</span></span>
<span class="line"><span>.vite_opt_cache</span></span>
<span class="line"><span>.vscode</span></span>
<span class="line"><span>pnpm-global</span></span>
<span class="line"><span>build</span></span>
<span class="line"><span>cache</span></span>
<span class="line"><span>dist</span></span>
<span class="line"><span>temp</span></span>
<span class="line"><span>examples-temp</span></span>
<span class="line"><span>license</span></span>
<span class="line"><span>README.md</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div></div></div>
<h3 id="_2-5-run" tabindex="-1">2-5. RUN <a class="header-anchor" href="#_2-5-run" aria-label="Permalink to &quot;2-5. RUN&quot;"></a></h3>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>dependencies 들을 설치해 주는 부분이다.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> pnpm install</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>이렇게만 작성해도 될 텐데 뭐 이렇게 어렵게 작성해 뒀냐고 한다면<br>
docker image를 만들 때마다 처음부터 패키지를 install 할거였으면 pnpm이니 yarn 을 쓸 이유가 없다.<br>
그래서 캐시된 패키지도 사용해서 쓰기 위해 이렇게 작성했다.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> apk --no-cache add git</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>vitepress의 lastUpdate 옵션을 사용하기 위해 git을 설치하는 곳이다.<br>
lastUpdate 안 쓸 거면 안 적어도 되고 <a href="#_2-1-from">2-1. FROM</a>에서도 <code>node:20-slim</code> 사용해도 된다.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> pnpm run docs:build</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>드디어 빌드하는 부분이다.<br>
빌드를 하게 되면 컨테이너 내부에 <code>/app/.vitepress/dist</code> 경로에 빌드가 되어있을 것이다.
이제 배포하기 위한 정적 파일이 준비되었다.</p>
<h2 id="_3-dockerfile-deploy-작성" tabindex="-1">3. Dockerfile - deploy 작성 <a class="header-anchor" href="#_3-dockerfile-deploy-작성" aria-label="Permalink to &quot;3. Dockerfile - deploy 작성&quot;"></a></h2>
<p>이제 빌드된 파일을 배포하기 위한 배포용 stage를 만들어 볼 것이다.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># Deploy</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">FROM</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> nginx:alpine </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> deploy</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> --from=build /app/.vitepress/dist /usr/share/nginx/html</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> default.conf /etc/nginx/conf.d/default.conf</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">EXPOSE</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> 80</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">CMD</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"nginx"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"-g"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"daemon off;"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><h3 id="_3-1-from" tabindex="-1">3-1. FROM <a class="header-anchor" href="#_3-1-from" aria-label="Permalink to &quot;3-1. FROM&quot;"></a></h3>
<p>정적 html, css, js 및 asset들을 전달하기 위한 웹서버가 필요하다.<br>
nginx로 할 거다.</p>
<p><code>nginx:alpine</code> 이미지를 베이스 이미지로 사용한다고 작성하고 시작해 보겠다.</p>
<h3 id="_3-2-copy" tabindex="-1">3-2. COPY <a class="header-anchor" href="#_3-2-copy" aria-label="Permalink to &quot;3-2. COPY&quot;"></a></h3>
<p>아까 빌드했던 dist 파일을 <code>deploy stage</code>로 들고 오는 부분이다.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> --from=build /app/.vitepress/dist /usr/share/nginx/html</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>아까는 dockerfile이 존재하는 root에서 파일을 들고 왔지만 <code>--from=build</code> 옵션을 통해 <code>build stage</code>에서 파일을 들고 오게 된다.<br>
nginx의 root 경로인 <code>/usr/share/nginx/html</code>에 <code>dist</code>폴더의 내용을 다 옮겨주도록 하자.</p>
<p>nginx 설정 또한 컨테이너 빌드 할때마다 바뀔 테니 프로젝트 root든 어디에 <code>default.conf</code>라고 nginx 설정 파일을 만들어서 <code>deploy stage</code>로 들고 오도록 하자.</p>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> default.conf /etc/nginx/conf.d/default.conf</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>아래 코드는 내가 사용한 nginx 설정 파일이다.<br>
vitepress 공식 문서의 <a href="https://vitepress.vuejs.kr/guide/deploy#nginx" target="_blank" rel="noreferrer">여기</a>서 들고 왔다.<br>
rss 파일은 .xml 안 보이게 하고 싶어서 따로 <code>/rss</code>로 들어오면 <code>/rss.xml</code>을 전달해 주도록 살짝 수정해 줬다.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-9aclz" id="tab-rlZWN-h" checked><label data-title="default.conf" for="tab-rlZWN-h">default.conf</label></div><div class="blocks">
<div class="language-nginx vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">nginx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    gzip </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">on</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    gzip_types </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    listen </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">80</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    server_name </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">_;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    index </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">index;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    location</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> / </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        # content location</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        root </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/usr/share/nginx/html;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        # exact matches -> reverse clean urls -> folders -> not found</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        try_files </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">$uri $uri $uri/ </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">=404</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        # non existent pages</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        error_page </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">404</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /404;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        # a folder without index raises 403 in this setup</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        error_page </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">403</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /404;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        # adjust caching headers</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        # files in the assets folder have hashes filenames</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        location</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> ~*</span><span style="--shiki-light:#032F62;--shiki-dark:#DBEDFF"> ^/assets/ </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">            expires </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">1y;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">            add_header </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">Cache-Control </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"public, immutable"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    location</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#DBEDFF"> /rss </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        root </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/usr/share/nginx/html;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        try_files </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">/rss.xml </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">=404</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        default_type </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">application/rss+xml;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        add_header </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">Content-Type application/rss+xml;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">        add_header </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">X-Content-Type-Options nosniff;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br></div></div></div></div>
<h3 id="_3-3-expose" tabindex="-1">3-3. EXPOSE <a class="header-anchor" href="#_3-3-expose" aria-label="Permalink to &quot;3-3. EXPOSE&quot;"></a></h3>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">EXPOSE</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> 80</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>도커 컨테이너 내부에서 열린 포트를 host에서도 쓸 수 있게 해주는 부분이다.<br>
이거 안 넣어두면 말짱 도루묵이니 작성해서 80 포트 오픈해 주도록 하자.</p>
<div class="danger custom-block"><p class="custom-block-title">DANGER</p>
<p>다른 포트로 열고 싶은 건 알겠으니 일단 이렇게 작성하도록 하자.<br>
나중에 컨테이너의 80 포트랑 host의 다른 포트랑 연결하는 거 알려줄 테니 조금만 참자.</p>
<blockquote>
<p><a href="#_5-2-실행">바로가기</a></p>
</blockquote>
</div>
<h3 id="_3-4-cmd" tabindex="-1">3-4. CMD <a class="header-anchor" href="#_3-4-cmd" aria-label="Permalink to &quot;3-4. CMD&quot;"></a></h3>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">CMD</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"nginx"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"-g"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"daemon off;"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>CMD는 해당 컨테이너가 수행하게 될 실행 명령어를 작성하는 부분이다.<br>
컨테이너가 최종적으로 수행할 부분이니 RUN이랑 혼동하지 말자.<br>
우리는 nginx 띄울 거니까 nginx 시작 명령어 작성해 주면 될 거 같다.</p>
<h2 id="_4-완성된-dockerfile" tabindex="-1">4. 완성된 Dockerfile <a class="header-anchor" href="#_4-완성된-dockerfile" aria-label="Permalink to &quot;4. 완성된 Dockerfile&quot;"></a></h2>
<div class="language-dockerfile vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># Build</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">FROM</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> node:20-alpine </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> build</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">ENV</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> PNPM_HOME=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"/pnpm"</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">ENV</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> PATH=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"$PNPM_HOME:$PATH"</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> corepack enable</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">WORKDIR</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /app</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> . .</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> apk --no-cache add git</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">RUN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> pnpm run docs:build</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># Deploy</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">FROM</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> nginx:alpine </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> deploy</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> --from=build /app/.vitepress/dist /usr/share/nginx/html</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">COPY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> default.conf /etc/nginx/conf.d/default.conf</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">EXPOSE</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> 80</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">CMD</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"nginx"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"-g"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"daemon off;"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br></div></div><h2 id="_5-이미지-굽기-실행" tabindex="-1">5. 이미지 굽기 &amp; 실행 <a class="header-anchor" href="#_5-이미지-굽기-실행" aria-label="Permalink to &quot;5. 이미지 굽기 &amp; 실행&quot;"></a></h2>
<h3 id="_5-1-이미지-생성" tabindex="-1">5-1. 이미지 생성 <a class="header-anchor" href="#_5-1-이미지-생성" aria-label="Permalink to &quot;5-1. 이미지 생성&quot;"></a></h3>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> build</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">이미지</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 이</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">름</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> .</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># ex)</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> build</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -t</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> blog</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> .</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>맨 마지막 <code>. (점)</code> 빼먹지 말도록 하자.<br>
build 관련 추가 옵션 및 명령어는 공식 문서 확인하는 거로~</p>
<h3 id="_5-2-실행" tabindex="-1">5-2. 실행 <a class="header-anchor" href="#_5-2-실행" aria-label="Permalink to &quot;5-2. 실행&quot;"></a></h3>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -it</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -p</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">원하는</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 포</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">트</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">:80</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">이미지</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 이</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">름</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># ex)</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -it</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 80:80</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> blog</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>run 관련 추가 옵션 및 명령어는 공식 문서 확인하는거로~</p>
<h2 id="_6-마치는-글" tabindex="-1">6. 마치는 글 <a class="header-anchor" href="#_6-마치는-글" aria-label="Permalink to &quot;6. 마치는 글&quot;"></a></h2>
<p>Docker compose를 통해서 실행하고 싶다면 <a href="/posts/deploy-vitepress-with-docker-compose">다음 포스트</a>를 확인하거나 내 블로그 github 가서 긁어가면 된다.<br>
서버 없는 사람들을 위해서 어차피 정적 파일밖에 없는 vitepress 파일들을 굳이 서버에 안 올리고 github page에 action을 통해서 main 브랜치에 push 될 때 배포되도록 하는 방법 역시 작성을 해둘 생각이다.</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Static Site Generator <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>기존에도 docker만 가지고 해서 서버에 잡다하게 설치하지 않고 사용하고 있었다. <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p><code>node:20-slim</code>을 사용하려고 했는데 vitepress에서 lastUpdate 옵션을 사용하려면 git이 필요한 이슈가 있어서 변경했다. <a href="#fnref3" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[Vuejs] Expose로 ref에서 함수 꺼내 쓰기]]></title>
            <link>https://leteu.dev/posts/vue-expose</link>
            <guid>https://leteu.dev/posts/vue-expose</guid>
            <pubDate>Tue, 20 Jan 1970 16:26:51 GMT</pubDate>
            <content:encoded><![CDATA[<p>사실 expose 하는 방법에 대한 글이라기 보단<br>
typescript로 작성할 때 자동완성 때문에  글 쓰게 됨<br>
난 vscode 쓰기 때문에 jetbrains에서는 원래 잘 나오고 있는지는 모른다.<br>
그래도 그냥 이렇게 명시적으로 해주는게 맞는거 같아 보인다.</p>
<h2 id="_1-하는-방법" tabindex="-1">1. 하는 방법 <a class="header-anchor" href="#_1-하는-방법" aria-label="Permalink to &quot;1. 하는 방법&quot;"></a></h2>
<p>아래 코드 처럼 <code>expose</code>에 함수를 넣어주기만 하면 된다.
그럼 사용은 가능하다.<br>
(<code>typescript</code>에서는 조금 더 해줘야 한다.)</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-rbg-e" id="tab-VnhWXGv" checked><label data-title="Composition API" for="tab-VnhWXGv">Composition API</label><input type="radio" name="group-rbg-e" id="tab-6-csSMx" ><label data-title="Optional API" for="tab-6-csSMx">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { ..., defineExpose } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> something</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'to do'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">defineExpose</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({ something })</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">...</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  method: {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    somthing: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> () {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'to do'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    },</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  expose: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'something'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">],</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div></div></div>
<h2 id="_2-사용법" tabindex="-1">2. 사용법 <a class="header-anchor" href="#_2-사용법" aria-label="Permalink to &quot;2. 사용법&quot;"></a></h2>
<p>위에서 작성한 Component를 <code>Child</code> 컴포넌트라고 하고 시작하겠다.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-syDMG" id="tab-Le5KN3F" checked><label data-title="부모 컴포넌트" for="tab-Le5KN3F">부모 컴포넌트</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Child</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> @click</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"onClick"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> Child </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'src/components/path/to/ChildComponent.vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> ChildRef</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ref</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">typeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> Child>()</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> onClick</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  ChildRef.value?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">something</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">()</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // 이러면 console에 `to do`라고 나올 거임</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div></div></div>
<p>이렇게 작성하면 실행은 될거다.</p>
<p>그런데 문제가 생겼다. 아주 <code>빅 이슈</code>다.</p>
<p>something이라는 method가 자동완성도 안되고 마우스를 얹어봐도 <code>any</code>라고만 나온다.<br>
<code>lint</code>가 함수가 존재하는지 여부도 몰라서 ? 붙이라고 뭐라고 한다.<br>
내가 기대한 건<code>() =&gt; void</code>인데...<br>
멋이 없다.. 팀원들도 내가 만든 컴포넌트를 사용하면서 expose된 함수가 뭔지 모를거다...</p>
<h2 id="_3-멋-생성" tabindex="-1">3. 멋 생성 <a class="header-anchor" href="#_3-멋-생성" aria-label="Permalink to &quot;3. 멋 생성&quot;"></a></h2>
<p>애초에 import 저렇게 해오는 거부터 멋이 없다. 저거 먼저 해결해 보자.<br>
컴포넌트를 그냥 냅다 파일 경로로 들고오지 말고 깔끔하게 좀 쓰자.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-mjMiG" id="tab-0kTHeLb" checked><label data-title="src/components/path/to/index.ts" for="tab-0kTHeLb">src/components/path/to/index.ts</label></div><div class="blocks">
<div class="language-ts vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">default</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> Child } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> './ChildComponent.vue'</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div></div></div>
<p>이렇게 Child 컴포넌트가 있는 폴더에 <code>index.ts</code> 하나 만들어서 export 해주자.</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { Child } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'src/components/path/to'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">...</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>이런 느낌으로 <code>import</code> 해 올 수 있다. 벌써 멋있다.
하지만 이 글을 작성하게 된 이유인 내가 만든 멋있는 함수의 타입이 <code>any</code>라고 나오는 문제가 남아있다.
위 코드처럼 작성해도 여전히 타입을 찾지 못한다.</p>
<p>index.ts를 이렇게 수정해 주자</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-DkOPx" id="tab-oGIPITA" checked><label data-title="src/components/path/to/index.ts" for="tab-oGIPITA">src/components/path/to/index.ts</label></div><div class="blocks">
<div class="language-ts vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">default</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> Child } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> './ChildComponent.vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">type</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> Child</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> InstaceType</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">typeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> Child></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { Child }</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div></div></div>
<p>이제 Child 컴포넌트를 사용하는 부모 vue 파일에서도 코드를 약간 수정해 준다.<br>
(typeof 라고 작성해준거 제거)</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-pbyRQ" id="tab-X4I9i8g" checked><label data-title="부모 컴포넌트" for="tab-X4I9i8g">부모 컴포넌트</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark has-diff vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">Child</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> @click</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"onClick"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> Child </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'src/components/path/to/ChildComponent.vue'</span></span>
<span class="line"></span>
<span class="line diff remove"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> ChildRef</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ref</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">typeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> Child>()  </span></span>
<span class="line diff add"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> ChildRef</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ref</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Child</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>()  </span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div></div></div>
<p>이제 자동 완성도 잘 되고 타입 툴팁도 잘 뜨고 멋있다.
위에 index.ts에서 Child컴포넌트의 alias로 타입을 알려주었기 때문에 가능하다.</p>
<p>항상 멋있게 코드를 작성하자</p>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[JS] 네비게이션 타이밍 가져오기 (새로고침, 뒤로가기, 네비게이트)]]></title>
            <link>https://leteu.dev/posts/js-navigation-timing</link>
            <guid>https://leteu.dev/posts/js-navigation-timing</guid>
            <pubDate>Tue, 20 Jan 1970 15:26:09 GMT</pubDate>
            <content:encoded><![CDATA[<p>페이지 새로고침을 통해 화면에 왔을 경우 뭔가 처리를 하고 싶었는데<br>
죄다 beforeunload만 알려주길래 그냥 MDN 뒤져서 찾았다.<br>
메모 및 다른 사람들은 이런 삽질은 안했으면 좋겠어서 작성해둔다.</p>
<h2 id="_1-performancenavigationtiming" tabindex="-1">1. PerformanceNavigationTiming <a class="header-anchor" href="#_1-performancenavigationtiming" aria-label="Permalink to &quot;1. PerformanceNavigationTiming&quot;"></a></h2>
<p>이거 쓰면 다 해결됨</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">window.performance.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getEntriesByType</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'navigation'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><h2 id="_2-사용법" tabindex="-1">2. 사용법 <a class="header-anchor" href="#_2-사용법" aria-label="Permalink to &quot;2. 사용법&quot;"></a></h2>
<p>우리는 바로 전 화면의 타입을 봐야하니 위 코드에서 이렇게 <code>type</code>만 가져온다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">window.performance.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getEntriesByType</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'navigation'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)?.[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]?.type</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><h3 id="_2-1-navigate" tabindex="-1">2-1. navigate <a class="header-anchor" href="#_2-1-navigate" aria-label="Permalink to &quot;2-1. navigate&quot;"></a></h3>
<p>a태그나 location.href로 넘어왔거나 아래 3개의 경우가 아니면 이거다.</p>
<h3 id="_2-2-reload" tabindex="-1">2-2. reload <a class="header-anchor" href="#_2-2-reload" aria-label="Permalink to &quot;2-2. reload&quot;"></a></h3>
<p>내가 원하던거다. 새로고침으로 페이지에 들어왔을때 이거로 나온다.</p>
<h3 id="_2-3-back-forward" tabindex="-1">2-3. back_forward <a class="header-anchor" href="#_2-3-back-forward" aria-label="Permalink to &quot;2-3. back_forward&quot;"></a></h3>
<p>뒤로가기로 페이지에 오면 이거로 나온다.</p>
<h3 id="_2-4-prerender" tabindex="-1">2-4. prerender <a class="header-anchor" href="#_2-4-prerender" aria-label="Permalink to &quot;2-4. prerender&quot;"></a></h3>
<p>다음 라우팅을 위해 페이지 리소스가 필요할 수 있다는 힌트를 브라우저에게 전달해서 가져올때는 <code>navigate</code>가 아니라 <code>prerender</code>라고 나온다. 사전 렌더링 때는 이거로 나온다는 뜻이다.</p>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[JS] 배열 활용 map, filter, reduce, forEach, find 메소드]]></title>
            <link>https://leteu.dev/posts/js-array-higher-order-function</link>
            <guid>https://leteu.dev/posts/js-array-higher-order-function</guid>
            <pubDate>Tue, 20 Jan 1970 10:05:32 GMT</pubDate>
            <content:encoded><![CDATA[<p>자바스크립트를 하다 보면 엄청 자주 쓰게 되는 배열 조작 메소드들을 소개해보려고 한다.
알아두면 두고두고 쓸 일이 많다.
아래 링크에서 더 자세하고 많이 볼 수 있다.</p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array" target="_blank" rel="noreferrer">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array</a></p>

      <div>
        <a
          href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Array - JavaScript | MDN</div>
            <div class="url-embed__desc">다른 프로그래밍 언어의 배열과 마찬가지로, Array 객체는 여러 항목의 컬렉션을 단일 변수 이름 아래 저장할 수 있고, 일반적인 배열 연산을 수행하기 위한 멤버가 있습니다.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://developer.mozilla.org/mdn-social-share.d893525a4fb5fb1f67a2.png" alt="" /></div>
        </a>
      </div><ul>
<li>아래 나오는 친구들 모두 원래의 배열은 변형하지 않는다.</li>
</ul>
<h2 id="_1-map" tabindex="-1">1. Map <a class="header-anchor" href="#_1-map" aria-label="Permalink to &quot;1. Map&quot;"></a></h2>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">arr.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">map</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">callback</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(currentValue[, index[, array]])[, thisArg])</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>공식 문서에는 이렇게 설명하고 있다.<br>
저거보고 이해하는 사람은 이 글 안 보고 나가도 될 거 같다.</p>
<p>Map 메소드는 배열은 반복하여 현재 값, 현재 값의 인덱스, 돌고 있는 배열을 콜백으로 돌려준다.<br>
그리고 콜백의 리턴된 값으로 새 배열을 만들어준다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'홍길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">20</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'고길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'둘리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">4</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'햄토리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">40</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'루피'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">50</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 이렇게 작성하거나</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">map</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">item</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">index</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> item.id</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 화살표 함수니까 굳이 중괄호해서 return 하지 말고 이렇게도 가능하다.</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">map</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">item</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">index</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> item.id)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newArr) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// [1,2,3,4,5]</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>temp는 변경되지 않는다.</p>
<h2 id="_2-filter" tabindex="-1">2. Filter <a class="header-anchor" href="#_2-filter" aria-label="Permalink to &quot;2. Filter&quot;"></a></h2>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">arr.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">filter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">callback</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(element[, index[, array]])[, thisArg])</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>filter도 크게 다르지 않다.<br>
똑같이 현재 값, 현재 값의 인덱스, 돌고 있는 배열을 콜백으로 돌려준다.<br>
콜백의 리턴 값이 true인 것만 모아서 배열로 만들어준다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'홍길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">20</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'고길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'둘리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">4</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'햄토리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">40</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'루피'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">50</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">filter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">item</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">index</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // item의 age가 20보다 작거나 같으면 true 리턴</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> item.age </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">&#x3C;=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 20</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newArr) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// [{ id: 1, name: '홍길동', age: 20 }, { id: 3, name: '둘리', age: 10 }]</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h2 id="_3-reduce" tabindex="-1">3. Reduce <a class="header-anchor" href="#_3-reduce" aria-label="Permalink to &quot;3. Reduce&quot;"></a></h2>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">arr.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">reduce</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(callback[, initialValue])</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>얘는 공식 문서를 보면 솔직히 좀 특이하게 생기긴 했다.</p>
<p>누산기, 현재 값, 현재 값의 인덱스, 돌고 있는 배열을 콜백으로 돌려준다.
보통 숫자 배열 전부 더할 때 나배 열에 중복 값을 제거하여 사용할 때 쓸 수 있다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp1</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">4</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'홍길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">20</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'history'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'고길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'babyDooly'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'둘리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'babyDooly'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">4</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'햄토리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">40</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'hemtaro'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'루피'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">50</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'onepiece'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr1</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp1.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">reduce</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">acc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">cur</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> acc </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> cur)</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp1.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">reduce</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">acc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">cur</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> acc </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> cur, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">//초기값을 지정해줄 수도 있다.</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr3</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">reduce</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">acc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">current</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">index</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (acc.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">findIndex</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> type </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">===</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> current.type) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">===</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> -</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // acc안에 같은 값이 없을때만 acc에 추가</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    acc.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">push</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(current.type)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> acc </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 꼭 acc를 리턴 해줘야한다. 리턴 된 결과가 다음에 acc에 들어가서 사용됨.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}, [])</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newArr1) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 15;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newArr2) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 25;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newArr3) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// ['history', 'babyDooly', 'hemtaro', 'onepiece'];</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br></div></div><h2 id="_4-foreach" tabindex="-1">4. ForEach <a class="header-anchor" href="#_4-foreach" aria-label="Permalink to &quot;4. ForEach&quot;"></a></h2>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">arr.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">forEach</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">callback</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(currentvalue[, index[, array]])[, thisArg])</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>배열 안 만들어 주는 거 빼면 map이랑 같다.
forEach 메소드는 배열은 반복하여 현재 값, 현재 값의 인덱스, 돌고 있는 배열을 콜백으로 돌려준다.
for문 대신해서 멋있어 보이게 쓸 수 있을 거 같다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'홍길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">20</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'고길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'둘리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">4</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'햄토리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">40</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'루피'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">50</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr1</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> []</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newArr2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> []</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">for</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> i</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">; i </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">&#x3C;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">length</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">; i</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  newArr1.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">push</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(temp[i].id)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">temp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">forEach</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">item</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">index</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  newArr2.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">push</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(item.id)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newArr1) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// [1,2,3,4,5]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newArr2) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// [1,2,3,4,5]</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><h2 id="_5-find" tabindex="-1">5. find <a class="header-anchor" href="#_5-find" aria-label="Permalink to &quot;5. find&quot;"></a></h2>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">arr.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">find</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(callback[, thisArg])</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>find는 현재 값, 현재 값의 인덱스, 돌고 있는 배열을 콜백으로 돌려준다.
정말 고마운 친구다. 배열 안에서 조건에 맞는 첫 번째 요소를 리턴해준다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'홍길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">20</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'고길동'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'둘리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">4</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'햄토리'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">40</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  { id: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'루피'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, age: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">50</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> newElement</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">find</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">item</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">index</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> item.id </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(newElement) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// { id: 2, name: '고길동', age: 30 }</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div>]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[Vuejs] Component 기초 - template, render, setup, slot]]></title>
            <link>https://leteu.dev/posts/vue-component-basics</link>
            <guid>https://leteu.dev/posts/vue-component-basics</guid>
            <pubDate>Tue, 20 Jan 1970 10:05:32 GMT</pubDate>
            <description><![CDATA[<p>컴포넌트는 Vue에서 가장 기초가 되는 부분이다.
컴포넌트 하나 잘 만들어두면 비슷한 화면은 계속 가져다 쓸 수 있다.
Vue 3를 기준으로 작성하였다.</p>
<h2 id="_1-참고" tabindex="-1">1. 참고 <a class="header-anchor" href="#_1-참고" aria-label="Permalink to &quot;1. 참고&quot;">&ZeroWidthSpace;</a></h2>
<p><a href="https://v2.ko.vuejs.org/v2/guide/components.html" target="_blank" rel="noreferrer">https://v2.ko.vuejs.org/v2/guide/components.html</a></p>

      <div>
        <a
          href="https://v2.ko.vuejs.org/v2/guide/components.html"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #4fc08d"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">컴포넌트 — Vue.js</div>
            <div class="url-embed__desc">Vue.js - 프로그레시브 자바스크립트 프레임워크</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://v2.ko.vuejs.org/v2/guide/components.html</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://vuejs.org//images/logo.png" alt="" /></div>
        </a>
      </div><p>일단 공식 문서를 보자. 항상 공식 문서를 먼저 확인하자.<br>
저거 새창으로 열고 뒤로가기 눌러도 좋다.</p>
<h2 id="_2-화면" tabindex="-1">2. 화면 <a class="header-anchor" href="#_2-화면" aria-label="Permalink to &quot;2. 화면&quot;">&ZeroWidthSpace;</a></h2>
<p>일단 제일 중요한 건 화면이다.<br>
일단 뭐가 보여야 재밌으니 화면부터 들어가겠다.<br>
Template, Setup, Render 이렇게 3곳 중 한 군대를 골라서 화면을 만들어줄 수 있다.</p>
<h3 id="_2-1-template" tabindex="-1">2-1. template <a class="header-anchor" href="#_2-1-template" aria-label="Permalink to &quot;2-1. template&quot;">&ZeroWidthSpace;</a></h3>
<p>제일 익숙한 html로 짤 수 있다.<br>
pug 언어로도 가능하다. ( 이 포스트에선 다루지 않는다 )</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-d_7H-" id="tab-CmQp2ke" checked><label data-title="Composition API" for="tab-CmQp2ke">Composition API</label><input type="radio" name="group-d_7H-" id="tab-4h5nxJV" ><label data-title="Optional API" for="tab-4h5nxJV">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  &#x3C;!-- 여기에 html 짜면 화면에 나온다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  &#x3C;!-- 여기에 html 짜면 화면에 나온다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {},</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div></div></div>
<p>딱 봐도 Optional API는 옛날 Vue2 시절을 못잊은 사람들을 위해 남겨둔거처럼 보인다.<br>
옛날에 data, create, method 넣던곳에 setup 하나만 넣고 끝낼 수 있다.<br>
어짜피 <code>composition api</code>랑 별반 차이 없으니 <code>render</code> 빼고는 <code>composition api</code> 기준으로만 작성하려고 한다.<br>
typescript, javascript 파일에서 컴포넌트 만들 사람들은 <code>optional api</code> 말고는 선택지가 없다.</p>
<h3 id="_2-2-render" tabindex="-1">2-2. render <a class="header-anchor" href="#_2-2-render" aria-label="Permalink to &quot;2-2. render&quot;">&ZeroWidthSpace;</a></h3>
<p>vue3에서 vue2와 문법이 바뀐 녀석이다.<br>
바뀌어 봐야 <code>createElement</code>를 param으로 넘겨주던걸 h 함수를 import 해오는 식으로 밖에 변경된건 없다.<br>
<a href="https://v2.vuejs.org/v2/guide/render-function" target="_blank" rel="noreferrer">vue 2 render function</a></p>

      <div>
        <a
          href="https://v2.vuejs.org/v2/guide/render-function"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #4fc08d"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Render Functions & JSX — Vue.js</div>
            <div class="url-embed__desc">Vue.js - The Progressive JavaScript Framework</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://v2.vuejs.org/v2/guide/render-function</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://vuejs.org/images/logo.png" alt="" /></div>
        </a>
      </div><p>h 함수를 vue에서 임포트 해와서 코드를 짤 수 있다.<br>
쓸 때 template은 지우고 써야 한다. 걔가 우선순위가 더 높다.</p>
<p>h 함수는 React의 <code>createElement</code>와 매우 유사하다.
<s>라고 해봐야 react에서 <code>createElement</code> 써본 사람 몇 없다는건 말 안해줘도 알거 같다.</s></p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, h } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {},</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  render</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">      'div'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 어트리뷰트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 하위 컴포넌트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      ],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    )</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>근데 우리는 vue3니까</p>
<h3 id="_2-3-setup" tabindex="-1">2-3. setup <a class="header-anchor" href="#_2-3-setup" aria-label="Permalink to &quot;2-3. setup&quot;">&ZeroWidthSpace;</a></h3>
<p>여기서도 할 수는 있다. 근데 보통 여기서는 사용할 데이터를 선언해야 해서 잘 안 쓴다. 알아만 두자<br>
진짜로 쓰고 싶으면 template과 render는 지우고 사용해야한다.<br>
근데 웬만해선 여기선 render 하지 말고 template에서 하자<br>
문법은 render와 같이 h 함수를 임포트 해와서 쓴다.</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, h } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">      'div'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 어트리뷰트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 하위 컴포넌트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      ],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    )</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>setup에서는 기존 vue2에서 하던 <code>data</code>, <code>create</code>, <code>method</code>, ... 등의 라이프사이클과 state, method 등을 js, ts 파일에서 작성하듯이 작성할 수 있게 해준다.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-mND9l" id="tab-OkSyxE7" checked><label data-title="Composition API" for="tab-OkSyxE7">Composition API</label><input type="radio" name="group-mND9l" id="tab--moWl_N" ><label data-title="Optional API" for="tab--moWl_N">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { ref, onBeforeMount } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// data에서 변수 선언 하던거 이런 느낌으로 바뀜</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ref</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">onBeforeMount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // create랑 똑같이 마운트 되기 전에 호출함.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, ref, onBeforeMount } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // data에서 변수 선언 하던거 이런 느낌으로 바뀜</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ref</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    onBeforeMount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      // create랑 똑같이 마운트 되기 전에 호출함.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    })</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      temp,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div></div></div>
<p><code>Optional</code>과 <code>Composition</code> 둘다 setup이 있지만 <code>Composition</code>은 return 안해주고 선언만 해도 template에서 쓸 수 있다.</p>
<p>더 뭐 보고 싶은게 있다면 공식 문서를 보거나 댓글로 질문 남겨주시면 답변 달아드립니다.</p>
<h2 id="_3-컴포넌트-사용" tabindex="-1">3. 컴포넌트 사용 <a class="header-anchor" href="#_3-컴포넌트-사용" aria-label="Permalink to &quot;3. 컴포넌트 사용&quot;">&ZeroWidthSpace;</a></h2>
<p>컴포넌트를 만들어 놔도 불러오지 않으면 화면에 뿌릴 수 없다.<br>
전체적으로 사용하는 컴포넌트는 전역으로 처리하고 아닐 경우에 아래 코드처럼 하나하나 import 해와서 사용해주면 된다.</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ChildComponenet</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-MaYmG" id="tab-MnPEwAD" checked><label data-title="Composition API" for="tab-MnPEwAD">Composition API</label><input type="radio" name="group-MaYmG" id="tab-6oKumEF" ><label data-title="Optional API" for="tab-6oKumEF">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ChildrenComponent </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> './ChildrenComponent.vue'</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ChildrenComponent </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> './ChildrenComponent.vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  component: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ComponenetVue,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {},</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div></div></div>
<h2 id="_4-slot" tabindex="-1">4. Slot <a class="header-anchor" href="#_4-slot" aria-label="Permalink to &quot;4. Slot&quot;">&ZeroWidthSpace;</a></h2>
<p><a href="https://vuejs.org/guide/components/slots.html" target="_blank" rel="noreferrer">https://vuejs.org/guide/components/slots.html</a></p>

      <div>
        <a
          href="https://vuejs.org/guide/components/slots.html"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #3c8772"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Vue.js</div>
            <div class="url-embed__desc">Vue.js - The Progressive JavaScript Framework</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://vuejs.org/guide/components/slots.html</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://vuejs.org/images/logo.png" alt="" /></div>
        </a>
      </div><p>prop으로 냅다 모든걸 보내버릴 생각 말고 <code>slot</code>도 활용을 해주자.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-dZmGU" id="tab-SQLurIj" checked><label data-title="Component.vue" for="tab-SQLurIj">Component.vue</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- default --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"content"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- custom name --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div></div></div>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-WGKcV" id="tab-g4fh090" checked><label data-title="shorthand" for="tab-g4fh090">shorthand</label><input type="radio" name="group-WGKcV" id="tab-GsNfwD9" ><label data-title="full" for="tab-GsNfwD9">full</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    &#x3C;!-- 여기에 적으면 컴포넌트 안에 default slot에 적힌다 --></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> #</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- 여기에 적으면 컴포넌트 안에 content slot에 적힌다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    &#x3C;!-- 여기에 적으면 컴포넌트 안에 default slot에 적힌다 --></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> v-slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- 여기에 적으면 컴포넌트 안에 content slot에 적힌다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></div></div>
<p>이렇게 컴포넌트 안에 원하는 위치에 따로 커스텀이 가능하다.<br>
컴포넌트의 재사용을 늘릴 수 있다.</p>
<p><code>h 함수</code> 쓸 때도 slot 사용이 가능하다.</p>
<p>children을 쓰는 곳에 그냥 h 함수나 h 함수의 배열을 쓰면 기본적으로 default 슬롯에 들어가게 된다.<br>
따로 슬롯을 명시하여 사용하면 RawChildren 인터페이스가 아닌 RawSlots 인터페이스로 잡히게 된다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  ComponentVue,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 어트리뷰트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">( </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ],</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">( </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ),</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">( </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>슬롯명: () =&gt; h( ... ) 형태로 사용하면 vue JSX에서도 슬롯이 사용 가능하다.</p>
]]></description>
            <content:encoded><![CDATA[<p>컴포넌트는 Vue에서 가장 기초가 되는 부분이다.
컴포넌트 하나 잘 만들어두면 비슷한 화면은 계속 가져다 쓸 수 있다.
Vue 3를 기준으로 작성하였다.</p>
<h2 id="_1-참고" tabindex="-1">1. 참고 <a class="header-anchor" href="#_1-참고" aria-label="Permalink to &quot;1. 참고&quot;"></a></h2>
<p><a href="https://v2.ko.vuejs.org/v2/guide/components" target="_blank" rel="noreferrer">https://v2.ko.vuejs.org/v2/guide/components</a></p>

      <div>
        <a
          href="https://v2.ko.vuejs.org/v2/guide/components"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #4fc08d"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">컴포넌트 — Vue.js</div>
            <div class="url-embed__desc">Vue.js - 프로그레시브 자바스크립트 프레임워크</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://v2.ko.vuejs.org/v2/guide/components</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://vuejs.org//images/logo.png" alt="" /></div>
        </a>
      </div><p>일단 공식 문서를 보자. 항상 공식 문서를 먼저 확인하자.<br>
저거 새창으로 열고 뒤로가기 눌러도 좋다.</p>
<h2 id="_2-화면" tabindex="-1">2. 화면 <a class="header-anchor" href="#_2-화면" aria-label="Permalink to &quot;2. 화면&quot;"></a></h2>
<p>일단 제일 중요한 건 화면이다.<br>
일단 뭐가 보여야 재밌으니 화면부터 들어가겠다.<br>
Template, Setup, Render 이렇게 3곳 중 한 군대를 골라서 화면을 만들어줄 수 있다.</p>
<h3 id="_2-1-template" tabindex="-1">2-1. template <a class="header-anchor" href="#_2-1-template" aria-label="Permalink to &quot;2-1. template&quot;"></a></h3>
<p>제일 익숙한 html로 짤 수 있다.<br>
pug 언어로도 가능하다. ( 이 포스트에선 다루지 않는다 )</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-GEX35" id="tab-XBkRHiL" checked><label data-title="Composition API" for="tab-XBkRHiL">Composition API</label><input type="radio" name="group-GEX35" id="tab-TmJdY_N" ><label data-title="Optional API" for="tab-TmJdY_N">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  &#x3C;!-- 여기에 html 짜면 화면에 나온다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  &#x3C;!-- 여기에 html 짜면 화면에 나온다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {},</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div></div></div>
<p>딱 봐도 Optional API는 옛날 Vue2 시절을 못잊은 사람들을 위해 남겨둔거처럼 보인다.<br>
옛날에 data, create, method 넣던곳에 setup 하나만 넣고 끝낼 수 있다.<br>
어짜피 <code>composition api</code>랑 별반 차이 없으니 <code>render</code> 빼고는 <code>composition api</code> 기준으로만 작성하려고 한다.<br>
typescript, javascript 파일에서 컴포넌트 만들 사람들은 <code>optional api</code> 말고는 선택지가 없다.</p>
<h3 id="_2-2-render" tabindex="-1">2-2. render <a class="header-anchor" href="#_2-2-render" aria-label="Permalink to &quot;2-2. render&quot;"></a></h3>
<p>vue3에서 vue2와 문법이 바뀐 녀석이다.<br>
바뀌어 봐야 <code>createElement</code>를 param으로 넘겨주던걸 h 함수를 import 해오는 식으로 밖에 변경된건 없다.<br>
<a href="https://v2.vuejs.org/v2/guide/render-function" target="_blank" rel="noreferrer">vue 2 render function</a></p>

      <div>
        <a
          href="https://v2.vuejs.org/v2/guide/render-function"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #4fc08d"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Render Functions & JSX — Vue.js</div>
            <div class="url-embed__desc">Vue.js - The Progressive JavaScript Framework</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://v2.vuejs.org/v2/guide/render-function</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://vuejs.org/images/logo.png" alt="" /></div>
        </a>
      </div><p>h 함수를 vue에서 임포트 해와서 코드를 짤 수 있다.<br>
쓸 때 template은 지우고 써야 한다. 걔가 우선순위가 더 높다.</p>
<p>h 함수는 React의 <code>createElement</code>와 매우 유사하다.
<s>라고 해봐야 react에서 <code>createElement</code> 써본 사람 몇 없다는건 말 안해줘도 알거 같다.</s></p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, h } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {},</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  render</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">      'div'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 어트리뷰트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 하위 컴포넌트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      ],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    )</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>근데 우리는 vue3니까</p>
<h3 id="_2-3-setup" tabindex="-1">2-3. setup <a class="header-anchor" href="#_2-3-setup" aria-label="Permalink to &quot;2-3. setup&quot;"></a></h3>
<p>여기서도 할 수는 있다. 근데 보통 여기서는 사용할 데이터를 선언해야 해서 잘 안 쓴다. 알아만 두자<br>
진짜로 쓰고 싶으면 template과 render는 지우고 사용해야한다.<br>
근데 웬만해선 여기선 render 하지 말고 template에서 하자<br>
문법은 render와 같이 h 함수를 임포트 해와서 쓴다.</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, h } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">      'div'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 어트리뷰트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">        // 하위 컴포넌트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      ],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    )</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>setup에서는 기존 vue2에서 하던 <code>data</code>, <code>create</code>, <code>method</code>, ... 등의 라이프사이클과 state, method 등을 js, ts 파일에서 작성하듯이 작성할 수 있게 해준다.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-TqRGz" id="tab-0gLuupJ" checked><label data-title="Composition API" for="tab-0gLuupJ">Composition API</label><input type="radio" name="group-TqRGz" id="tab-PIN26Dn" ><label data-title="Optional API" for="tab-PIN26Dn">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { ref, onBeforeMount } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// data에서 변수 선언 하던거 이런 느낌으로 바뀜</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ref</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">onBeforeMount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // create랑 똑같이 마운트 되기 전에 호출함.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, ref, onBeforeMount } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // data에서 변수 선언 하던거 이런 느낌으로 바뀜</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> ref</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    onBeforeMount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      // create랑 똑같이 마운트 되기 전에 호출함.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    })</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      temp,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div></div></div>
<p><code>Optional</code>과 <code>Composition</code> 둘다 setup이 있지만 <code>Composition</code>은 return 안해주고 선언만 해도 template에서 쓸 수 있다.</p>
<p>더 뭐 보고 싶은게 있다면 공식 문서를 보거나 댓글로 질문 남겨주시면 답변 달아드립니다.</p>
<h2 id="_3-컴포넌트-사용" tabindex="-1">3. 컴포넌트 사용 <a class="header-anchor" href="#_3-컴포넌트-사용" aria-label="Permalink to &quot;3. 컴포넌트 사용&quot;"></a></h2>
<p>컴포넌트를 만들어 놔도 불러오지 않으면 화면에 뿌릴 수 없다.<br>
전체적으로 사용하는 컴포넌트는 전역으로 처리하고 아닐 경우에 아래 코드처럼 하나하나 import 해와서 사용해주면 된다.</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ChildComponenet</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-mgkWu" id="tab-UMiLlfM" checked><label data-title="Composition API" for="tab-UMiLlfM">Composition API</label><input type="radio" name="group-mgkWu" id="tab-y75jnhO" ><label data-title="Optional API" for="tab-y75jnhO">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ChildrenComponent </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> './ChildrenComponent.vue'</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ChildrenComponent </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> './ChildrenComponent.vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  component: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ComponenetVue,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">() {},</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div></div></div>
<h2 id="_4-slot" tabindex="-1">4. Slot <a class="header-anchor" href="#_4-slot" aria-label="Permalink to &quot;4. Slot&quot;"></a></h2>
<p><a href="https://vuejs.org/guide/components/slots" target="_blank" rel="noreferrer">https://vuejs.org/guide/components/slots</a></p>

      <div>
        <a
          href="https://vuejs.org/guide/components/slots"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #3c8772"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Vue.js</div>
            <div class="url-embed__desc">Vue.js - The Progressive JavaScript Framework</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://vuejs.org/guide/components/slots</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://vuejs.org/images/logo.png" alt="" /></div>
        </a>
      </div><p>prop으로 냅다 모든걸 보내버릴 생각 말고 <code>slot</code>도 활용을 해주자.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-VKUGV" id="tab-dlH4nJe" checked><label data-title="Component.vue" for="tab-dlH4nJe">Component.vue</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- default --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"content"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- custom name --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div></div></div>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-zldmn" id="tab-_eH2DL-" checked><label data-title="shorthand" for="tab-_eH2DL-">shorthand</label><input type="radio" name="group-zldmn" id="tab-r64Nf6S" ><label data-title="full" for="tab-r64Nf6S">full</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    &#x3C;!-- 여기에 적으면 컴포넌트 안에 default slot에 적힌다 --></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> #</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- 여기에 적으면 컴포넌트 안에 content slot에 적힌다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    &#x3C;!-- 여기에 적으면 컴포넌트 안에 default slot에 적힌다 --></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> v-slot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      &#x3C;!-- 여기에 적으면 컴포넌트 안에 content slot에 적힌다 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ComponentVue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></div></div>
<p>이렇게 컴포넌트 안에 원하는 위치에 따로 커스텀이 가능하다.<br>
컴포넌트의 재사용을 늘릴 수 있다.</p>
<p><code>h 함수</code> 쓸 때도 slot 사용이 가능하다.</p>
<p>children을 쓰는 곳에 그냥 h 함수나 h 함수의 배열을 쓰면 기본적으로 default 슬롯에 들어가게 된다.<br>
따로 슬롯을 명시하여 사용하면 RawChildren 인터페이스가 아닌 RawSlots 인터페이스로 잡히게 된다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  ComponentVue,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    // 어트리뷰트</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">( </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ],</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">( </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ),</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      h</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">( </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>슬롯명: () =&gt; h( ... ) 형태로 사용하면 vue JSX에서도 슬롯이 사용 가능하다.</p>
<hr>
<div class="tip custom-block"><p class="custom-block-title">TIP</p>
<p><strong>Prop</strong>, <strong>Emit</strong> 사용법은 여기로</p>
<blockquote>
<p><a href="/posts/vue-prop-emit">[Vue 3] Props, Emit</a></p>
</blockquote>
</div>
<div class="tip custom-block"><p class="custom-block-title">TIP</p>
<p><strong>Expose</strong> 사용법은 여기로</p>
<blockquote>
<p><a href="/posts/vue-expose">[Vuejs] Expose로 ref에서 함수 꺼내 쓰기</a></p>
</blockquote>
</div>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[Git] Git Remote repository 변경]]></title>
            <link>https://leteu.dev/posts/git-remote-change</link>
            <guid>https://leteu.dev/posts/git-remote-change</guid>
            <pubDate>Tue, 20 Jan 1970 10:05:32 GMT</pubDate>
            <content:encoded><![CDATA[<p>사내에서 깃랩 주소가 바뀌거나 프로젝트 이름이나 주소를 바꾸는 경우가 종종 있었다.<br>
검색해서 보면 되기에 굳이 외워두지는 않았는데 계속 검색하기도 귀찮아서 외워둘겸 메모해두려고 한다.</p>
<h2 id="_1-자주-발생하는-오류" tabindex="-1">1. 자주 발생하는 오류 <a class="header-anchor" href="#_1-자주-발생하는-오류" aria-label="Permalink to &quot;1. 자주 발생하는 오류&quot;"></a></h2>
<div class="language-log vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">log</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">fatal: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'origin'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> does not appear to be a git repository</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">fatal: Could not read from remote repository.</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">Please make sure you have the correct access rights and the repository exists.</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>이거 때문에 고생해서 오는 사람 많을 거 같다.<br>
얘도 똑같이 따라 해 주면 고쳐질 수도 있다. ( 아닐 수도 있다 )</p>
<h2 id="_2-remote-확인" tabindex="-1">2. Remote 확인 <a class="header-anchor" href="#_2-remote-확인" aria-label="Permalink to &quot;2. Remote 확인&quot;"></a></h2>
<p>일단 확인부터 하자</p>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> remote</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -v</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>실행하고 나면 보통 아래처럼 2줄 정도 뜬다.</p>
<div class="language-log vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">log</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">origin	</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">https://github.com/leteu/leteu.git</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (fetch)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">origin	</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">https://github.com/leteu/leteu.git</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (push)</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>여기서  <a href="#1-자주-발생하는-오류">1번</a>처럼 오류가 난다면 https 가 아니라 http 라고 적혀 있어서 그런 게 대부분일 거라 생각한다.<br>
아니라면 url이 변경되었거나 뭐 그런 거다</p>
<h2 id="_2-remote-url-변경" tabindex="-1">2. Remote URL 변경 <a class="header-anchor" href="#_2-remote-url-변경" aria-label="Permalink to &quot;2. Remote URL 변경&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> remote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ser-url</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">remote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 이름</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (ex. </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">origin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">git 주소</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>이거면 웬만해선 다 될 거다.<br>
<code>&lt;remote 이름&gt;</code>에 url을 명령어 마지막에 작성하는 <code>&lt;git 주소&gt;</code>로 바꿔준다.</p>
<h2 id="_3-remote-name-변경" tabindex="-1">3. Remote name 변경 <a class="header-anchor" href="#_3-remote-name-변경" aria-label="Permalink to &quot;3. Remote name 변경&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> remote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> rename</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">원래</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 이</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">름</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">바꿀</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 이</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">름</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p><code>&lt;원래 이름&gt;</code>을 <code>&lt;바꿀 이름&gt;</code>으로 바꿔준다.
기존 저장소 이름 바꾸고 새 저장소를 origin으로 바꾸고 싶을 때 쓸 수 있다.</p>
<h2 id="_4-remote-추가" tabindex="-1">4. Remote 추가 <a class="header-anchor" href="#_4-remote-추가" aria-label="Permalink to &quot;4. Remote 추가&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> remote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">remote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 이</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">름</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 주</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">소</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p><code>&lt;remote 이름&gt;</code>으로 remote를 하나 더 만들어 준다.</p>
<h2 id="_5-remote-삭제" tabindex="-1">5. Remote 삭제 <a class="header-anchor" href="#_5-remote-삭제" aria-label="Permalink to &quot;5. Remote 삭제&quot;"></a></h2>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> remote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> remove</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">remote</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 이</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">름</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>위 명령어를 실행하면 로컬에서 <code>&lt;remote 이름&gt;</code> 리모트를 삭제한다.<br>
원격 저장소 지워지는 거 아니니까 걱정 말자.</p>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[Vue 3] Props, Emit]]></title>
            <link>https://leteu.dev/posts/vue-prop-emit</link>
            <guid>https://leteu.dev/posts/vue-prop-emit</guid>
            <pubDate>Tue, 20 Jan 1970 01:38:24 GMT</pubDate>
            <content:encoded><![CDATA[<h2 id="_1-왜-쓰나" tabindex="-1">1. 왜 쓰나 <a class="header-anchor" href="#_1-왜-쓰나" aria-label="Permalink to &quot;1. 왜 쓰나&quot;"></a></h2>
<p>Vue를 사용하다 보면 상위 컴포넌트에서 하위 컴포넌트로 데이터를 넘겨주거나 반대로 하위에서 상위로 올려 받아야 하는 경우가 있을 수 있습니다.</p>
<h2 id="_2-간단-요약" tabindex="-1">2. 간단 요약 <a class="header-anchor" href="#_2-간단-요약" aria-label="Permalink to &quot;2. 간단 요약&quot;"></a></h2>
<div class="info custom-block"><p class="custom-block-title">Props</p>
<ul>
<li>상위 컴포넌트에서 하위 컴포넌트로 뿌려주는 것</li>
<li>하위 컴포넌트에서 선언하고 상위에서 선언해둔 이름으로 보낼 수 있음.</li>
</ul>
</div>
<div class="info custom-block"><p class="custom-block-title">Emit</p>
<ul>
<li>하위 컴포넌트에서 상위 컴포넌트로 올려주는 것</li>
<li>하위 컴포넌트에서 선언하고 상위에서 선언해둔 이름으로 받을 수 있음.</li>
</ul>
</div>
<h2 id="_3-props" tabindex="-1">3. Props <a class="header-anchor" href="#_3-props" aria-label="Permalink to &quot;3. Props&quot;"></a></h2>
<p>예시)</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ChildComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> :</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">custom-prop</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">value</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  {{ customProp }}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">props</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">	customProp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: String,</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">		default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    required</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    validator</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">val</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><p>컴포넌트의 props에서 키을 지정한 뒤 부모 컴포넌트에서 키에 맞는 값을 보내주는 식으로 사용한다.<br>
props는 배열로 작성하여 키값을 텍스트만으로도 지정할 수 있다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">props</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'key1'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'key2'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>하지만 이렇게 작성할 경우 키에 대한 타입이 명확하지 않아 협업시 문제가 생길 수 있다.</p>
<p>typescript를 사용할 경우에는 Vue3 기준으로</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, PropType } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  props: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    key1: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      type: Array </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> PropType</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">타입</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>이런 식으로 PropType을 불러와 사용해주면 된다.</p>
<p>2023.02.24 추가) Composition API setup에서의 활용을 안적고 올렸길래 추가</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>...&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { PropType } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">defineProps</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  customProp: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    type: String </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> PropType</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'hihi'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'hihi'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    required: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    validator</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">val</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> val </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">===</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'hihi'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h2 id="_4-emit" tabindex="-1">4. Emit <a class="header-anchor" href="#_4-emit" aria-label="Permalink to &quot;4. Emit&quot;"></a></h2>
<p>Emit은 하위의 자식 컴포넌트에서 다시 상위인 부모 컴포넌트로 값을 보내줄 때 사용한다.</p>
<p>예시)</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">&#x3C;!-- 부모 컴포넌트 --></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">ChildComponent</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> @update:text</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"(val) => (text = val)"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">data</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(){</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">	return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    	text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">&#x3C;!-- 자식 컴포넌트--></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, PropType } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  emit: [ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ],</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">	created</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(){</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">    	this</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">$emit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'테스트 텍스트'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	},</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">&#x3C;!-- 자식 컴포넌트--></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent, PropType } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  emit: [ </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> ],</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">	setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">props</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">emit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }) {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    emit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'테스트 메시지'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p>2023.02.24 추가) setup에서의 활용을 안적고 올렸길래 추가</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>...&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"ts"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { PropType } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 이렇게 하나</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> emit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineEmits</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">([</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:src'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">])</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 이렇게 하나</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> emit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineEmits</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">txt</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> txt,</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  'update:src'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">src</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> src,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 이렇게 하나 같음</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> emit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineEmits</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;{</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">e</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">txt</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> void</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">e</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'update:src'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">src</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> void</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}>()</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> emitText</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  emit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'text'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> emitSrc</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  emit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'update:src'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'src'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><h2 id="_5-번외-vuex-pinia" tabindex="-1">5. 번외 ( Vuex, Pinia ) <a class="header-anchor" href="#_5-번외-vuex-pinia" aria-label="Permalink to &quot;5. 번외 ( Vuex, Pinia )&quot;"></a></h2>
<p>만약 동일 선상에 컴포넌트끼리 data를 주고 받으려면 A 컴포넌트에서 상위 컴포넌트로 Emit 하고 상위 컴포넌트에서 B 컴포넌트로 prop으로 넘겨주고 이러한 번거로운 작업이 생겨 버립니다.</p>
<p>이를 해결해주는것이 Store이고 좀 더 편하게 사용할 수 있도록 만들어진 라이브러리가 Vuex, Pinia 등이 있습니다.</p>
<p>Vuex와 Pinia는 이번 포스팅에선 언급만 하고 넘어가고 후에 자세하게 풀어보도록 하겠습니다.</p>
<p><a href="https://v2.ko.vuejs.org/v2/guide/state-management" target="_blank" rel="noreferrer">https://v2.ko.vuejs.org/v2/guide/state-management</a></p>

      <div>
        <a
          href="https://v2.ko.vuejs.org/v2/guide/state-management"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #4fc08d"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">상태 관리 — Vue.js</div>
            <div class="url-embed__desc">Vue.js - 프로그레시브 자바스크립트 프레임워크</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://v2.ko.vuejs.org/v2/guide/state-management</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://vuejs.org//images/logo.png" alt="" /></div>
        </a>
      </div>]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[Vue]  Quasar Vue UI framwork 소개]]></title>
            <link>https://leteu.dev/posts/review-quasar-framework</link>
            <guid>https://leteu.dev/posts/review-quasar-framework</guid>
            <pubDate>Tue, 20 Jan 1970 01:16:49 GMT</pubDate>
            <content:encoded><![CDATA[<p>회사에서 사용 중인 Vue UI 프레임워크를 소개해보려고 한다.
Vue 사용자도 React에 비해 많이 적은 와중에 UI 프레임워크는 보통 Vuetify를 많이 사용한다.
Quasar를 처음 접했을 때 검색하기 참 힘들었던 거 같다.</p>
<h2 id="_1-공식-사이트" tabindex="-1">1. 공식 사이트 <a class="header-anchor" href="#_1-공식-사이트" aria-label="Permalink to &quot;1. 공식 사이트&quot;"></a></h2>
<p><a href="https://quasar.dev/" target="_blank" rel="noreferrer">https://quasar.dev/</a></p>

      <div>
        <a
          href="https://quasar.dev/"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #00B4FF"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Quasar Framework - Build high-performance VueJS user interfaces in record time</div>
            <div class="url-embed__desc">Developer-oriented, front-end framework with VueJS components for best-in-class high-performance, responsive websites, PWA, SSR, Mobile and Desktop apps, all from the same codebase. Sensible people choose Vue. Productive people choose Quasar. Be both.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://quasar.dev/</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://cdn.quasar.dev/logo-v2/social-cover.jpg" alt="" /></div>
        </a>
      </div><p>Vuetify 와는 다르게 문서가 좀 더 깔끔하고 상냥한 거 같다.
상단에 컴포넌트의 설명을 검색도 가능하게 해 준 뒤 예제들을 종류별로 다 뿌려두었다.
Vuetify는 직접 태그를 추가하며 확인해보는 것에 비해 Quasar는 필요한 걸 바로 확인하고 소스를 긁어 갈 수 있어서 좋았다.</p>
<h2 id="_2-quasar-cli" tabindex="-1">2. Quasar Cli <a class="header-anchor" href="#_2-quasar-cli" aria-label="Permalink to &quot;2. Quasar Cli&quot;"></a></h2>
<p>Quasar는 전용 cli를 지원한다.<br>
Vue 초기 세팅을 못하는 사람이라도 cli를 쓰면 빠르게 세팅이 가능하다.<br>
기본적으로 Typescript와 Vuex, vue-router 등을 지원하고 전역 함수와 전역 스타일을 정리할 수 있게 따로 정리를 해두었다.</p>
<p>기본적으로 SPA(싱글 페이지 애플리케이션)으로 동작하지만 Electron을 사용하여 프로그램으로 빌드하거나 Cordova나 Capacitor를 통해 앱으로 빌드할 수 있다.<br>
PWA도 지원하여 웹을 간단하게 앱으로 만들어버릴 수도 있다.<br>
서버사이드 랜더링 역시 지원하고 있다.</p>
<p>우선 npm 명령어를 통해 전역으로 Quasar를 설치해준다.<br>
( Quasar는 yarn으로 하길 원하지만 나는 npm이 편하다. )</p>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">$</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> global</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> add</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> @quasar/cli</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D"># or</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">$</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> install</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -g</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> @quasar/cli</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>cli를 설치한 뒤 프로젝트를 세팅할 폴더에 가서 quasar create &lt;폴더명&gt;을 해준다.</p>
<div class="language-bash vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">quasar</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> create</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> &#x3C;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">폴더</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">명</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>eslint나 typescript 등을 선택해주고 css의 전처리기 등등을 선택해주고 나면 기초적인 세팅이 끝난 Vue 프로젝트가 생성된다.</p>
<p>vue.conf.js 대신 quasar.conf.js가 있다. 여기서 퀘이사 cli를 사용하며 필요한 설정, 빌드 타입 등을 설정해줄 수 있다.</p>
<p>quasar.conf.js에 framwork에 lang을 ko-kr로 설정해야 언어가 한국어로 나온다.
달력이 영어로 나오길래 한번 찾아봤었다.</p>
<h2 id="_3-전용-directive" tabindex="-1">3. 전용 Directive <a class="header-anchor" href="#_3-전용-directive" aria-label="Permalink to &quot;3. 전용 Directive&quot;"></a></h2>
<p><img src="/images/quasar-directive.png" alt="quasar directive">
유용한 Directive도 지원한다.</p>
<p>다 살펴 보진 않았지만 Close Popup은 조건에 따라 QMenu나 QDialog 등의 Quasar가 지원하는 팝업 컴포넌트를 Close (hide) 처리 할 수 있다.</p>
<p>Scroll도 스크롤이 가능한 엘리먼트에 사용하면 스크롤 했을때 Event를 바로바로 받아 볼 수 있다.</p>
<p>Thouch 들은 마우스 뿐만 아니라 모바일에서도 옆으로 넘기거나 꾹 누르는 효과등을 처리해 줄 수 있다.</p>
<h2 id="_4-레이아웃-빌더" tabindex="-1">4. 레이아웃 빌더 <a class="header-anchor" href="#_4-레이아웃-빌더" aria-label="Permalink to &quot;4. 레이아웃 빌더&quot;"></a></h2>
<p><a href="https://quasar.dev/layout-builder" target="_blank" rel="noreferrer">https://quasar.dev/layout-builder</a></p>
<p>Layout Builder | Quasar Framework
Tool to build Quasar layouts. Configure the layout parts then export the code.
quasar.dev</p>
<p>따로 레이아웃 빌더도 지원하고 있다.
입맛에 맞춰서 메인 레이아웃을 만들어 사용할 수 있다.
Export Layout을 누르면 template 코드를 복사할 수 있는 화면이 나온다.</p>
<h2 id="_5-커뮤니티" tabindex="-1">5. 커뮤니티 <a class="header-anchor" href="#_5-커뮤니티" aria-label="Permalink to &quot;5. 커뮤니티&quot;"></a></h2>
<p>Vue를 하다보면 질문 사항이 생겨도 검색해 봤을 때 잘 안 나오거나 어떻게 검색해야 할지 모를 때가 있을 수 있다.
Quasar는 디스코드 커뮤니티를 운영하고 있는데 한국어 채널이 있긴 하지만 한국어 채널에서 활동하는 사람은 잘 없다.
영어로 질문글 올리면 Quasar 개발자들이나 유저들이 반나절 내외로 답변해준다.
뭐 안되는거 있다고 올리면 codeSandBox 링크 주면서 이런 식으로 수정해라 하고 답변해줄 때도 있다.</p>
<p><a href="https://discord.com/invite/5TDhbDg" target="_blank" rel="noreferrer">https://discord.com/invite/5TDhbDg</a></p>
<h2 id="_6-quasar-1년-써본-후기" tabindex="-1">6. Quasar 1년 써본 후기 <a class="header-anchor" href="#_6-quasar-1년-써본-후기" aria-label="Permalink to &quot;6. Quasar 1년 써본 후기&quot;"></a></h2>
<p>cli 지원 해주는게 엄청 편했다. Vue 깡통 프로젝트 생성해서 모듈을 하나하나 직접 집어넣는 거도 한 번쯤은 해보는 게 좋겠지만 귀찮으니 다 해주는 게 편하다.
Vite 유행하니 babel 대신에 Vite로 빌드할 수 있게 해주기도 하고 초기 세팅을 대신 해주는게 가장 큰 장점인 거 같다.
디자인도 Material Design을 따라가기 때문에 호불호도 적다.</p>
<p>Vue를 아예 처음하는 사람이라면 추천한다.
물론 처음부터 한번 싹 세팅해보는 게 좋지만 그럴 시간이 없을 때 쓰기 좋은 거 같다.
다른 프래임워크는 컴포넌트 하나하나에 중심을 줬다면 Quasar는 전체적인 소스를 줘버리기 때문에 그대로 복사해서 붙여 넣으면 크게 어려운 게 없는 거 같다.</p>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[Vue 3] 라우트 변경, 새로고침, 창 닫기 감지]]></title>
            <link>https://leteu.dev/posts/vue-route-observe</link>
            <guid>https://leteu.dev/posts/vue-route-observe</guid>
            <pubDate>Tue, 20 Jan 1970 00:58:04 GMT</pubDate>
            <content:encoded><![CDATA[<p>웹 소캣 이용해서 채팅 서비스 만들다가 새로고침으로 방 나가는 방법 예외 추가하려고 했다.<br>
당최 깔끔하게 해결법이 안나오다가 해결해서 글 적어본다.</p>
<div class="tip custom-block"><p class="custom-block-title">TIP</p>
<p>이 페이지에 도달한게 <strong>새로고침</strong>인지 <strong>뒤로가기</strong>인지 <strong>링크 클릭</strong>해서 왔는지 궁금할땐</p>
<blockquote>
<p><a href="/posts/js-navigation-timing">[JS] 네비게이션 타이밍 가져오기 (새로고침, 뒤로가기, 네비게이트)</a></p>
</blockquote>
</div>
<h2 id="_1-watch" tabindex="-1">1. Watch <a class="header-anchor" href="#_1-watch" aria-label="Permalink to &quot;1. Watch&quot;"></a></h2>
<p>그냥 주소만 바꿔서 나가는 경우일 때 사용할 수 있다.<br>
사용하긴 제일 쉽지만 별로 맘에 드는 방법은 아니다.<br>
새로고침 시엔 라우터가 변경되는 게 아니라 확인이 불가해서 동작하지 않는다.</p>
<div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-rqDdm" id="tab-Xub2953" checked><label data-title="Composition API" for="tab-Xub2953">Composition API</label><input type="radio" name="group-rqDdm" id="tab-9AL0Vuo" ><label data-title="Optional API" for="tab-9AL0Vuo">Optional API</label></div><div class="blocks">
<div class="language-vue vp-adaptive-theme active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> setup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { watch } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { useRoute } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue-router'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> route</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> useRoute</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">()</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">watch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> route,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">to</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">from</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">    /* 라우트 변경 감지시 여기가 실행됨 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    deep: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { defineComponent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'vue'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> defineComponent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">  data</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(){</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">    return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  watch: {</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">    '$route'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">to</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">from</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">      // 라우트 변경이 감지되면 여기 실행됨</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">  ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div></div></div>
<ul>
<li>setup에서 route 쓰려면 위 코드처럼 useRoute 불러와서 써주면 된다. ( router는 useRouter )</li>
</ul>
<h2 id="_2-beforerouteleave" tabindex="-1">2. BeforeRouteLeave <a class="header-anchor" href="#_2-beforerouteleave" aria-label="Permalink to &quot;2. BeforeRouteLeave&quot;"></a></h2>
<p>라우트 컴포넌트의 내부 가드이다. ( 어려운 말로 썼지만 그냥 vue-router 쓴 컴포넌트이다 )</p>
<p>BeforeRouteLeave 가드를 사용하면 장점이 어떠한 처리를 한 후에 next함수를 통해 라우트를 이동시켜 버릴 수 있다.<br>
사용자가 가려고 하는 라우트에 권한을 체크해서 <code>next()</code>를 하는 식으로 사용하면 좋다.<br>
단점으론 새로고침을 할 경우엔 라우터가 변경되지 않기 때문에 체크하지 못하고 창을 닫는 경우에도 마찬가지이다.</p>
<div class="language-vue vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">beforeRouteLeave</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(to, from, next) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // to 어디로 가려고 하고</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // from 어디에서 왔고</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">  // 처리 다 끝나고 next(); 로 이동 가능하다.</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>next 함수는 아규먼트로 아래 예제처럼 사용 가능하다.</p>
<div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">next</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'/'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// '/' 주소로 이동한다.</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">next</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(from.path) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// 왔던 주소로 돌아간다.</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h2 id="_3-beforeunload-event" tabindex="-1">3. beforeunload Event <a class="header-anchor" href="#_3-beforeunload-event" aria-label="Permalink to &quot;3. beforeunload Event&quot;"></a></h2>
<p>사이트를 나가려고 할 때 정말 나가시겠습니까? 하고 뜨는 알림 창이다.<br>
창 닫기를 할 경우나 새로고침을 할 경우 경고를 띄워줄 수 있다.<br>
비동기 처리가 끝나고 창이 닫히게는 안 되는 거 같지만 창을 닫기 직전에 임시저장 처리 등을 해줄 수 있다.</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> leave</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">event</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  event.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">preventDefault</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">()</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  event.returnValue </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ''</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">onMounted</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  window.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">addEventListener</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'beforeunload'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, leave)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">onBeforeUnMount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  window.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">removeEventListener</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'beforeunload'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, leave)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">})</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p>이렇게만 하면 알림 창이 나오긴 나온다.</p>
<p><img src="/images/beforeunload-alert.png" alt="before unload alert"></p>
<p>문제는 나가기 버튼을 누른 후에 뭔갈 할 수가 없다.<br>
api를 쏴보려고 해도 빛에 속도로 나가 지더라...</p>
]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 백틱 ( ` )]]></title>
            <link>https://leteu.dev/posts/js-template-literal</link>
            <guid>https://leteu.dev/posts/js-template-literal</guid>
            <pubDate>Tue, 20 Jan 1970 00:26:01 GMT</pubDate>
            <content:encoded><![CDATA[<h2 id="_1-탬플릿-리터널" tabindex="-1">1. 탬플릿 리터널 <a class="header-anchor" href="#_1-탬플릿-리터널" aria-label="Permalink to &quot;1. 탬플릿 리터널&quot;"></a></h2>
<p>ES6부터 도입된 문자열이다.<br>
백틱 ( ` )을 사용한다.</p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals" target="_blank" rel="noreferrer">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals</a></p>

      <div>
        <a
          href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals"
          target="_blank"
          class="url-embed row"
          style="--theme-color: #2e2e2e"
        >
          <div class="col url-embed__container">
            <div class="url-embed__title">Template literals - JavaScript | MDN</div>
            <div class="url-embed__desc">템플릿 리터럴은 내장된 표현식을 허용하는 문자열 리터럴입니다. 여러 줄로 이뤄진 문자열과 문자 보간기능을 사용할 수 있습니다. 이전 버전의 ES2015사양 명세에서는 "template strings" (템플릿 문자열) 라고 불려 왔습니다.</div>
            <div class="col"></div>
            <div class="url-embed__info">
              <span>https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals</span>
            </div>
          </div>
          <div class="url-embed__image"><img src="https://developer.mozilla.org/mdn-social-share.d893525a4fb5fb1f67a2.png" alt="" /></div>
        </a>
      </div><p>위 문서를 기반으로 포스팅한 글이다.<br>
블로그만 보지 말고 공식 문서도 한번 읽어보면 좋겠다.</p>
<h2 id="_2-줄-바꿈" tabindex="-1">2. 줄 바꿈 <a class="header-anchor" href="#_2-줄-바꿈" aria-label="Permalink to &quot;2. 줄 바꿈&quot;"></a></h2>
<p>기존 문자열은 \n과 같은 거로 줄 바꿈 해야 했지만 이젠 그냥 엔터 치고 줄 바꿈 하면 그대로 들어간다.</p>
<p>기존</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '줄바꿈</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">줄바꿈'</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>백틱 사용</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> `줄바꿈</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">줄바꿈`</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h2 id="_3-변수-사용" tabindex="-1">3. 변수 사용 <a class="header-anchor" href="#_3-변수-사용" aria-label="Permalink to &quot;3. 변수 사용&quot;"></a></h2>
<p>기존엔 문자열 따옴표 사이사이마다 변수와 플러스(+)의 향연이었지만 이젠 더 이쁘게 사용할 수 있다.<br>
이전엔 띄어쓰기 같은 경우에도 문자열에 넣어주고 더해줬지만 이젠 사이사이마다 ${}로 변수를 넣어줄 수 있다.</p>
<p>기존</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> age</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 21</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> gender</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '남'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> nickname</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'leteu'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '별명: '</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> nickname </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ' / 나이: '</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> age </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ' / 성별: '</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> gender</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>백틱 사용</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> age</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 21</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> gender</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '남'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> nickname</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 'leteu'</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> `별명: ${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">nickname</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">} / 나이: ${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">age</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">} / 성별: ${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">gender</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">}`</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h2 id="_4-dom-생성시" tabindex="-1">4. Dom 생성시 <a class="header-anchor" href="#_4-dom-생성시" aria-label="Permalink to &quot;4. Dom 생성시&quot;"></a></h2>
<p>자바스크립트에서 Dom Element를 생성시 html 문자열을 짜야하는 상황이 있을 수 있다.<br>
그때도 유용하게 쓸 수 있다.</p>
<div class="language-html vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">&#x3C;!-- index --></span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;!</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">doctype</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> html</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">html</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"en"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">head</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">meta</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> charset</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"UTF-8"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">meta</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      http-equiv</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"X-UA-Compatible"</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"IE=edge"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">meta</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"viewport"</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">      content</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"width=device-width, initial-scale=1.0"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    /></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">title</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>Document&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">title</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">head</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"box"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &#x3C;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> src</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"index.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">>&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&#x3C;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">html</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">></span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div><p>기존</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">/* index.js */</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">let</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> temp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> ''</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">temp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '&#x3C;h3>박스&#x3C;/h3>'</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">temp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '&#x3C;div>'</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">temp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '&#x3C;span>텍스트&#x3C;/span>'</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">temp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> '&#x3C;/div>'</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getElementById</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'box'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">appendChild</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(temp)</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>백틱 사용</p>
<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0" v-pre=""><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">/* index.js */</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> `</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  &#x3C;h3>박스&#x3C;/h3></span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  &#x3C;div></span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">    &#x3C;span>텍스트&#x3C;/span></span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  &#x3C;/div></span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">`</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">getElementById</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">'box'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">appendChild</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(temp)</span></span></code></pre>
<div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div>]]></content:encoded>
            <author>contact@leteu.dev (Shin Gyuhyeon)</author>
        </item>
    </channel>
</rss>