<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>shaking blog</title>
    <link>https://88240.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 9 Apr 2026 00:21:07 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>shaking</managingEditor>
    <image>
      <title>shaking blog</title>
      <url>https://tistory1.daumcdn.net/tistory/1409332/attach/31eb2365a34e40a2ac75c31ea56442c9</url>
      <link>https://88240.tistory.com</link>
    </image>
    <item>
      <title>[CSS] z-index 에 대해서</title>
      <link>https://88240.tistory.com/541</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; font-size: 1.44em; letter-spacing: -1px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot;&gt;z-index 의 특징&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;z-index 값이 클 수록 위로 올라온다. &lt;br /&gt;ex) A 의 z-index 는 0, B 의 z-index는 1 일 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.28.03.png&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b443wt/btsDQ9kxY8R/i0EJAogajst3MLCuKFO720/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b443wt/btsDQ9kxY8R/i0EJAogajst3MLCuKFO720/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b443wt/btsDQ9kxY8R/i0EJAogajst3MLCuKFO720/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb443wt%2FbtsDQ9kxY8R%2Fi0EJAogajst3MLCuKFO720%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;234&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.28.03.png&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;z-index 값이 같을 경우 나중에 배치된 레이어가 위로 올라온다.&lt;br /&gt;ex) A 와 B 의 z-index 모두 0 인데, html B 가 더 나중에 배치된 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.28.27.png&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buvY23/btsDQRqQJd7/Cs7wBm0i3QFOhaHN2yBUkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buvY23/btsDQRqQJd7/Cs7wBm0i3QFOhaHN2yBUkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buvY23/btsDQRqQJd7/Cs7wBm0i3QFOhaHN2yBUkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuvY23%2FbtsDQRqQJd7%2FCs7wBm0i3QFOhaHN2yBUkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;352&quot; height=&quot;262&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.28.27.png&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;태그 깊이가 같은 것 끼리만 비교가 된다.&lt;br /&gt;ex) A 는 z-index가 2, B 는 z-index 1, C 는 z-index 3 일 때 A &amp;gt; C &amp;gt; B 순으로 나타난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1706063333671&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;A&quot;&amp;gt;A&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;B&quot;&amp;gt;
  B
  &amp;lt;div class=&quot;C&quot;&amp;gt;C&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.29.01.png&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uPoNb/btsDQ8Ts5sh/kKrwqasnde3tY3Hf6quCi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uPoNb/btsDQ8Ts5sh/kKrwqasnde3tY3Hf6quCi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uPoNb/btsDQ8Ts5sh/kKrwqasnde3tY3Hf6quCi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuPoNb%2FbtsDQ8Ts5sh%2FkKrwqasnde3tY3Hf6quCi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;382&quot; height=&quot;299&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.29.01.png&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;rarr; A 와 B 중 A z-index 값이 더 크므로 A가 B 보다 위로 위치한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;rarr; B 와 C 중 C z-index 값이 더 크므로 C 가 B 보다 위로 위치한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;즉, 부모 영향을 받으니 아무리 z-index 값이 크더라도 다른 요소들 보다 아래에 위치할 수 있음을 유의할 것&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;z-index 값의 기본 값 (선언하지 않은 값) 은 0 이 아니라 auto 이다. 이말은 즉,
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 쌓임 맥락에서의 자신의 위치 : 3번 예시로 설명 됨&lt;/li&gt;
&lt;li&gt;자신만의 쌓임 맥락 생성 여부
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 말은 z-index: auto로 지정하거나 z-index를 설정하지 않은 경우에는 쌓임에 대한 정의가 아예 아무것도 없다는 의미. (z-index: 0 은 쌓임 맥락은 있지만 값이 0 일뿐)&lt;br /&gt;ex) 3 예시에서 B 의 z-index 을 아예 없앴을 경우 C &amp;gt; A &amp;gt; B 순으로 나타난다.&lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.29.57.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCx4dv/btsDNIHMG9x/FxcamOVoPKqPHLzdfEukUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCx4dv/btsDNIHMG9x/FxcamOVoPKqPHLzdfEukUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCx4dv/btsDNIHMG9x/FxcamOVoPKqPHLzdfEukUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCx4dv%2FbtsDNIHMG9x%2FFxcamOVoPKqPHLzdfEukUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;518&quot; height=&quot;436&quot; data-filename=&quot;스크린샷 2024-01-24 오전 11.29.57.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;rarr; B 에 z-index 가 있었을 때는, A와 B를 비교했지만 (형제끼리 비교)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;B 의 z-index 가 auto 이면, B의 자식인 C 가 비교할 대상으로 선정된다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;따라서, C(z-index: 3) 가 A(z-index: 2) 보다 더 위에 위치하게 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;즉!
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;z-index 는 기본적으로 형제 끼리 비교가 우선이다.&lt;/li&gt;
&lt;li&gt;하지만 형제의 z-index 값이 auto 이면 형제의 자식도 확인하여 비교한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;다른-디자인-시스템-Use-Case-정리&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;1221&quot; data-ke-size=&quot;size23&quot;&gt;다른 디자인 시스템 Use Case 정리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vuetify
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://vuetifyjs.com/en/components/dialogs/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;dialog&lt;/a&gt;: 202&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vuetifyjs.com/en/components/snackbars/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;snackbar&lt;/a&gt;: 1000&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vuetifyjs.com/en/components/tooltips/#tooltips&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;tooltip&lt;/a&gt;: 8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;meterial - &lt;a href=&quot;https://mui.com/material-ui/customization/z-index/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ant - zindex 를 props 로 받음
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://ant.design/components/popover&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;popover&lt;/a&gt;: 1030&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ant.design/components/tooltip&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;tooltip&lt;/a&gt;: 1070&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ant.design/components/popconfirm&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;popconfirm&lt;/a&gt;: 1060&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ant.design/components/modal&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;modal&lt;/a&gt;: 1000&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ant.design/components/notification&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;notification&lt;/a&gt;: 1050&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ant.design/components/drawer&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;drawer&lt;/a&gt;: 1000&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;bootstrap - &lt;a href=&quot;https://getbootstrap.com/docs/5.3/layout/z-index/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://getbootstrap.com/docs/5.3/components/modal/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;modal&lt;/a&gt;: 1055&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://getbootstrap.com/docs/5.3/components/popovers/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;popover&lt;/a&gt;: 1070&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://getbootstrap.com/docs/5.3/components/toasts/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;toast&lt;/a&gt;: 1090&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://getbootstrap.com/docs/5.3/components/tooltips/&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;tooltip&lt;/a&gt;: 1080&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;chakra - &lt;a href=&quot;https://chakra-ui.com/docs/styled-system/theme#z-index-values&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;forma - &lt;a href=&quot;https://f36.contentful.com/tokens/z-index#__next&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;salesforce - &lt;a href=&quot;https://www.lightningdesignsystem.com/design-tokens/#category-z-index&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;nord - &lt;a href=&quot;https://nordhealth.design/tokens/#z-index&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;stackoverflow - &lt;a href=&quot;https://stackoverflow.design/product/base/z-index/#classes&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;shoelace - &lt;a href=&quot;https://shoelace.style/tokens/z-index&quot; data-renderer-mark=&quot;true&quot; data-testid=&quot;link-with-safety&quot;&gt;zindex&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;background-color: #ffffff; color: #172b4d; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-table-width=&quot;760&quot; data-number-column=&quot;false&quot; data-testid=&quot;renderer-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;vuetify&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;202&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;202&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;merterial&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1050&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1200&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1300&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1400&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;ant&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1050&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1070&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;bootstrap&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1020&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1030&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1070&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1090&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1080&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;charkra&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1100&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1400&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1700&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;shoelace&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;900&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;700&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;800&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;nord&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;400&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;300&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;900&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;800&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;stackoverflow&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;9000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left; width: 17.2093%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;forma&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 13.8372%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.65116%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 9.76744%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; width: 10.2326%;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;75.56&quot;&gt;1000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>CSS</category>
      <category>z-index</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/541</guid>
      <comments>https://88240.tistory.com/541#entry541comment</comments>
      <pubDate>Wed, 24 Jan 2024 11:33:53 +0900</pubDate>
    </item>
    <item>
      <title>지원 브라우저 확인 하는 사이트</title>
      <link>https://88240.tistory.com/540</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://caniuse.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://caniuse.com/&lt;/a&gt;&lt;/p&gt;</description>
      <category>Browser</category>
      <category>Developer</category>
      <category>js</category>
      <category>MEMO</category>
      <category>vue</category>
      <category>개발</category>
      <category>메모</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/540</guid>
      <comments>https://88240.tistory.com/540#entry540comment</comments>
      <pubDate>Wed, 17 Jan 2024 16:50:35 +0900</pubDate>
    </item>
    <item>
      <title>맥북에서 Apple 기기 테스트 하는 방법</title>
      <link>https://88240.tistory.com/539</link>
      <description>&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;spotlight 검색 열기 (command + space bar)&lt;/li&gt;
&lt;li&gt;simulator 검색&lt;/li&gt;
&lt;li&gt;docker 위의 simulator 아이콘 에서 마우스 오른쪽 &amp;rarr; device 선택&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>apple</category>
      <category>ios</category>
      <category>MAC</category>
      <category>macbook</category>
      <category>Safari</category>
      <category>Simulator</category>
      <category>text</category>
      <category>맥북</category>
      <category>연결</category>
      <category>테스트</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/539</guid>
      <comments>https://88240.tistory.com/539#entry539comment</comments>
      <pubDate>Wed, 17 Jan 2024 16:49:49 +0900</pubDate>
    </item>
    <item>
      <title>Storybook Button Example (feat. vue)</title>
      <link>https://88240.tistory.com/538</link>
      <description>&lt;h3 data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size23&quot;&gt;Start&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;package.json 에 다음과 같이 명령어를 넣는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1705477150377&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  &quot;scripts&quot;: {
    &quot;dev&quot;: &quot;vite&quot;,
    ...
    &quot;preview&quot;: &quot;vite preview&quot;,
    &quot;storybook&quot;: &quot;storybook dev -p 6006&quot;
  },&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다음 명령어를 통해 Storybook 을 실행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;dockerfile&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;npm run dev:storybook&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;http://localhost:3003&amp;nbsp;로&amp;nbsp;Storybook&amp;nbsp;이&amp;nbsp;자동&amp;nbsp;실행&amp;nbsp;된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;c04a5948-f80e-41b9-bee3-e603b4af863e.png&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;1322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSiQlk/btsDCTnY8jW/8RGTVFuiYlB06LnF0FkOqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSiQlk/btsDCTnY8jW/8RGTVFuiYlB06LnF0FkOqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSiQlk/btsDCTnY8jW/8RGTVFuiYlB06LnF0FkOqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSiQlk%2FbtsDCTnY8jW%2F8RGTVFuiYlB06LnF0FkOqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1710&quot; height=&quot;1322&quot; data-filename=&quot;c04a5948-f80e-41b9-bee3-e603b4af863e.png&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;1322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;Button Example&lt;/h3&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;1. Button Story 를 추가해봤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5.png&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DxIRT/btsDxxGXDzD/pKQfVdVFurakSMG3P0ZEsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DxIRT/btsDxxGXDzD/pKQfVdVFurakSMG3P0ZEsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DxIRT/btsDxxGXDzD/pKQfVdVFurakSMG3P0ZEsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDxIRT%2FbtsDxxGXDzD%2FpKQfVdVFurakSMG3P0ZEsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;310&quot; height=&quot;128&quot; data-filename=&quot;5.png&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 전체적인 코드를 먼저 대략적으로 말하자면, Button Component 에서 label, primary 여부, size, backgroundColor 를 props 으로 받고 click 이벤트를 세팅했다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스토리 포맷의 세부 내용은 다음과 같다. 기본적으로 스토리를 만들기 위해서는 &lt;span&gt;title&lt;/span&gt;, &lt;span&gt;component&lt;/span&gt;, &lt;span&gt;template&lt;/span&gt; 이 있어야한다. 다음은 primary 스토리를 만든 예시이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;routeros&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;import CommonButton from './CommonButton.vue';

export default {
  title: 'Example/Button',
  component: CommonButton,
};

export const Primary = () =&amp;gt; ({
  components: { CommonButton },
  template: '&amp;lt;CommonButton primary label=&quot;Button&quot; /&amp;gt;',
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;title&lt;/b&gt; 은 Storybook 의 tree 구조 및 라이브러리와 스토리 이름을 정할 때 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;6.png&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c65SdF/btsDyCH27va/K6ftkkFwO44dF1aLWVYPT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c65SdF/btsDyCH27va/K6ftkkFwO44dF1aLWVYPT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c65SdF/btsDyCH27va/K6ftkkFwO44dF1aLWVYPT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc65SdF%2FbtsDyCH27va%2FK6ftkkFwO44dF1aLWVYPT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;458&quot; height=&quot;248&quot; data-filename=&quot;6.png&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-pm-slice=&quot;3 3 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;component&lt;/span&gt;&lt;/b&gt; 는 미리 보려하는 구성 요소를 뜻한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;template&lt;/span&gt;&lt;/b&gt; 은 말 그대로 사용할 컴포넌트 템플릿을 만들 때 사용한다. 자유롭게 인자를 지정하여 여러개의 스토리를 만들 수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 자유롭게&amp;nbsp;인자를&amp;nbsp;지정하기&amp;nbsp;위해서는&amp;nbsp;args&amp;nbsp;와&amp;nbsp;argTypes&amp;nbsp;를&amp;nbsp;이용하면&amp;nbsp;된다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;import CommonButton from './CommonButton.vue';

export default {
  title: 'Example/Button',
  component: CommonButton,
  args: {
    backgroundColor: '#000'
  },
  argTypes: {
    backgroundColor: { control: 'color' },
  }
};
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-pm-slice=&quot;3 3 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;args&lt;/span&gt;&lt;/b&gt; 는 모든 스토리에 공통으로 전달될 props 를 말한다. 예를 들어 위와 같이 설정 했을 경우 모든 스토리에 공통으로 backgroundColor 가 검정색으로 전달이 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;argTypes&lt;/span&gt;&lt;/b&gt; 는 각 스토리 &lt;span&gt;args&lt;/span&gt; 의 행동(behaviour) 방식을 설정한다. 예를 들어 위와 같이 설정 했을 경우 Controls 에서 선택한 색상을 bacgroundColor 에 적용할 수 있도록 props 를 전달하겠다는 의미이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;8.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqYIQS/btsDBSiAGqI/t5og6x8OKgy8fekCj5U800/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqYIQS/btsDBSiAGqI/t5og6x8OKgy8fekCj5U800/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqYIQS/btsDBSiAGqI/t5og6x8OKgy8fekCj5U800/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqYIQS%2FbtsDBSiAGqI%2Ft5og6x8OKgy8fekCj5U800%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1032&quot; height=&quot;380&quot; data-filename=&quot;8.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 그 외 decorators, parameters, excludeStories&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://storybook.js.org/docs/react/writing-stories/introduction&quot;&gt;등&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;decorators&lt;/span&gt; : 스토리를 래핑하는 추가 랜더링 기능&lt;/li&gt;
&lt;li&gt;&lt;span&gt;parameters&lt;/span&gt; : 스토리에 대한 정적 메타 데이터 정의&lt;/li&gt;
&lt;li&gt;&lt;span&gt;excludeStories&lt;/span&gt; : 랜더링 제외 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 다음은 &lt;span&gt;args&lt;/span&gt; 와 &lt;span&gt;argTypes&lt;/span&gt; 를 이용해 여러개의 스토리 &lt;span&gt;template&lt;/span&gt; 을 만든 코드이다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;...
const Template: any = (args: any, { argTypes }: any) =&amp;gt; ({
  props: Object.keys(argTypes),
  components: { CommonButton },
  template: '&amp;lt;CommonButton v-bind=&quot;$props&quot; /&amp;gt;'
});

export const Primary = Template.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Button',
};

export const Large = Template.bind({});
Large.args = {
  size: 'large',
  label: 'Button',
};

export const Small = Template.bind({});
Small.args = {
  size: 'small',
  label: 'Button',
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 위에서 만든 CommonButton Component 의 스토리를 만들어봤다.&lt;/p&gt;
&lt;pre id=&quot;code_1705477387381&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import CommonButton from './CommonButton.vue';

export default {
  title: 'Example/Button',
  component: CommonButton,
  argTypes: {
    backgroundColor: { control: 'color' },
    size: {
      control: { type: 'select' },
      options: ['small', 'medium', 'large'],
    },
  }
};

const Template: any = (args: any, { argTypes }: any) =&amp;gt; ({
  props: Object.keys(argTypes),
  components: { CommonButton },
  template: '&amp;lt;CommonButton @click=&quot;onClick&quot; v-bind=&quot;$props&quot; /&amp;gt;'
});

export const Primary = Template.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Button',
};

export const Large = Template.bind({});
Large.args = {
  size: 'large',
  label: 'Button',
};

export const Small = Template.bind({});
Small.args = {
  size: 'small',
  label: 'Button',
};&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Helloworld!/Vue</category>
      <category>Button</category>
      <category>example</category>
      <category>storybook</category>
      <category>vue</category>
      <category>스토리북</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/538</guid>
      <comments>https://88240.tistory.com/538#entry538comment</comments>
      <pubDate>Wed, 17 Jan 2024 16:46:21 +0900</pubDate>
    </item>
    <item>
      <title>Storybook 시작하기 (feat. vue)</title>
      <link>https://88240.tistory.com/537</link>
      <description>&lt;h3 id=&quot;Install&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;2&quot; data-ke-size=&quot;size23&quot;&gt;Install&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;2&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;1. Storybook CLI 사용해 설치한다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;npx sb init&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-pm-slice=&quot;3 3 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;루트 안에 &lt;span&gt;.storybook&lt;/span&gt; 과 &lt;span&gt;storybook-static&lt;/span&gt; 추가된다.&lt;/li&gt;
&lt;li&gt;package.json 에 명령어 추가된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;erlang&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;...
&quot;storybook&quot;: &quot;start-storybook -p 6006&quot;,
&quot;build-storybook&quot;: &quot;build-storybook&quot;
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;span&gt;.gitignore&lt;/span&gt; 에 다음과 같이 추가한다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;.storybook
storybook-static&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Stroybook 을 다음 명령어로 실행한다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;npm run storybook&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;http://localhost:6006 로 Storybook 자동 실행 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22c52d2e-7220-429c-bfc9-9e9a46cc7fad.png&quot; data-origin-width=&quot;3258&quot; data-origin-height=&quot;1829&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNUYcZ/btsDCOmBEXX/zpLuKJgB5OPmgakjSeni60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNUYcZ/btsDCOmBEXX/zpLuKJgB5OPmgakjSeni60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNUYcZ/btsDCOmBEXX/zpLuKJgB5OPmgakjSeni60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNUYcZ%2FbtsDCOmBEXX%2FzpLuKJgB5OPmgakjSeni60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3258&quot; height=&quot;1829&quot; data-filename=&quot;22c52d2e-7220-429c-bfc9-9e9a46cc7fad.png&quot; data-origin-width=&quot;3258&quot; data-origin-height=&quot;1829&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;Setting&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-pm-slice=&quot;1 1 [&amp;quot;panel&amp;quot;,{&amp;quot;panelType&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;panelIcon&amp;quot;:null,&amp;quot;panelIconId&amp;quot;:null,&amp;quot;panelIconText&amp;quot;:null,&amp;quot;panelColor&amp;quot;:null}]&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;.storybook/main.js 에서 스토리 위치 외 Storybook 에 관련된 다양한 &lt;a href=&quot;https://storybook.js.org/docs/react/configure/overview&quot;&gt;옵션&lt;/a&gt;들을 세팅할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 스토리 위치 세팅&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;.storybook/main.js&lt;/span&gt; 를 보면 Stroybook 설치 시 기본 세팅이 다음과 같이 &lt;span&gt;stories&lt;/span&gt; 폴더 하위에 스토리가 위치하도록 되어있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;module.exports = {
  &quot;stories&quot;: [
    &quot;../stories/**/*.stories.mdx&quot;,
    &quot;../stories/**/*.stories.@(js|jsx|ts|tsx)&quot;,
  ],
  ... &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;components&amp;nbsp;내부에&amp;nbsp;Component.vue&amp;nbsp;와&amp;nbsp;동일한&amp;nbsp;이름으로&amp;nbsp;같이&amp;nbsp;있는게&amp;nbsp;대세&amp;nbsp;같아&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;수정했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;module.exports = {
  &quot;stories&quot;: [
    &quot;../components/*.stories.@(js|jsx|ts|tsx)&quot;
  ],
  ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;span&gt;scss&lt;/span&gt; 세팅 &lt;a href=&quot;https://storybook.js.org/docs/react/addons/install-addons#using-preset-addons&quot;&gt;#&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다음 명령어 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;css&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;npm install @storybook/preset-scss css-loader sass sass-loader style-loader --save-dev&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.storybook/main.js 의 addon 에 설치한 preset-scss 추가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;prolog&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null,&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;module.exports = {
  ...
  &quot;addons&quot;: [
    ...
    '@storybook/preset-scss'
  ],
  ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;Example&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Storybook 에선 Component 를 Library, 예시를 Story 라고 부른다.&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Button Story 를 추가해봤다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;c04a5948-f80e-41b9-bee3-e603b4af863e.png&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;1322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEjf7E/btsDyPtz8jC/0CVKiANIKPK1aL3w8cmKI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEjf7E/btsDyPtz8jC/0CVKiANIKPK1aL3w8cmKI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEjf7E/btsDyPtz8jC/0CVKiANIKPK1aL3w8cmKI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEjf7E%2FbtsDyPtz8jC%2F0CVKiANIKPK1aL3w8cmKI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1710&quot; height=&quot;1322&quot; data-filename=&quot;c04a5948-f80e-41b9-bee3-e603b4af863e.png&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;1322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CommonButton.vue&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1705476167822&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;button type=&quot;button&quot; :class=&quot;classes&quot; @click=&quot;onClick&quot; :style=&quot;style&quot;&amp;gt;{{ label }}&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script lang=&quot;ts&quot;&amp;gt;
import { Component, Prop, Vue } from 'nuxt-property-decorator'

@Component
export default class Button extends Vue {
  @Prop({ type: String, required: true })
  label: string

  @Prop({ type: Boolean, default: false })
  primary: boolean

  @Prop({ type: String, default: 'medium', validator: (value) =&amp;gt; { return ['small', 'medium', 'large'].indexOf(value) !== -1; } })
  size: string

  @Prop({ type: String })
  backgroundColor!: String

  get classes() {
    return {
      'CommonButton': true,
      'CommonButton--primary': this.primary,
      'CommonButton--secondary': !this.primary,
      [`CommonButton--${this.size}`]: true,
    };
  }

  get style() {
    return {
      backgroundColor: this.backgroundColor,
    };
  }

  onClick() {
    this.$emit('onClick');
  }
}
&amp;lt;/script&amp;gt;

&amp;lt;style lang=&quot;scss&quot;&amp;gt;
.CommonButton {
  font-weight: 700;
  border: 0;
  border-radius: 3em;
  cursor: pointer;
  display: inline-block;
  line-height: 1;

  &amp;amp;--primary {
    color: white;
    background-color: #1ea7fd;
  }

  &amp;amp;--secondary {
    color: #333;
    background-color: transparent;
    box-shadow: rgba(0, 0, 0, 0.15) 0 0 0 1px inset;
  }

  &amp;amp;--small {
    font-size: 12px;
    padding: 10px 16px;
  }

  &amp;amp;--medium {
    font-size: 14px;
    padding: 11px 20px;
  }

  &amp;amp;--large {
    font-size: 16px;
    padding: 12px 24px;
  }
}
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CommonButton.stoires.ts&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1705476219091&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import CommonButton from './CommonButton.vue';

export default {
  title: 'Example/Button',
  component: CommonButton,
  decorators: [withDesign],
  argTypes: {
    backgroundColor: { control: 'color' },
    size: {
      control: { type: 'select' },
      options: ['small', 'medium', 'large'],
    },
  }
} as CompomentMeta&amp;lt;typeof CommonButton&amp;gt;;

const CommonButtonStory: ComponentStory&amp;lt;typeof CommonButtonStory&amp;gt; = (args, { argTypes }) =&amp;gt; ({
  props: Object.keys(argTypes),
  components: { CommonButton: CommonButton },
  template: '&amp;lt;CommonButton @click=&quot;onClick&quot; v-bind=&quot;$props&quot; /&amp;gt;'
});

export const Primary = CommonButtonStory.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
};

export const Secondary = CommonButtonStory.bind({});
Secondary.args = {
  label: 'Button',
};

export const Large = CommonButtonStory.bind({});
Large.args = {
  size: 'large',
  label: 'Button',
};

export const Small = CommonButtonStory.bind({});
Small.args = {
  size: 'small',
  label: 'Button',
};&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;Responsive Test&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Canvas &amp;gt; Change the size of the preview 버튼 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvkxZl/btsDC8d7Pvf/xGAKc8yiYGaI20k85CFZfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvkxZl/btsDC8d7Pvf/xGAKc8yiYGaI20k85CFZfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvkxZl/btsDC8d7Pvf/xGAKc8yiYGaI20k85CFZfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvkxZl%2FbtsDC8d7Pvf%2FxGAKc8yiYGaI20k85CFZfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1162&quot; height=&quot;282&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 원하는 화면 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZL6pK/btsDD0NCoWp/r49FY0TM6THtum6aIqBm00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZL6pK/btsDD0NCoWp/r49FY0TM6THtum6aIqBm00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZL6pK/btsDD0NCoWp/r49FY0TM6THtum6aIqBm00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZL6pK%2FbtsDD0NCoWp%2Fr49FY0TM6THtum6aIqBm00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;415&quot; height=&quot;316&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 직접 Viewport 추가하는 방법&lt;/p&gt;
&lt;pre class=&quot;vim&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;// .stroybook/preview.js

export const parameters = {
  viewport: {
    iphone5: {
      name: 'iPhone 5',
      styles: {
        height: '667px',
        width: '375px',
      },
      type: 'mobile',
    },
    iphoneXr: {
      name: 'iPhone XR',
      styles: {
        height: '896px',
        width: '414px',
      },
      type: 'mobile',
    },
    ...
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 기본적으로 Storybook 에서 제공하는 Viewport 세팅 하는 방법 &lt;a href=&quot;https://storybook.js.org/docs/react/essentials/viewport#use-a-detailed-set-of-devices&quot;&gt;#&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;// .storybook/preview.js

import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';

export const parameters = {
  viewport: {
    viewports: INITIAL_VIEWPORTS,
  },
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 특정 예시에 기본 Viewport 지정하는 방법&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;CommonButton 스토리에 Viewport 를 Storybook 에서 제공하는 Viewport 세팅하고, 기본적으로 보여질 화면을 아이폰 6로 지정한 예시이다. Component &lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;parameters&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt; 를 사용해 설정할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;routeros&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;export default {
  title: 'Example/Button',
  component: CommonButton,
  parameters: {
    viewport: {
       viewports: INITIAL_VIEWPORTS,
       defaultViewport: 'iphone6'
    }
  },
 ...
} as CompomentMeta&amp;lt;typeof CommonButton&amp;gt;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,{},&amp;quot;listItem&amp;quot;,{},&amp;quot;bulletList&amp;quot;,{},&amp;quot;listItem&amp;quot;,null]&quot;&gt;CommonButton 스토리 중 primary 버튼에 Viewport 를 지정 후 기본적으로 보여질 화면을 아이폰 X 로 지정한 예시이다. 스토리 parameters 에 Viewport 를 추가하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;gams&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,{},&amp;quot;listItem&amp;quot;,{},&amp;quot;bulletList&amp;quot;,{},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;Primary.parameters = {
  viewport: {
    viewports: INITIAL_VIEWPORTS,
    defaultViewport: 'iphonex'
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;Addon Figma&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. storybook-addon-designs 설치한다. &lt;a href=&quot;https://storybook.js.org/addons/storybook-addon-designs&quot;&gt;#&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;q&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;npm install --save-dev storybook-addon-designs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;span&gt;.storybook/main.js&lt;/span&gt; 의 addon 에 &lt;span&gt;storybook-addon-designs&lt;/span&gt; 추가한다.&lt;/p&gt;
&lt;pre class=&quot;prolog&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;module.exports = {
  ...
  &quot;addons&quot;: [
    ...
    'storybook-addon-designs'
  ],
  ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;span&gt;CommonButton.storires.ts&lt;/span&gt; 에 다음 코드를 추가한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;export default {
  ...
  decorators: [withDesign],
  parameters: {
    design: {
      type: 'figma',
      url:
        'https://www.figma.com/file/LKQ4FJ4bTnCSjedbRpk931/Sample-File'
    },
  },
  ...
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Design 탭에서 연동된 Figma 를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;2064&quot; data-origin-height=&quot;1048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/emUgpA/btsDyOOWIuV/wvfzK3IhcluVTK3yqcmpVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/emUgpA/btsDyOOWIuV/wvfzK3IhcluVTK3yqcmpVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/emUgpA/btsDyOOWIuV/wvfzK3IhcluVTK3yqcmpVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FemUgpA%2FbtsDyOOWIuV%2FwvfzK3IhcluVTK3yqcmpVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2064&quot; height=&quot;1048&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;2064&quot; data-origin-height=&quot;1048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Story 별로 Figma 연동하고 싶을 경우는 다음과 같이 작성하면 된다.&lt;/p&gt;
&lt;pre class=&quot;scala&quot; data-pm-slice=&quot;1 1 [&amp;quot;orderedList&amp;quot;,{&amp;quot;order&amp;quot;:1},&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;export default {
  ...
  decorators: [withDesign],
  ...
};
...
Primary.args = {
  primary: true,
  label: 'Button',
};
Primary.parameters = { //Primary Story 에만 figma 연동
  design: {
    type: 'figma',
      url:
    'https://www.figma.com/file/LKQ4FJ4bTnCSjedbRpk931/Sample-File',
  },
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Helloworld!/Vue</category>
      <category>js</category>
      <category>storybook</category>
      <category>vue</category>
      <category>스토리북</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/537</guid>
      <comments>https://88240.tistory.com/537#entry537comment</comments>
      <pubDate>Wed, 17 Jan 2024 16:28:24 +0900</pubDate>
    </item>
    <item>
      <title>[Vue] Vue2 에 Composition API 적용하기</title>
      <link>https://88240.tistory.com/536</link>
      <description>&lt;h3 data-pm-slice=&quot;0 0 []&quot; data-ke-size=&quot;size23&quot;&gt;Composition API 설치&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;install&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;css&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;npm install @nuxtjs/composition-api --save&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;plugin 추가&lt;br /&gt;&lt;a href=&quot;https://bitbucket.org/backpackr/web.idus.com/src/f71db99f7dbd/plugins/composition-api.plugin.ts&quot;&gt;https://bitbucket.org/backpackr/web.idus.com/src/f71db99f7dbd/plugins/composition-api.plugin.ts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;nuxt.config.ts &amp;gt; buildModules 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;golo&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;buildModules: [
    ...
    '@nuxtjs/composition-api/module'
  ],&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Composition API 사용 하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Composition API import&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;nimrod&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;import {reactive, ref} from &quot;@nuxtjs/composition-api&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;setup()&lt;/span&gt;에 전달된 인자에 대한 타입을 추론하려면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;defineComponent&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 사용해야한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://v3.ko.vuejs.org/api/composition-api.html#setup&quot;&gt;#&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;xquery&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;&amp;lt;script lang=&quot;ts&quot;&amp;gt;
export default defineComponent({
  name: 'HomePage',
  components: {
    Logo,
  },
  setup() {
    const count: number = ref(0)
    return { count }
  }
})
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Ref&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;setup&lt;/span&gt; 안에서 &lt;span&gt;ref&lt;/span&gt; 를 출력할 땐 &lt;span&gt;.value&lt;/span&gt; 를 붙여줘야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;applescript&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;let count = ref(0)
console.log(count.value)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 처럼 타입을 정의하지 않아도 알아서 타입을 체크하지만,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;ref&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 타입을 정의하고 싶다면 다음과 같이 두가지 방법이 있다&lt;br /&gt;첫번째 방법은 여러 타입을 정의할 때 사용하고, 두번째 방법은 기존에 지정 했던 타입을 재정의 할 때 사용하길 권장한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://vuejs.org/guide/typescript/composition-api.html#typing-ref&quot;&gt;#&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;const count: Ref&amp;lt;number | string&amp;gt; = ref('0') // 또는
const count = ref&amp;lt;number | string&amp;gt;(0)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Reactive&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;ref&lt;/span&gt; 와 달리 &lt;span&gt;reactive&lt;/span&gt; 는 중첩된 타입을 가지 않는것을 권장한다. &lt;a href=&quot;https://vuejs.org/guide/typescript/composition-api.html#typing-reactive&quot;&gt;#&lt;/a&gt;&lt;br /&gt;그래서 그런지 위와 같이 여러 타입 정의할 수 있도록 도와주는 interface 가 존재하지 않는다. &lt;span data-emoji-text=&quot; &quot; data-emoji-id=&quot;1f612&quot; data-emoji-short-name=&quot;:unamused:&quot;&gt; &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;출력은 &lt;span&gt;ref&lt;/span&gt; 와 다르게 &lt;span&gt;.value&lt;/span&gt; 없이 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;const header = reactive&amp;lt;IHeader&amp;gt;({ title: 'hello idus', useLogo: false }) // 또는
const header: IHeader = reactive({ title: 'hello idus', useLogo: false })
console.log(header.title)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Computed&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;get&lt;/span&gt; 만 할 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;moonscript&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;const handleClickInclude = () =&amp;gt; count.value++
const handleClickExclude = () =&amp;gt; count.value--&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;get&lt;/span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모두 사용할 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;arduino&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;const computedText = computed({
    get: (): string =&amp;gt; text.value,
    set: (newText): string =&amp;gt; text.value = newText
})&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;타입을 지정하고 싶으면 다음과 같이 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;typescript&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;const computedText = computed&amp;lt;string&amp;gt;({
    get: (): string =&amp;gt; text.value,
    set: (newText): number =&amp;gt; text.value = newText
})

// 여러 타입 정의 시 ComputedRef 사용한다.
const style: ComputedRef&amp;lt;IBgStyle | undefined&amp;gt; = computed(() =&amp;gt; {
  if (props.backgroundColor) {
    return {
      backgroundColor: props.backgroundColor,
    }
  }
})&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;타입 지정할 때 볼 수 있듯이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;computed&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;setup&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;안에서 사용할 땐&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;ref&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;처럼&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;.value&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 붙여줘야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;css&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;console.log(computedText.value)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Function&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모두가 아는 그것. 설명을 생략하겠다.&lt;/li&gt;
&lt;li&gt;아! &lt;span data-emoji-text=&quot; &quot; data-emoji-id=&quot;1f62e&quot; data-emoji-short-name=&quot;:open_mouth:&quot;&gt; &lt;/span&gt; &lt;span&gt;ref&lt;/span&gt;, &lt;span&gt;reactive&lt;/span&gt;, &lt;span&gt;computed&lt;/span&gt;, &lt;span&gt;function&lt;/span&gt; 등 모두 template 에서 사용하려면 &lt;span&gt;return&lt;/span&gt; 을 해줘야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;javascript&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;setup() {
  const count = ref(0)

  const handleClickInclude = () =&amp;gt; count.value++
  const handleClickExclude = () =&amp;gt; count.value--

  return {
    count,
    handleClickInclude,
    handleClickExclude
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 코드는 간단하지만 코드가 길어지면 Composition API 사용하는데 의미가 없다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://backpackr.atlassian.net/wiki/spaces/~899424980/pages/1055424580/Composition+API#Composition-API-%ED%83%84%EC%83%9D-%EB%B0%B0%EA%B2%BD&quot;&gt;&lt;span data-mark-type=&quot;annotation&quot; data-mark-annotation-type=&quot;inlineComment&quot; data-id=&quot;3481452d-d3bb-482b-80c6-a5bac82c8f03&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Watch&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한개의 소스만 Watch 할 경우, &lt;span&gt;ref&lt;/span&gt; 일 경우와 아닐 경우 사용 방법이 다르다. &lt;a href=&quot;https://v3.ko.vuejs.org/api/computed-watch-api.html#watch&quot;&gt;#&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;pf&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;// ref watch 할 경우
const count = ref(0)
watch(count, (count, prevCount) =&amp;gt; {
  ...
})

// reactive, props (getter) 등을 watch 할 경우
const state = reactive({ count: 0 })
watch(
  () =&amp;gt; state.count,
  (count, prevCount) =&amp;gt; {
  ...
  }
)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 소스를 Watch 할 경우는 다음과 같이 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;reasonml&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) =&amp;gt; {
  ...
})&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Props&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자식 Component 에서 Props 을 선언할 땐 다음과 같이 &lt;span&gt;defineComponent&lt;/span&gt; 안에 &lt;span&gt;setup&lt;/span&gt; 보다 위에 선언한다.&lt;/li&gt;
&lt;li&gt;기존과 다른점이라면 Array 나 Object 에 &lt;span&gt;as PropType&amp;lt;YourInterface&amp;gt;&lt;/span&gt; 를 사용해 타입을 지정할 수 있다는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;yaml&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;export default defineComponent({
  name: 'ProductList',
  props: {
    products: {
      type: Array as PropType&amp;lt;IProduct[]&amp;gt;, // Array 에 타입 정의
      required: true
    },
    order: {
      type: String,
      required: true
    }
  },
  setup() {
    ...
  }
})&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;setup&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;은 2가지의 인자를 전달하는데&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;props&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이다. 따라서 자식 Component 에서 Props 로 받은 데이터를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;setup&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;안에서 사용하고 싶다면 다음과 같이 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;routeros&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;export default defineComponent({
  name: 'ProductList',
  ...
  setup(props) {
    return {
      ...useOrderedProduct(props),
      ...useOrderClasses(props)
    }
  }
})&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Props 의 타입은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;defineComponent&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;가 알아서 찾아주니 선언할 필요는 없다고 한다&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://vuejs.org/guide/typescript/composition-api.html#typing-component-props&quot;&gt;#&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Emit&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;setup 전달인자 중 context 안에 있는 emit 을 활용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;coffeescript&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;setup(props: ICommonButtonProps, { emit }: SetupContext) {
  ...

  const handleClickButton = () =&amp;gt; {
    emit('click')
  }

  return {
    classes,
    style,
    handleClickButton
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Lifecycle Hooks&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전 스터디때 설명 드렸던 바와 같이 &lt;span&gt;beaforCreate&lt;/span&gt;, &lt;span&gt;created&lt;/span&gt; hook을 &lt;span&gt;setup&lt;/span&gt; 훅으로 대체하여 사용되고, 그 외 기존과 다르게 다음과 같이 Lifecycle이 달라지고 사용할 땐 앞에 &lt;span&gt;on&lt;/span&gt;을 붙여서 사용 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;coffeescript&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;setup() {
  onMounted(() =&amp;gt; {
    console.log('mounted!')
  })
  onUpdated(() =&amp;gt; {
    console.log('updated!')
  })
  onUnmounted(() =&amp;gt; {
    console.log('unmounted!')
  })
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Template reference&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Composition API를 사용하면, reactive refs API와 template 의 refs의 개념이 통합됩니다. &lt;span&gt;template&lt;/span&gt; 내 &lt;span&gt;ref&lt;/span&gt; 를 사용하고 싶다면 기존과 같이 &lt;span&gt;ref&lt;/span&gt;를 선언하고 &lt;span&gt;setup&lt;/span&gt;에서 반환하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;xml&quot; data-pm-slice=&quot;1 1 [&amp;quot;bulletList&amp;quot;,null,&amp;quot;listItem&amp;quot;,null]&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div class=&quot;ProductList&quot; ref=&quot;root&quot;&amp;gt;
    ...
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
  import {defineComponent, onMounted, ref} from &quot;@nuxtjs/composition-api&quot;;

  export default {
    setup() {
      const root = ref(null)

    onMounted(() =&amp;gt; {
      console.log(root.value) // &amp;lt;div class=&quot;ProductList&quot;&amp;gt;...
    })

    return {
      root
    }
  }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Helloworld!/Vue</category>
      <category>composition api</category>
      <category>computed</category>
      <category>emit</category>
      <category>function</category>
      <category>Life Cycle</category>
      <category>prop</category>
      <category>reactive</category>
      <category>Ref</category>
      <category>vue</category>
      <category>Watch</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/536</guid>
      <comments>https://88240.tistory.com/536#entry536comment</comments>
      <pubDate>Wed, 17 Jan 2024 14:04:21 +0900</pubDate>
    </item>
    <item>
      <title>[GIT] 방금한 commit 취소 (하고 다시 stage 로 복구)</title>
      <link>https://88240.tistory.com/535</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 작성했던 git 에서 commit 취소 하는 방법은 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://88240.tistory.com/523&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://88240.tistory.com/523&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reset 명령어를 통해 commit 한 내용을 모두 지우는 것인데, &lt;br /&gt;commit 을 하지 않아야할 상황에 잘못 commit 해서 commit 실행취소처럼 다시 stage 에 복구시키는 명령어에 대해 메모한다. &lt;br /&gt;명령어는 다음과 같다. &lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;git reset HEAD^&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Helloworld!/GIT</category>
      <category>COMMIT</category>
      <category>Git</category>
      <category>reset</category>
      <category>Rollback</category>
      <category>STAGE</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/535</guid>
      <comments>https://88240.tistory.com/535#entry535comment</comments>
      <pubDate>Wed, 17 Jan 2024 12:11:31 +0900</pubDate>
    </item>
    <item>
      <title>[GIT] git 에서 pull 받으려 할 때 다음과 같이 error 날 경우</title>
      <link>https://88240.tistory.com/534</link>
      <description>&lt;pre class=&quot;http&quot; data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;hint: You have divergent branches and need to specify how to reconcile them. 
hint: You can do so by running one of the following commands sometime before

hint: git config pull.rebase false # merge 
hint: git config pull.rebase true # rebase 
hint: hint: You can replace &quot;git config&quot; with &quot;git config --global&quot; to set a default hint: preference for all repositories. You can also pass --rebase, --no-rebase, 
hint: or --ff-only on the command line to override the configured default per hint: invocation. Need to specify how to reconcile divergent branches.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 에러가 날 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;code&gt;git pull --ff-only&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;code&gt;git config --global pull.ff only&lt;/code&gt; &lt;br /&gt;&lt;br /&gt;위의 두 명령어 실행하면 해결 된다.&lt;/p&gt;</description>
      <category>Helloworld!/GIT</category>
      <category>error</category>
      <category>Git</category>
      <category>Pull</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/534</guid>
      <comments>https://88240.tistory.com/534#entry534comment</comments>
      <pubDate>Wed, 17 Jan 2024 12:05:38 +0900</pubDate>
    </item>
    <item>
      <title>intellij 에서 treeview 안보일 때</title>
      <link>https://88240.tistory.com/533</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://apeltop.blogspot.com/2018/06/intellij.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://apeltop.blogspot.com/2018/06/intellij.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>IDE</category>
      <category>IntelliJ</category>
      <category>jetbrain</category>
      <category>TreeView</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/533</guid>
      <comments>https://88240.tistory.com/533#entry533comment</comments>
      <pubDate>Tue, 16 May 2023 17:31:56 +0900</pubDate>
    </item>
    <item>
      <title>[Vue] Composition API</title>
      <link>https://88240.tistory.com/532</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Vue3 에서 달라진 점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://v3.ko.vuejs.org/guide/migration/introduction.html#&quot;&gt;https://v3.ko.vuejs.org/guide/migration/introduction.html#&lt;/a&gt;&lt;a href=&quot;https://v3.ko.vuejs.org/guide/migration/introduction.html#%E1%84%8C%E1%85%AE%E1%84%86%E1%85%A9%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF-%E1%84%86%E1%85%A1%E1%86%AB%E1%84%92%E1%85%A1%E1%86%AB-%E1%84%89%E1%85%A2%E1%84%85%E1%85%A9%E1%84%8B%E1%85%AE%E1%86%AB-%E1%84%80%E1%85%B5%E1%84%82%E1%85%B3%E1%86%BC%E1%84%83%E1%85%B3%E1%86%AF&quot;&gt;주목할-만한-새로운-기능들&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647842262213&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;시작하기 | Vue.js&quot; data-og-description=&quot;시작하기 INFO Vue.js의 새로운 기능에 대한 정보가 필요하신가요? 그렇다면 필수가이드를 확인하세요. 이번 가이드는 Vue 2 경험이 있으면서, Vue 3 변경사항 및 새로운 기능을 배우고 싶은 사용자를&quot; data-og-host=&quot;v3.ko.vuejs.org&quot; data-og-source-url=&quot;https://v3.ko.vuejs.org/guide/migration/introduction.html#%E1%84%8C%E1%85%AE%E1%84%86%E1%85%A9%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF-%E1%84%86%E1%85%A1%E1%86%AB%E1%84%92%E1%85%A1%E1%86%AB-%E1%84%89%E1%85%A2%E1%84%85%E1%85%A9%E1%84%8B%E1%85%AE%E1%86%AB-%E1%84%80%E1%85%B5%E1%84%82%E1%85%B3%E1%86%BC%E1%84%83%E1%85%B3%E1%86%AF&quot; data-og-url=&quot;https://v3.ko.vuejs.org/guide/migration/introduction.html#%E1%84%8C%E1%85%AE%E1%84%86%E1%85%A9%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF-%E1%84%86%E1%85%A1%E1%86%AB%E1%84%92%E1%85%A1%E1%86%AB-%E1%84%89%E1%85%A2%E1%84%85%E1%85%A9%E1%84%8B%E1%85%AE%E1%86%AB-%E1%84%80%E1%85%B5%E1%84%82%E1%85%B3%E1%86%BC%E1%84%83%E1%85%B3%E1%86%AF&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://v3.ko.vuejs.org/guide/migration/introduction.html#%E1%84%8C%E1%85%AE%E1%84%86%E1%85%A9%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF-%E1%84%86%E1%85%A1%E1%86%AB%E1%84%92%E1%85%A1%E1%86%AB-%E1%84%89%E1%85%A2%E1%84%85%E1%85%A9%E1%84%8B%E1%85%AE%E1%86%AB-%E1%84%80%E1%85%B5%E1%84%82%E1%85%B3%E1%86%BC%E1%84%83%E1%85%B3%E1%86%AF&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://v3.ko.vuejs.org/guide/migration/introduction.html#%E1%84%8C%E1%85%AE%E1%84%86%E1%85%A9%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AF-%E1%84%86%E1%85%A1%E1%86%AB%E1%84%92%E1%85%A1%E1%86%AB-%E1%84%89%E1%85%A2%E1%84%85%E1%85%A9%E1%84%8B%E1%85%AE%E1%86%AB-%E1%84%80%E1%85%B5%E1%84%82%E1%85%B3%E1%86%BC%E1%84%83%E1%85%B3%E1%86%AF&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;시작하기 | Vue.js&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;시작하기 INFO Vue.js의 새로운 기능에 대한 정보가 필요하신가요? 그렇다면 필수가이드를 확인하세요. 이번 가이드는 Vue 2 경험이 있으면서, Vue 3 변경사항 및 새로운 기능을 배우고 싶은 사용자를&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;v3.ko.vuejs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://composition-api.nuxtjs.org/&quot;&gt;https://composition-api.nuxtjs.org/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647842272399&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Nuxt Composition API&quot; data-og-description=&quot;Vue 3 Composition API in Nuxt&quot; data-og-host=&quot;composition-api.nuxtjs.org&quot; data-og-source-url=&quot;https://composition-api.nuxtjs.org/&quot; data-og-url=&quot;https://composition-api.nuxtjs.org/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://composition-api.nuxtjs.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://composition-api.nuxtjs.org/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Nuxt Composition API&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Vue 3 Composition API in Nuxt&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;composition-api.nuxtjs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Composition API 탄생 배경&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3c999926-5015-49fb-8801-e9685b4b5116.png&quot; data-origin-width=&quot;1424&quot; data-origin-height=&quot;1634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tNhwe/btrwws6IWna/9XLD0w0MlbHfBDWRzVpIM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tNhwe/btrwws6IWna/9XLD0w0MlbHfBDWRzVpIM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tNhwe/btrwws6IWna/9XLD0w0MlbHfBDWRzVpIM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtNhwe%2Fbtrwws6IWna%2F9XLD0w0MlbHfBDWRzVpIM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1424&quot; height=&quot;1634&quot; data-filename=&quot;3c999926-5015-49fb-8801-e9685b4b5116.png&quot; data-origin-width=&quot;1424&quot; data-origin-height=&quot;1634&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Options API&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;data&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, &lt;code&gt;computed&lt;/code&gt; 에 각각 로직이 분산되어 추적이 어렵다.&lt;/li&gt;
&lt;li&gt;하나의 데이터가 어떻게 변화하고 사용되는지 그룹핑하기 어렵다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;mixin&lt;/code&gt; 을 사용하면 되지만 다중 &lt;code&gt;mixin&lt;/code&gt; 을 상속하게 되면 오버라이딩 문제나 component 관리가 어려워진다.&lt;/li&gt;
&lt;li&gt;즉, 유지보수가 어렵다 어려워 :(&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Composition API 의 &lt;code&gt;setup&lt;/code&gt; 함수에 데이터가 그룹핑 되어 보다 용이하게 데이터의 흐름을 파악하고 로직의 재사용성과 가독성을 높여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Composition API 예시&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Count: {{ count }}&amp;lt;/h1&amp;gt;
        &amp;lt;h1&amp;gt;Double: {{ double }}&amp;lt;/h1&amp;gt;
        &amp;lt;button @click=&quot;increase&quot;&amp;gt;increase&amp;lt;/button&amp;gt;
        &amp;lt;button @click=&quot;decrease&quot;&amp;gt;decrease&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    data () {
        return {
            count: 0,
        }
    },
    computed: {
        double () {
            return this.count * 2;
        }
    },
    methods: {
        increase () {
            ++this.count;
        },
        decrease () {
            --this.count;
        }
    }
}
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱히 별 기능 없이 간단한 카운트 기능을 하는 Component 에 비슷한 기능을 가진 로직들이 &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, &lt;code&gt;computed&lt;/code&gt; 로 각각 분리되어 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Component API 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Count: {{ count }}&amp;lt;/h1&amp;gt;
        &amp;lt;h1&amp;gt;Double: {{ double }}&amp;lt;/h1&amp;gt;
        &amp;lt;button @click=&quot;increase&quot;&amp;gt;increase&amp;lt;/button&amp;gt;
        &amp;lt;button @click=&quot;decrease&quot;&amp;gt;decrease&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
import { reactive, computed } from '@vue/composition-api';

const useCount = () =&amp;gt; {
    const count = ref(0);
    const double = computed(() =&amp;gt; count.value * 2);

    const increase = () =&amp;gt; ++count.value;
    const decrease = () =&amp;gt; --count.value;

    return { count, double, increase, decrease }
}

export default {
    setup () {
        const { count, double, increase, decrease } = useCount();

        return {
            count,
            double,
            increase,
            decrease
        }
    }
}
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관련된 것들을 한 부분에서 해결하고 있기 때문에 추후 Component 를 나눌 때도 편해지고 가독성도 좋아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Setup&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로 추가된 라이프 사이클 훅으로써 Composition API 를 사용하기 위한 초기화 지점이다.&lt;/li&gt;
&lt;li&gt;기존의 &lt;code&gt;beforCreate&lt;/code&gt; 훅 이전에 &lt;code&gt;setup&lt;/code&gt;이 호출되며, Composition API 를 사용하는 경우 &lt;code&gt;beaforCreate&lt;/code&gt;, &lt;code&gt;created&lt;/code&gt; hook을 &lt;code&gt;setup&lt;/code&gt; 훅으로 대체하여 사용된다.&lt;/li&gt;
&lt;li&gt;따라서 다음과 같이 기존 라이프 사이클에도 변화가 생긴다. (기존의 라이프 사이클을 사용할 땐 앞에 &lt;code&gt;on&lt;/code&gt;을 붙여서 사용해야 된다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;4e7e2e0f-639d-4471-9318-1ea284df5ce4.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;1026&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GGH1a/btrwzc3BZoo/I3HwVtunSWO1RXzPax4AKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GGH1a/btrwzc3BZoo/I3HwVtunSWO1RXzPax4AKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GGH1a/btrwzc3BZoo/I3HwVtunSWO1RXzPax4AKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGGH1a%2Fbtrwzc3BZoo%2FI3HwVtunSWO1RXzPax4AKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;1026&quot; data-filename=&quot;4e7e2e0f-639d-4471-9318-1ea284df5ce4.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;1026&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;import { onMounted, onUpdated, onUnmounted } from  '@vue/composition-api'

const MyComponent = {
  setup() {
    onMounted(() =&amp;gt; {
      console.log('mounted!')
    })
    onUpdated(() =&amp;gt; {
      console.log('updated!')
    })
    onUnmounted(() =&amp;gt; {
      console.log('unmounted!')
    })
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Data 선언&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;ref&lt;/code&gt; : 원시값(ex. 1, 'abc', false), 객체 선언 시 사용하며 모두 반응형을 가진다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reactive&lt;/code&gt; : 원시값에 대해서는 반응형을 가지지 않고 객체나 배열에서만 깊은 감지를 수행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;{{ count }} {{ object.foo }}&amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
import { ref, reactive } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const object = reactive({ foo: 'bar' });
    console.log(count.value); // 0

    return {
      count,
      object
    }
  }
}
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제에서 보다 시피 &lt;code&gt;ref&lt;/code&gt; 로 선언한 값은 반드시 &lt;code&gt;.value&lt;/code&gt; 를 통해 접근해야 실제 값을 받아올 수 있다. 그러나 template 에서는 접근하려 할 경우는 생략 가능하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;ref&lt;/code&gt; 와 &lt;code&gt;reactive&lt;/code&gt; 둘다 객체 선언이 가능하면 &lt;code&gt;ref&lt;/code&gt; 만 사용하면 되는게 아닐까?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;ref&lt;/code&gt; 는 원본 값을 &lt;code&gt;value&lt;/code&gt; 라는 속성에 담아두고 변경을 감시하는 객체이고, &lt;code&gt;reactive&lt;/code&gt; 는 원본 객체 자체에 변경을 감지하는 옵저버를 추가하여 그대로 반환하기 때문에 각 특성에 따라 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ref&lt;/code&gt; 로만 구성했을 때 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;setup(props, context) {
  const inputText = ref('');
  const isFocused = ref(false);

  const onChange = (): void =&amp;gt; {
    context.emit('on-change', inputText.value);
  }
  const onFocus = (): void =&amp;gt; {
    isFocused.value = true; // value에 할당
  }

  const onBlur = (): void =&amp;gt; {
    isFocused.value = false; // value에 할당
  }

  onBeforeMount(() =&amp;gt; {
    inputText.value = props.value; // value에 할당
  })

  return {
    inputText,
    isFocused,
    onChange,
    onFocus,
    onBlur
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;reactive&lt;/code&gt; 로 구성했을 때 예시 ( + &lt;code&gt;toRefs&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;setup(props, context) {
  const state = reactive({
    inputText: '',
    isFocused: false
  });

  const onChange = (): void =&amp;gt; {
    context.emit('on-change', state.inputText);
  }
  const onFocus = (): void =&amp;gt; {
    state.isFocused = true; // state의 property를 통해 값을 할당한다.
  }

  const onBlur = (): void =&amp;gt; {
    state.isFocused = false; // state의 property에 값을 할당한다.
  }

  onBeforeMount(() =&amp;gt; {
    state.inputText = props.value; // state의 property에 값을 할당한다.
  })

  return {
    ...toRefs(state), // toRefs를 사용하여 ref로 변환한다.
    onChange,
    onFocus,
    onBlur
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 위와 같이 &lt;code&gt;reactive&lt;/code&gt; 로 객체 값을 생성한 뒤 각 속성을 분해해서 &lt;b&gt;재할당 할 경우 반응형으로 동작하지 않기 때문&lt;/b&gt;에 반환 시 &lt;code&gt;toRefs&lt;/code&gt; 를 사용해 문제를 해결할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;ifRef&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;...
const printValue = obj =&amp;gt; {
  console.log(isRef(obj) ? obj.vlaue : obj); //ref 이면 .value 붙여서 출력, 아닐 경우 obj만으로 출력
}
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Component 선언&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;computed(fn)&lt;/code&gt; 처럼 감싸서 값 선언을 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;{{ count }} {{ object.foo }}&amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
import { ref, reactive } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const plusOne = computed(() =&amp;gt; count.value + 1);

    console.log(plusOne.value); // 1

    return {
      count,
      object
    }
  }
}
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;get&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt; 또는 추가 설정 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;{{ count }} {{ object.foo }}&amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
import { ref, reactive } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const plusOne = computed({
      get: () =&amp;gt; count.value + 1,
      set: val =&amp;gt; { count.value = val - 1 }
    });

    console.log(plusOne.value); // 1

    return {
      count,
      object
    }
  }
}
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Props&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상위에서 어떤 &lt;code&gt;props&lt;/code&gt; 를 받을 것인지 알려준 후, &lt;code&gt;setup&lt;/code&gt; 에서 &lt;code&gt;props.xxx&lt;/code&gt; 로 접근한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;// Parent Component
&amp;lt;template&amp;gt;
  &amp;lt;dlv class=&quot;home&quot;&amp;gt;
    &amp;lt;PostList :posts=&quot;posts&quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
  import PostList from '../components/PostList.vue'
  import { ref } from 'vue';

  export default {
    name: 'Home',
    components: { PostList },

    setup() {
      const posts = ref([
        { title: '1번 타이틀', body: '1번 제목', id: 1 },
        { title: '2번 타이틀', body: '2번 제목', id: 2 },
      ]);

      return { posts }
    }
  }
&amp;lt;/script&amp;gt;

// Child Component
&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    {{ post.title }}
    {{ post.body }}
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
export default {
  props: [&quot;posts&quot;], // 사용할 props를 배열내에 정의합니다.
  setup(props) {
    console.log(props.posts); // 받은 prop 사용가능
  }
};
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이로써 죄다 &lt;code&gt;this&lt;/code&gt; 에 때려박는 바인딩에서 탈피할 수 있다 (&lt;code&gt;props&lt;/code&gt; 는 props! &lt;code&gt;this&lt;/code&gt; 는 this!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;그 외&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TemplateRef
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내에서
&lt;div&gt;와 같이 TemplateRef를 사용할 때는 항상 ref로 정의한 state를 사용해야 한다. reactive로 정의한 state는 정상적으로 참조되지 않는다.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Composition API 에서 fetch 관련 라이프 사이클이 없다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;따라서 middleware 로 사용할 것을 &lt;a href=&quot;https://github.com/nuxt/nuxt.js/issues/6517#issuecomment-564035362&quot;&gt;권장&lt;/a&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;hellip;etc
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://v3.vuejs.org/guide/composition-api-introduction.html#standalone-computed-properties&quot;&gt;https://v3.vuejs.org/guide/composition-api-introduction.html#standalone-computed-properties&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.danvega.dev/blog/2020/02/12/vue3-ref-vs-reactive/&quot;&gt;https://www.danvega.dev/blog/2020/02/12/vue3-ref-vs-reactive/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vuemastery.com/pdf/Vue-3-Cheat-Sheet.pdf&quot;&gt;https://www.vuemastery.com/pdf/Vue-3-Cheat-Sheet.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Helloworld!/Vue</category>
      <category>composition api</category>
      <category>Options API</category>
      <category>reactive</category>
      <category>Ref</category>
      <category>vue</category>
      <category>vue3</category>
      <author>shaking</author>
      <guid isPermaLink="true">https://88240.tistory.com/532</guid>
      <comments>https://88240.tistory.com/532#entry532comment</comments>
      <pubDate>Mon, 21 Mar 2022 14:57:06 +0900</pubDate>
    </item>
  </channel>
</rss>