<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Sweat100</title>
    <link>https://freewebsite1028.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 16 Apr 2026 13:49:36 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Sweat100</managingEditor>
    <image>
      <title>Sweat100</title>
      <url>https://tistory1.daumcdn.net/tistory/4547145/attach/745edb2adf894f3ab40ef27665abf41d</url>
      <link>https://freewebsite1028.tistory.com</link>
    </image>
    <item>
      <title>[1028 책] 너의내면을 검색하라 by  차드 멩탄</title>
      <link>https://freewebsite1028.tistory.com/entry/1028-%EC%B1%85-%EB%84%88%EC%9D%98%EB%82%B4%EB%A9%B4%EC%9D%84-%EA%B2%80%EC%83%89%ED%95%98%EB%9D%BC-by-%EC%B0%A8%EB%93%9C-%EB%A9%A9%ED%83%84</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1단계 주의력 훈련&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2단계 자기이해와 자기통제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3단계 유용한 정신습관 창조&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;gt; 행복훈련 :&amp;nbsp; 현상을 바라보는 깊은 통찰에서 시작.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;gt; 행복 설정값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;gt;&amp;nbsp; 반응의 유연성 &amp;gt;&amp;gt;&amp;nbsp; 감정에 이름을 붙이자 &quot;나는 분노를 느껴&quot;&amp;nbsp; &amp;gt;&amp;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;2분 마음챙김 &amp;gt;&amp;gt;&amp;nbsp; 행위에서 &quot;존재&quot;로 전환, 그냥 존재하는 것은 인생에서 가장 평범하면서도 동시에 가장 귀중한 경험 . 살아있음, 존재함을 느낀다.&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;주의력 , 메타주의력(주의력이 벗어났음을인지)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명상 &amp;gt;&amp;gt; 고요함, 청명함, 행복&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행복은 마음의 초기 상태다. &quot;행복은 허용하는것&quot;&amp;nbsp; 행복은 이미 존재한다. &amp;gt;&amp;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 사실을 인정한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 판단하거나 반응하지 않고 경험한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 반응해야 한다면 마음챙김을 유지한다. - 감각, 의도, 움직임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 그냥 내버려둔다.&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;마음 챙김 듣기 = 경청 , 상대 몰입&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;우리가 타인에게 줄 수 있는 가장 귀중한 선물은 우리의 존재다.&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;마음챙김 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;gt;듣기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;gt;루핑 = 청자가 화자의 말을 완전 히 이해할 수 있도록 서로 돕는 협력프로젝트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;gt;디핑 -&amp;nbsp; 상대 말에 집중을 방해하는 내적 요소들을 그냥 주목하고 인정해야한다.&amp;nbsp; 듣기에 어떤 영향을 주는지만 의식하라.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026-01-15&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;듣기를 명상으로 사용할 수 있음을 몰랐다. 필요하다. 디핑이 필요한 상황도 많이 경험하는거같은데.&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>BOOK</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/303</guid>
      <comments>https://freewebsite1028.tistory.com/entry/1028-%EC%B1%85-%EB%84%88%EC%9D%98%EB%82%B4%EB%A9%B4%EC%9D%84-%EA%B2%80%EC%83%89%ED%95%98%EB%9D%BC-by-%EC%B0%A8%EB%93%9C-%EB%A9%A9%ED%83%84#entry303comment</comments>
      <pubDate>Fri, 16 Jan 2026 00:14:21 +0900</pubDate>
    </item>
    <item>
      <title>cpu, gpu 차이</title>
      <link>https://freewebsite1028.tistory.com/entry/cpu-vs-gpu</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;CPU :&amp;nbsp; 헤비한 연산 , 코어수 적고 병렬처리 최적화 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU : 자잘한 작업을 병렬로 잘한다.&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;딥러닝 모델들은 자잘한 작업을 엄청 많이 해야함 GPU 작업에 훨씬 어울림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔비디아가 Cuda드라이버 생태계를 잘 조성해놔서 최적화가 잘되있음&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-start=&quot;86&quot; data-end=&quot;333&quot;&gt;
&lt;tbody data-start=&quot;126&quot; data-end=&quot;333&quot;&gt;
&lt;tr data-start=&quot;126&quot; data-end=&quot;208&quot;&gt;
&lt;td data-start=&quot;126&quot; data-end=&quot;131&quot; data-col-size=&quot;sm&quot;&gt;이름&lt;/td&gt;
&lt;td data-start=&quot;131&quot; data-end=&quot;168&quot; data-col-size=&quot;sm&quot;&gt;중앙 처리 장치 (Central Processing Unit)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-start=&quot;168&quot; data-end=&quot;208&quot;&gt;그래픽 처리 장치 (Graphics Processing Unit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;209&quot; data-end=&quot;259&quot;&gt;
&lt;td data-start=&quot;209&quot; data-end=&quot;216&quot; data-col-size=&quot;sm&quot;&gt;주 역할&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-start=&quot;216&quot; data-end=&quot;237&quot;&gt;범용 컴퓨팅 (논리, 조건문 등)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-start=&quot;237&quot; data-end=&quot;259&quot;&gt;대규모 병렬 계산 (행렬 곱 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;260&quot; data-end=&quot;304&quot;&gt;
&lt;td data-start=&quot;260&quot; data-end=&quot;267&quot; data-col-size=&quot;sm&quot;&gt;코어 수&lt;/td&gt;
&lt;td data-start=&quot;267&quot; data-end=&quot;284&quot; data-col-size=&quot;sm&quot;&gt;적고 강력함 (4~16개)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-start=&quot;284&quot; data-end=&quot;304&quot;&gt;많고 가벼움 (수백~수천 개)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;305&quot; data-end=&quot;333&quot;&gt;
&lt;td data-start=&quot;305&quot; data-end=&quot;310&quot; data-col-size=&quot;sm&quot;&gt;구조&lt;/td&gt;
&lt;td data-start=&quot;310&quot; data-end=&quot;321&quot; data-col-size=&quot;sm&quot;&gt;직렬 처리 중심&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-start=&quot;321&quot; data-end=&quot;333&quot;&gt;병렬 처리 중심&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기타</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/292</guid>
      <comments>https://freewebsite1028.tistory.com/entry/cpu-vs-gpu#entry292comment</comments>
      <pubDate>Sat, 9 Aug 2025 09:34:36 +0900</pubDate>
    </item>
    <item>
      <title>Vue.js - API  호출 정리 - Promise</title>
      <link>https://freewebsite1028.tistory.com/entry/Vuejs-api</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 729px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 65px;&quot;&gt;
&lt;td style=&quot;width: 11.3953%; height: 65px;&quot; rowspan=&quot;12&quot;&gt;API&amp;nbsp; 호출&lt;/td&gt;
&lt;td style=&quot;width: 12.907%; height: 65px;&quot;&gt;호출 시점&lt;/td&gt;
&lt;td style=&quot;width: 75.6977%; height: 65px;&quot; colspan=&quot;2&quot;&gt;&lt;span&gt;&amp;nbsp; - 페이지 로딩시 onMounted :&amp;nbsp;DOM 이 준비된 뒤 실행&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;nbsp; - 값이 바뀔때 watch() : 반응형 데이터 변경시&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;nbsp; - @click = &quot;함수&quot; : 사용자 UI 상호작용(인터렉션) 발생시&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 87px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 208px;&quot; rowspan=&quot;2&quot;&gt;호출방법&lt;/td&gt;
&lt;td style=&quot;width: 14.6511%; height: 87px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;fetch&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 87px;&quot;&gt;&lt;span&gt; Promise 기반&lt;br /&gt;1. 기본적용&lt;/span&gt;&lt;br /&gt;&lt;span&gt;2. header 설정 필요, body 를 분명히 명시해야 하고, JSON.stringify() 수동파싱&lt;/span&gt;&lt;br /&gt;&lt;span&gt;3. 응답을 res.json() 직접호출&lt;/span&gt;&lt;br /&gt;&lt;span&gt;4. 구버전 브라우저 안됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 121px;&quot;&gt;
&lt;td style=&quot;width: 14.6511%; height: 121px;&quot;&gt;axios&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 121px;&quot;&gt;&lt;span&gt; Promise 기반&lt;br /&gt;1. npm install axios&lt;/span&gt;&lt;br /&gt;&lt;span&gt;2. header application/json 자동설정,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;객체 전달시 자동 JSON처리-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;JSON.stringify()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;3. res.data 로 받음&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;기타. timeout 지연, 인터셉터 지연, 폴리필지원으로 IE11 까지 지원(내부 XHR 사용)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 439px;&quot; rowspan=&quot;9&quot;&gt;비동기 처리 흐름 정&lt;/td&gt;
&lt;td style=&quot;width: 14.6511%; height: 43px;&quot;&gt;1995~2014:&amp;nbsp;&lt;br /&gt;콜백(callback)&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 43px;&quot;&gt;-&amp;nbsp;초창기&amp;nbsp;JavaScript는&amp;nbsp;비동기&amp;nbsp;작업을&amp;nbsp;콜백&amp;nbsp;함수로&amp;nbsp;처리. &lt;br /&gt;-&amp;nbsp;중첩&amp;nbsp;호출이&amp;nbsp;많아지면&amp;nbsp;&quot;콜백&amp;nbsp;지옥(callback&amp;nbsp;hell)&quot;&amp;nbsp;발생.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 14.6511%; height: 43px;&quot;&gt;2005:&amp;nbsp;&lt;br /&gt;AJAX&amp;nbsp;등장&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 43px;&quot;&gt;-&amp;nbsp;XMLHTTPRequest(XHR)를&amp;nbsp;기반으로&amp;nbsp;서버와&amp;nbsp;비동기&amp;nbsp;통신&amp;nbsp;가능해짐. &lt;br /&gt;-&amp;nbsp;Gmail,&amp;nbsp;Google&amp;nbsp;Maps&amp;nbsp;등에서&amp;nbsp;사용되며&amp;nbsp;대중화.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 14.6511%; height: 194px;&quot; rowspan=&quot;2&quot;&gt;2015&amp;nbsp;(ES6):&amp;nbsp;&lt;br /&gt;Promise&amp;nbsp;도입&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 43px;&quot;&gt;- 비동기&amp;nbsp;처리&amp;nbsp;후,&amp;nbsp;결과를&amp;nbsp;나중에&amp;nbsp;알려주는&amp;nbsp;객체&lt;br /&gt;-&amp;nbsp;콜백&amp;nbsp;대신&amp;nbsp;`.then()`&amp;nbsp;체이닝으로&amp;nbsp;가독성과&amp;nbsp;에러&amp;nbsp;처리&amp;nbsp;개선.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 151px;&quot;&gt;
&lt;td style=&quot;width: 61.0466%; height: 151px;&quot;&gt;promise&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;//&lt;span&gt; then, catch 전에는 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;pending&lt;span&gt;&amp;nbsp;상태&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(result&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&quot;Then:&quot;,&amp;nbsp;result);&amp;nbsp;&amp;nbsp;// fulfilled&amp;nbsp; 성공하면 이 블록 실행 &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.catch(error&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error(&quot;Catch:&quot;,&amp;nbsp;error);&amp;nbsp;&amp;nbsp;// rejected&amp;nbsp;실패하면&amp;nbsp;이&amp;nbsp;블록&amp;nbsp;실행 &lt;br /&gt;&amp;nbsp;&amp;nbsp;}); &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 14.6511%; height: 99px;&quot; rowspan=&quot;2&quot;&gt;2015&amp;nbsp;(ES6):&amp;nbsp;&lt;br /&gt;fetch&amp;nbsp;API&amp;nbsp;등장&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 43px;&quot;&gt;-&amp;nbsp;XHR을&amp;nbsp;대체할&amp;nbsp;새로운&amp;nbsp;API로,&amp;nbsp;Promise를&amp;nbsp;기반으로&amp;nbsp;동작. &lt;br /&gt;-&amp;nbsp;네트워크&amp;nbsp;요청을&amp;nbsp;더&amp;nbsp;간단하게&amp;nbsp;작성할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;함.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 56px;&quot;&gt;
&lt;td style=&quot;width: 61.0466%; height: 56px;&quot;&gt;1. fetch 는 Promise로 반환&lt;br /&gt;const&amp;nbsp;promise&amp;nbsp;=&amp;nbsp;fetch('/api/data'); &lt;br /&gt;console.log(promise); //&amp;nbsp; Promise { &amp;lt;pending&amp;gt; }&lt;br /&gt;&lt;br /&gt;2. POST,PUT, PATCH 사용시 반드시 headers, body 직접작성&lt;br /&gt;- Promise 형식 처리&lt;br /&gt;fetch('/api/data',&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;method:&amp;nbsp;'POST', &lt;br /&gt;&amp;nbsp;&amp;nbsp;headers:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'Content-Type':&amp;nbsp;'application/json'&amp;nbsp;//&amp;nbsp;꼭&amp;nbsp;명시! &lt;br /&gt;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;body:&amp;nbsp;JSON.stringify({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'홍길동', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;age:&amp;nbsp;30 &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(res =&amp;gt; res.json())// &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;res.json()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&amp;nbsp; 도 &lt;span&gt;Promise { &amp;lt;pending&amp;gt; }&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(data =&amp;gt; console.log(data));&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 60px;&quot;&gt;
&lt;td style=&quot;width: 14.6511%; height: 60px;&quot;&gt;2017&amp;nbsp;(ES8):&amp;nbsp;&lt;br /&gt;async/await&amp;nbsp;문법&amp;nbsp;도입&lt;br /&gt;&lt;br /&gt;(작성 권장)&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 60px;&quot;&gt;-&amp;nbsp;Promise를&amp;nbsp;더&amp;nbsp;간결하고&amp;nbsp;동기&amp;nbsp;코드처럼&amp;nbsp;작성할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;함. &lt;br /&gt;-&amp;nbsp;내부적으로는&amp;nbsp;Promise를&amp;nbsp;기반으로&amp;nbsp;동작하며,&amp;nbsp;가독성&amp;nbsp;향상.&lt;br /&gt;&lt;br /&gt;- async 는 비동기작업(await)로 기다리다 결과를 res에 저장&amp;nbsp;&lt;br /&gt;async/await&amp;nbsp;버전&lt;br /&gt;async&amp;nbsp;function&amp;nbsp;postData()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;await&amp;nbsp;fetch('/api/data',&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;method:&amp;nbsp;'POST', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;headers:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'Content-Type':&amp;nbsp;'application/json' &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;body:&amp;nbsp;JSON.stringify({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'홍길동', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;age:&amp;nbsp;30 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}); &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const data = await res.json(); &amp;nbsp;// 결과처리&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(error)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error(&quot;에러 발생:&quot;, error); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw error; // 에러도 밖으로 던져줘야 catch에서 처리 가능 &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;postData();&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.6511%; height: 17px;&quot;&gt;2016 :&amp;nbsp;&lt;br /&gt;axios&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%; height: 17px;&quot;&gt;import&amp;nbsp;axios&amp;nbsp;from&amp;nbsp;'axios'; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;async&amp;nbsp;&lt;/b&gt;function&amp;nbsp;postData()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;&lt;b&gt;await&amp;nbsp;&lt;/b&gt;axios.post('/api/data',&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'홍길동', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;age:&amp;nbsp;30 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}); &lt;br /&gt;&amp;nbsp; &amp;nbsp; res.data; // 결과처리&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(error)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error(&quot;에러 발생:&quot;, error); &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;postData();&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.6511%;&quot;&gt;2020 :&amp;nbsp;&lt;br /&gt;Vue 3.x&lt;/td&gt;
&lt;td style=&quot;width: 61.0466%;&quot;&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;ref,&amp;nbsp;onMounted&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue'; &lt;br /&gt;import&amp;nbsp;axios&amp;nbsp;from&amp;nbsp;'axios'; &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;result&amp;nbsp;=&amp;nbsp;ref(null); &lt;br /&gt;&lt;br /&gt;onMounted(&lt;b&gt;async&amp;nbsp;&lt;/b&gt;()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;&lt;b&gt;await&amp;nbsp;&lt;/b&gt;axios.get('/api/data'); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.value&amp;nbsp;=&amp;nbsp;res.data; &lt;br /&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(err)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error(&quot;에러:&quot;,&amp;nbsp;err); &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}); &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.9767%;&quot;&gt;Promise&lt;/td&gt;
&lt;td style=&quot;width: 88.0233%;&quot; colspan=&quot;3&quot;&gt;비동기&amp;nbsp;처리&amp;nbsp;후,&amp;nbsp;결과를&amp;nbsp;나중에&amp;nbsp;알려주는&amp;nbsp;객체&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Promise.resolve(value)&amp;nbsp; // 즉시 성공상태 promise 생성&lt;br /&gt;Promise.reject(error)&amp;nbsp; &amp;nbsp;// 즉시 실패상태 promize 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.9767%;&quot; rowspan=&quot;6&quot;&gt;함수&lt;/td&gt;
&lt;td style=&quot;width: 21.7443%;&quot; rowspan=&quot;2&quot;&gt;Promise.all &lt;/td&gt;
&lt;td style=&quot;width: 28.0232%;&quot; rowspan=&quot;2&quot;&gt;모두성공시 실행&lt;/td&gt;
&lt;td style=&quot;width: 38.2558%;&quot;&gt;const&amp;nbsp;fetchUser&amp;nbsp;=&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;axios.get('/api/user'); &lt;br /&gt;const&amp;nbsp;fetchPost&amp;nbsp;=&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;axios.get('/api/post'); &lt;br /&gt;const&amp;nbsp;fetchComment&amp;nbsp;=&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;axios.get('/api/comment'); &lt;br /&gt;&lt;br /&gt;Promise.all([fetchUser(),&amp;nbsp;fetchPost(),&amp;nbsp;fetchComment()]) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(([user,&amp;nbsp;post,&amp;nbsp;comment])&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&quot; &quot;,&amp;nbsp;user.data); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&quot; &quot;,&amp;nbsp;post.data); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&quot; &quot;,&amp;nbsp;comment.data); &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.catch(err&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error(&quot;❌&amp;nbsp;하나라도&amp;nbsp;실패함:&quot;,&amp;nbsp;err); &lt;br /&gt;&amp;nbsp;&amp;nbsp;});&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 38.2558%;&quot;&gt;const&amp;nbsp;urls&amp;nbsp;=&amp;nbsp;[&amp;nbsp;'/user',&amp;nbsp;'/book',&amp;nbsp;'/log'&amp;nbsp;]; &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;fetchAll&amp;nbsp;=&amp;nbsp;Promise.all( &lt;br /&gt;&amp;nbsp;&amp;nbsp;urls.map(url&amp;nbsp;=&amp;gt;&amp;nbsp;fetch(url).then(res&amp;nbsp;=&amp;gt;&amp;nbsp;res.json())) &lt;br /&gt;);&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.7443%;&quot; rowspan=&quot;2&quot;&gt;Promise.race &lt;/td&gt;
&lt;td style=&quot;width: 28.0232%;&quot; rowspan=&quot;2&quot;&gt;빨리 끝나는 하나사용&lt;br /&gt;실패가 먼저 끝나면 실패처리됨&lt;/td&gt;
&lt;td style=&quot;width: 38.2558%;&quot;&gt;const&amp;nbsp;fetchFromA&amp;nbsp;=&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;axios.get('/api/a'); &lt;br /&gt;const&amp;nbsp;fetchFromB&amp;nbsp;=&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;axios.get('/api/b'); &lt;br /&gt;&lt;br /&gt;Promise.race([fetchFromA(),&amp;nbsp;fetchFromB()]) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(res&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&quot; &amp;nbsp;먼저&amp;nbsp;도착한&amp;nbsp;응답:&quot;,&amp;nbsp;res.data); &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.catch(err&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error(&quot;❌&amp;nbsp;에러:&quot;,&amp;nbsp;err); &lt;br /&gt;&amp;nbsp;&amp;nbsp;}); &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 38.2558%;&quot;&gt;const&amp;nbsp;timeout&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Promise((_,&amp;nbsp;reject)&amp;nbsp;=&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;setTimeout(()&amp;nbsp;=&amp;gt;&amp;nbsp;reject(&quot;⏰&amp;nbsp;서버&amp;nbsp;너무&amp;nbsp;느림&quot;),&amp;nbsp;3000) &lt;br /&gt;); &lt;br /&gt;&lt;br /&gt;//&amp;nbsp;race로&amp;nbsp;둘&amp;nbsp;중&amp;nbsp;먼저&amp;nbsp;끝나는&amp;nbsp;걸&amp;nbsp;본다! &lt;br /&gt;const&amp;nbsp;result&amp;nbsp;=&amp;nbsp;await&amp;nbsp;Promise.race([fetchAll,&amp;nbsp;timeout]);&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.7443%;&quot;&gt;Promise.allSettled()&lt;/td&gt;
&lt;td style=&quot;width: 28.0232%;&quot;&gt;끝날 때까지 기다리고 성공(fulfilled)이든 실패(rejected)든 결과를 전부 알려줌&lt;/td&gt;
&lt;td style=&quot;width: 38.2558%;&quot;&gt;const&amp;nbsp;p1&amp;nbsp;=&amp;nbsp;Promise.resolve(&quot;✅&amp;nbsp;성공1&quot;); &lt;br /&gt;const&amp;nbsp;p2&amp;nbsp;=&amp;nbsp;Promise.reject(&quot;❌&amp;nbsp;실패&quot;); &lt;br /&gt;const&amp;nbsp;p3&amp;nbsp;=&amp;nbsp;Promise.resolve(&quot;✅&amp;nbsp;성공2&quot;); &lt;br /&gt;&lt;br /&gt;Promise.allSettled([p1,&amp;nbsp;p2,&amp;nbsp;p3]) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(results&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(results); &lt;br /&gt;&amp;nbsp;&amp;nbsp;});&lt;br /&gt;&lt;br /&gt;[ &lt;br /&gt;&amp;nbsp;&amp;nbsp;{ status: &quot;fulfilled&quot;, value: &quot;성공1&quot; }, &lt;br /&gt;&amp;nbsp;&amp;nbsp;{ status: &quot;rejected&quot;, reason: &quot;실패&quot; }, &lt;br /&gt;&amp;nbsp;&amp;nbsp;{ status: &quot;fulfilled&quot;, value: &quot;성공2&quot; } &lt;br /&gt;] &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.7443%;&quot;&gt;Promise.any()&lt;/td&gt;
&lt;td style=&quot;width: 28.0232%;&quot;&gt;성공한&amp;nbsp;것&amp;nbsp;중&amp;nbsp;가장&amp;nbsp;먼저&amp;nbsp;도착한&amp;nbsp;결과만&amp;nbsp;반환&lt;/td&gt;
&lt;td style=&quot;width: 38.2558%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.721%;&quot; colspan=&quot;2&quot;&gt;프로마이즈 체이닝&lt;/td&gt;
&lt;td style=&quot;width: 28.0232%;&quot;&gt;&amp;nbsp;앞 단계 결과 등&amp;nbsp; Promize 실행&lt;/td&gt;
&lt;td style=&quot;width: 38.2558%;&quot;&gt;fetch('/api/step1') &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(res&amp;nbsp;=&amp;gt;&amp;nbsp;res.json()) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(data1&amp;nbsp;=&amp;gt;&amp;nbsp;fetch(`/api/step2/${data1.id}`)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(res&amp;nbsp;=&amp;gt;&amp;nbsp;res.json()) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(data2&amp;nbsp;=&amp;gt;&amp;nbsp;console.log(&quot;최종&amp;nbsp;결과:&quot;,&amp;nbsp;data2)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.catch(err&amp;nbsp;=&amp;gt;&amp;nbsp;console.error(&quot;에러:&quot;,&amp;nbsp;err)); &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/289</guid>
      <comments>https://freewebsite1028.tistory.com/entry/Vuejs-api#entry289comment</comments>
      <pubDate>Thu, 7 Aug 2025 13:42:14 +0900</pubDate>
    </item>
    <item>
      <title>[핵심만 골라 배우는 Vue.js by 수코딩] 11. 네트워크 - axios (액시오스), json-server</title>
      <link>https://freewebsite1028.tistory.com/entry/vue-axios</link>
      <description>&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 39px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 39px;&quot;&gt;API&lt;/td&gt;
&lt;td style=&quot;width: 89.5349%; height: 39px;&quot; colspan=&quot;3&quot;&gt;Applicaion Programming Interface&lt;br /&gt;프론트엔드에서는 서버와 통신하기 위한 약속된 일련의 규칙&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 186px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 186px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 186px;&quot;&gt;Fetch API&lt;/td&gt;
&lt;td style=&quot;width: 70.1163%; height: 186px;&quot; colspan=&quot;2&quot;&gt;브라우저 내장, 모든 현대 브라우저&lt;br /&gt;- 단순요청, 의존성 줄이기 , ie11 지원안함&lt;br /&gt;fetch(url, options)&lt;br /&gt;&lt;br /&gt;fetch('http://localhost:3000/posts')&lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(res&amp;nbsp;=&amp;gt;&amp;nbsp;res.json())&lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(data&amp;nbsp;=&amp;gt;&amp;nbsp;console.log(data))&lt;br /&gt;&amp;nbsp;&amp;nbsp;.catch(err&amp;nbsp;=&amp;gt;&amp;nbsp;console.error(err))&lt;br /&gt;&lt;br /&gt;***modern JS 에서는 fetch 또는 axios 사용, ajax 사용안함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 104px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 104px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 104px;&quot;&gt;Axios(엑시오스)&lt;/td&gt;
&lt;td style=&quot;width: 70.1163%; height: 104px;&quot; colspan=&quot;2&quot;&gt;외부 라이브러리, 모든 브라우저 (IE도 Polyfill로 가능), 자동 json 파싱, 인터셉터, 타임아웃&lt;br /&gt;- 에러처리, 인터셉터, 전역설정 복잡한로직, ie11 지원&lt;br /&gt;설치 : npm i axios&lt;br /&gt;axios.request(config)&amp;nbsp;&lt;br /&gt;axios.get(url)&lt;br /&gt;axios.post(url, data) 등&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;Promise를 지원 - .then, .catch, awit 같은 Promise(비동기정처리가능) 문법 사용가능&lt;br /&gt;- async 비동기 함수를 정의할 때 사용. 함수는 항상 Promise를 반환 &lt;br /&gt;- await Promise가 완료될 때까지 기다렸다가 그 결과를 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 91px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 91px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 91px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%; height: 861px;&quot; rowspan=&quot;3&quot;&gt;plugins/api.js&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%; height: 91px;&quot;&gt;&lt;b&gt;import&amp;nbsp;axios&amp;nbsp;from&amp;nbsp;'axios'&lt;br /&gt;&lt;/b&gt;//&amp;nbsp;1.&amp;nbsp;Axios&amp;nbsp;인스턴스&amp;nbsp;생성&lt;br /&gt;const&amp;nbsp;api&amp;nbsp;=&amp;nbsp;axios.create({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;baseURL:&amp;nbsp;'&lt;a href=&quot;https://example.com/api',&quot;&gt;https://example.com/api',&lt;/a&gt;&amp;nbsp;//기본&amp;nbsp;요청&amp;nbsp;URL&lt;br /&gt;&amp;nbsp;&amp;nbsp;timeout:&amp;nbsp;5000,&amp;nbsp;//요청&amp;nbsp;제한&amp;nbsp;시간(ms)&lt;br /&gt;&amp;nbsp;&amp;nbsp;headers:&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'Authorization':&amp;nbsp;'Bearer&amp;nbsp;my-token',&amp;nbsp;//인증&amp;nbsp;토큰&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'Content-Type':&amp;nbsp;'application/json'&amp;nbsp;//요청&amp;nbsp;데이터&amp;nbsp;타입&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;params:&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lang:&amp;nbsp;'ko'&amp;nbsp;//기본&amp;nbsp;쿼리&amp;nbsp;파라미터&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;withCredentials:&amp;nbsp;false,&amp;nbsp;//쿠키&amp;nbsp;포함&amp;nbsp;여부(CORS)&lt;br /&gt;&amp;nbsp;&amp;nbsp;transformRequest:&amp;nbsp;[(data,&amp;nbsp;headers)&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;JSON.stringify(data)&amp;nbsp;//요청&amp;nbsp;전&amp;nbsp;데이터&amp;nbsp;가공&lt;br /&gt;&amp;nbsp;&amp;nbsp;}],&lt;br /&gt;&amp;nbsp;&amp;nbsp;transformResponse:&amp;nbsp;[data&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;JSON.parse(data)&amp;nbsp;//응답&amp;nbsp;후&amp;nbsp;데이터&amp;nbsp;가공&lt;br /&gt;&amp;nbsp;&amp;nbsp;}],&lt;br /&gt;&amp;nbsp;&amp;nbsp;responseType:&amp;nbsp;'json',&amp;nbsp;//응답&amp;nbsp;데이터&amp;nbsp;형식&lt;br /&gt;&amp;nbsp;&amp;nbsp;validateStatus:&amp;nbsp;status&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;status&amp;nbsp;&amp;gt;=&amp;nbsp;200&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;status&amp;nbsp;&amp;lt;&amp;nbsp;300&amp;nbsp;//성공으로&amp;nbsp;간주할&amp;nbsp;상태코드&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;})&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 272px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 272px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 272px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%; height: 272px;&quot;&gt;// 2. 요청 인터셉터&lt;br /&gt;// header 가 applicaion/json 이면 JSON.stringify 자동으로 변환&lt;br /&gt;api.interceptors.request.use(&lt;br /&gt;&amp;nbsp;&amp;nbsp;config&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 공통 토큰 삽입 등 처리&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;token&amp;nbsp;=&amp;nbsp;localStorage.getItem('access_token')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(token)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;config.headers['Authorization']&amp;nbsp;=&amp;nbsp;`Bearer&amp;nbsp;${token}`&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;config&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;error&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error('[요청&amp;nbsp;에러]',&amp;nbsp;error)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Promise.reject(error)&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 498px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 498px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 498px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%; height: 498px;&quot;&gt;//&amp;nbsp;3.&amp;nbsp;응답&amp;nbsp;인터셉터&lt;br /&gt;api.interceptors.response.use(&lt;br /&gt;&amp;nbsp;&amp;nbsp;response&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;response&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;error&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;status&amp;nbsp;=&amp;nbsp;error.response?.status&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 공통 에러 처리&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&amp;nbsp;(status)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;401:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert('로그인이&amp;nbsp;필요합니다')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;router.push('/login')&amp;nbsp;등&amp;nbsp;처리&amp;nbsp;가능&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;403:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert('권한이&amp;nbsp;없습니다')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;500:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert('서버&amp;nbsp;오류가&amp;nbsp;발생했습니다')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(error.message&amp;nbsp;||&amp;nbsp;'알&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;오류')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Promise.reject(error)&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 177px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 177px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 177px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%; height: 177px;&quot;&gt;main.js&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%;&quot;&gt;//&amp;nbsp;main.js&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;createApp&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue'&lt;br /&gt;import&amp;nbsp;App&amp;nbsp;from&amp;nbsp;'./App.vue'&lt;br /&gt;&lt;b&gt;import&amp;nbsp;api&amp;nbsp;from&amp;nbsp;'./plugins/api'&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;const app = createApp(App);&lt;br /&gt;&lt;br /&gt;&lt;b&gt;app.provide('api', api);&lt;span&gt;&amp;nbsp;&lt;/span&gt;// 옵션스 api&lt;/b&gt;&lt;br /&gt;&lt;b&gt;/&lt;span style=&quot;color: #ee2323;&quot;&gt;/app.config.globalProperties.$http =&amp;nbsp;api&amp;nbsp;&lt;/span&gt;;&amp;nbsp; // 컴포넌트 api&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;app.mount('#app');&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.1628%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;inject&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%;&quot;&gt;axios.create()로 만든 인스턴스를 전역으로 주입 재사용.&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%; height: 17px;&quot;&gt;import&amp;nbsp;{&amp;nbsp;inject,&amp;nbsp;onMounted,&amp;nbsp;ref&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue'&lt;br /&gt;&lt;br /&gt;const&amp;nbsp;api&amp;nbsp;=&amp;nbsp;inject('api')&amp;nbsp;//&amp;nbsp;main.js에서&amp;nbsp;provide한&amp;nbsp;api&amp;nbsp;인스턴스&amp;nbsp;받기&lt;br /&gt;&lt;br /&gt;const&amp;nbsp;loadData&amp;nbsp;=&amp;nbsp;async&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&amp;nbsp; const res = await api.get('/posts')&amp;nbsp; //&lt;span&gt;&amp;nbsp;&lt;/span&gt;옵션스&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;api&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; //const res = await $http.get('/posts')&amp;nbsp; // 컴포넌트 api&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;posts.value&amp;nbsp;=&amp;nbsp;res.data&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(err)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.error('데이터&amp;nbsp;로드&amp;nbsp;실패:',&amp;nbsp;err)&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.1628%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;injectStrict&lt;br /&gt;&lt;br /&gt;- 컴포넌트 api 사용안함&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%;&quot;&gt;import&amp;nbsp;{&amp;nbsp;inject&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue'&lt;br /&gt;&lt;br /&gt;export&amp;nbsp;function&amp;nbsp;&lt;b&gt;injectStrict&lt;/b&gt;(key,&amp;nbsp;fallbackMessage&amp;nbsp;=&amp;nbsp;'Injection&amp;nbsp;failed')&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;resolved&amp;nbsp;=&amp;nbsp;inject(key)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(resolved&amp;nbsp;===&amp;nbsp;undefined)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(fallbackMessage&amp;nbsp;+&amp;nbsp;`:&amp;nbsp;&quot;${String(key)}&quot;`)&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;resolved&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.1628%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%;&quot;&gt;&amp;lt;script&amp;nbsp;setup&amp;gt;&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;onMounted,&amp;nbsp;ref&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue'&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;&lt;b&gt;injectStrict&amp;nbsp;&lt;/b&gt;}&amp;nbsp;from&amp;nbsp;'@/utils/injectStrict'&amp;nbsp;//&amp;nbsp;직접&amp;nbsp;만든&amp;nbsp;함수&lt;br /&gt;&lt;br /&gt;const&amp;nbsp;api&amp;nbsp;=&amp;nbsp;injectStrict('api',&amp;nbsp;'Axios&amp;nbsp;인스턴스&amp;nbsp;주입&amp;nbsp;실패')&lt;br /&gt;&lt;br /&gt;const&amp;nbsp;posts&amp;nbsp;=&amp;nbsp;ref([])&lt;br /&gt;&lt;br /&gt;const&amp;nbsp;loadData&amp;nbsp;=&amp;nbsp;async&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;await&amp;nbsp;api.get('/posts')&lt;br /&gt;&amp;nbsp;&amp;nbsp;posts.value&amp;nbsp;=&amp;nbsp;res.data&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;onMounted&lt;/b&gt;(loadData)&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 1972px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 18px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 255px;&quot; rowspan=&quot;4&quot;&gt;json-server 라이브러리&lt;/td&gt;
&lt;td style=&quot;width: 70.1163%; height: 18px;&quot; colspan=&quot;2&quot;&gt;JSON&amp;nbsp; 기반 빠른 Mock API- 실제 서버 없이도 API처럼 동작하는 가짜 서버 -서버 구축 도구&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 78px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 78px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%; height: 78px;&quot;&gt;설치&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%; height: 78px;&quot;&gt;npm install -g json-server&amp;nbsp; &amp;nbsp; &amp;nbsp;전역설치&lt;br /&gt;npm&amp;nbsp;install&amp;nbsp;json-server&amp;nbsp;--save-dev&amp;nbsp; 지역설치&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 103px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 103px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%; height: 103px;&quot;&gt;db.json&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%; height: 103px;&quot;&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;posts&quot;:&amp;nbsp;[ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&quot;id&quot;:&amp;nbsp;1,&amp;nbsp;&quot;title&quot;:&amp;nbsp;&quot;Hello&amp;nbsp;Vue&quot;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&quot;id&quot;:&amp;nbsp;2,&amp;nbsp;&quot;title&quot;:&amp;nbsp;&quot;Using&amp;nbsp;json-server&quot;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;] &lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 56px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 56px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%; height: 56px;&quot;&gt;서버실행&lt;/td&gt;
&lt;td style=&quot;width: 59.3023%; height: 56px;&quot;&gt;json-server&amp;nbsp;--watch&amp;nbsp;db.json&amp;nbsp;--port&amp;nbsp;3000&lt;br /&gt;&lt;br /&gt;접속 : http://localhost:3000/posts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 1632px;&quot;&gt;
&lt;td style=&quot;width: 11.1628%; height: 1632px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; height: 1632px;&quot;&gt;http method&lt;/td&gt;
&lt;td style=&quot;height: 1632px;&quot; colspan=&quot;2&quot;&gt;get : 읽기&lt;br /&gt;post ; 쓰기&lt;br /&gt;put :&amp;nbsp; 전체 데이터 변경&lt;br /&gt;patch : 일부데이터 변경&lt;br /&gt;delete : 삭제&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;ref,&amp;nbsp;onMounted&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;axios&amp;nbsp;from&amp;nbsp;'axios' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;posts&amp;nbsp;=&amp;nbsp;ref([]) &lt;br /&gt;const&amp;nbsp;newTitle&amp;nbsp;=&amp;nbsp;ref('') &lt;br /&gt;const&amp;nbsp;editId&amp;nbsp;=&amp;nbsp;ref(null) &lt;br /&gt;const&amp;nbsp;editTitle&amp;nbsp;=&amp;nbsp;ref('') &lt;br /&gt;&lt;br /&gt;// API: 목록 불러오기 (GET) &lt;br /&gt;async&amp;nbsp;function&amp;nbsp;fetchPosts()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;await&amp;nbsp;&lt;b&gt;axios.get&lt;/b&gt;('http://localhost:3000/posts') &lt;br /&gt;&amp;nbsp;&amp;nbsp;posts.value&amp;nbsp;=&amp;nbsp;res.data &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;// API: 글 추가 (POST) &lt;br /&gt;async&amp;nbsp;function&amp;nbsp;addPost()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!newTitle.value.trim())&amp;nbsp;return &lt;br /&gt;&amp;nbsp;&amp;nbsp;await&amp;nbsp;&lt;b&gt;axios.post&lt;/b&gt;('http://localhost:3000/posts',&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;newTitle.value &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;newTitle.value&amp;nbsp;=&amp;nbsp;'' &lt;br /&gt;&amp;nbsp;&amp;nbsp;fetchPosts() &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;// 수정 모드 진입 &lt;br /&gt;function&amp;nbsp;startEdit(post)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;editId.value&amp;nbsp;=&amp;nbsp;post.id &lt;br /&gt;&amp;nbsp;&amp;nbsp;editTitle.value&amp;nbsp;=&amp;nbsp;post.title &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;// API: 글 수정 (PUT) &lt;br /&gt;async&amp;nbsp;function&amp;nbsp;updatePost()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!editTitle.value.trim())&amp;nbsp;return &lt;br /&gt;&amp;nbsp;&amp;nbsp;await&amp;nbsp;&lt;b&gt;axios.put&lt;/b&gt;(`http://localhost:3000/posts/${editId.value}`,&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;editTitle.value &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;editId.value&amp;nbsp;=&amp;nbsp;null &lt;br /&gt;&amp;nbsp;&amp;nbsp;editTitle.value&amp;nbsp;=&amp;nbsp;'' &lt;br /&gt;&amp;nbsp;&amp;nbsp;fetchPosts() &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;// API: 글 삭제 (DELETE) &lt;br /&gt;async&amp;nbsp;function&amp;nbsp;deletePost(id)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;await&amp;nbsp;&lt;b&gt;axios.delete&lt;/b&gt;(`http://localhost:3000/posts/${id}`) &lt;br /&gt;&amp;nbsp;&amp;nbsp;fetchPosts() &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;// 컴포넌트 초기 로드 시 실행 &lt;br /&gt;onMounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;fetchPosts() &lt;br /&gt;}) &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;style=&quot;padding:&amp;nbsp;2rem&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h1&amp;gt; &amp;nbsp;Vue&amp;nbsp;+&amp;nbsp;json-server&amp;nbsp;CRUD&amp;nbsp;예제&amp;nbsp;(form&amp;nbsp;사용)&amp;lt;/h1&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;✅&amp;nbsp;추가&amp;nbsp;폼&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;form&amp;nbsp;@submit.prevent=&quot;addPost&quot;&amp;nbsp;style=&quot;margin-bottom:&amp;nbsp;1rem&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;nbsp;v-model=&quot;newTitle&quot;&amp;nbsp;placeholder=&quot;새&amp;nbsp;글&amp;nbsp;제목&quot;&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;type=&quot;submit&quot;&amp;gt;등록&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/form&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;✅&amp;nbsp;수정&amp;nbsp;폼&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;form&amp;nbsp;v-if=&quot;editId&amp;nbsp;!==&amp;nbsp;null&quot;&amp;nbsp;@submit.prevent=&quot;updatePost&quot;&amp;nbsp;style=&quot;margin-bottom:&amp;nbsp;1rem&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;nbsp;v-model=&quot;editTitle&quot;&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;type=&quot;submit&quot;&amp;gt;수정&amp;nbsp;완료&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;type=&quot;button&quot;&amp;nbsp;@click=&quot;editId&amp;nbsp;=&amp;nbsp;null&quot;&amp;gt;취소&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/form&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;✅&amp;nbsp;목록&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ul&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;v-for=&quot;post&amp;nbsp;in&amp;nbsp;posts&quot;&amp;nbsp;:key=&quot;post.id&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{{&amp;nbsp;post.title&amp;nbsp;}} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;@click=&quot;startEdit(post)&quot;&amp;gt;수정&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;@click=&quot;deletePost(post.id)&quot;&amp;gt;삭제&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ul&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.1628%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%;&quot;&gt;컴포저블 패턴 사용&lt;/td&gt;
&lt;td style=&quot;width: 70.1163%;&quot; colspan=&quot;2&quot;&gt;//&amp;nbsp;plugins/api.js &lt;br /&gt;import&amp;nbsp;axios&amp;nbsp;from&amp;nbsp;'axios' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;api&amp;nbsp;=&amp;nbsp;axios.create({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;baseURL:&amp;nbsp;'&lt;a href=&quot;https://example.com/api',&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://example.com/api',&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;headers:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'Content-Type':&amp;nbsp;'application/json' &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;api &lt;br /&gt;//&amp;nbsp;composables/useAxios.js &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;ref&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;api&amp;nbsp;from&amp;nbsp;'@/plugins/api'&amp;nbsp;//&amp;nbsp;Axios&amp;nbsp;인스턴스&amp;nbsp;import &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;function&amp;nbsp;useAxios()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;data&amp;nbsp;=&amp;nbsp;ref(null) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;error&amp;nbsp;=&amp;nbsp;ref(null) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;loading&amp;nbsp;=&amp;nbsp;ref(false) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;request&amp;nbsp;=&amp;nbsp;async&amp;nbsp;(config)&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;true &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;null &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;await&amp;nbsp;api.request(config) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data.value&amp;nbsp;=&amp;nbsp;res.data &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(err)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;err &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;finally&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;false &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;request &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;onMounted&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;useAxios&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'@/composables/useAxios' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;{&amp;nbsp;data,&amp;nbsp;error,&amp;nbsp;loading,&amp;nbsp;request&amp;nbsp;}&amp;nbsp;=&amp;nbsp;useAxios() &lt;br /&gt;&lt;br /&gt;onMounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;request({&amp;nbsp;method:&amp;nbsp;'get',&amp;nbsp;url:&amp;nbsp;'/posts'&amp;nbsp;}) &lt;br /&gt;}) &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;v-if=&quot;loading&quot;&amp;gt;로딩&amp;nbsp;중...&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;v-else-if=&quot;error&quot;&amp;gt;에러:&amp;nbsp;{{&amp;nbsp;error.message&amp;nbsp;}}&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;ul&amp;nbsp;v-else&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;v-for=&quot;item&amp;nbsp;in&amp;nbsp;data&quot;&amp;nbsp;:key=&quot;item.id&quot;&amp;gt;{{&amp;nbsp;item.title&amp;nbsp;}}&amp;lt;/li&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/ul&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/287</guid>
      <comments>https://freewebsite1028.tistory.com/entry/vue-axios#entry287comment</comments>
      <pubDate>Tue, 5 Aug 2025 18:03:57 +0900</pubDate>
    </item>
    <item>
      <title>[핵심만 골라 배우는 Vue.js by 수코딩] 10. 피니아(Pinia), storeToRefs</title>
      <link>https://freewebsite1028.tistory.com/entry/vue-Pinia</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 1077px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 126px;&quot;&gt;
&lt;td style=&quot;width: 12.5581%; height: 126px;&quot;&gt;Pinia(피니아)&lt;/td&gt;
&lt;td style=&quot;width: 87.4419%; height: 126px;&quot; colspan=&quot;3&quot;&gt;Vue.js의 공식 &lt;b&gt;상태 관리 라이브러리&lt;/b&gt;(vue3)&lt;br /&gt;Pinia는 전역 상태(state)를 관리하는 도구로, Vue 컴포넌트 간 데이터를 공유할 수 있게 해줍니다.&lt;br /&gt;* 라우팅으로 상태관리가 어려워 피니아 사용&lt;br /&gt;&lt;br /&gt;1. 피니어가 공유되면 초기화가 안되니&amp;nbsp; 변수를 다르게 하거나, 매개변수를 분리&lt;br /&gt;2. 파일은 js or 타입스크립트 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5581%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%; height: 17px;&quot;&gt;명명규칙&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 50.8139%; height: 17px;&quot;&gt;1. use + 파일명 + Store&amp;nbsp; &amp;nbsp;ex) &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;useCounterStore&lt;span&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;2. 고유값은 파일명과 같게 ex) defineStore(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;' counter ',&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.9535%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;구조분해할당JS문법&lt;/td&gt;
&lt;td style=&quot;width: 50.8139%;&quot;&gt;const&amp;nbsp;store&amp;nbsp;=&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;count:&amp;nbsp;5, &lt;br /&gt;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'Vue' &lt;br /&gt;}&lt;br /&gt;const { count, name } = store&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br /&gt;동일 : const count = store.count,&amp;nbsp; const &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;name&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; &amp;nbsp;= store. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;name&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.9535%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;storeToRefs&lt;/td&gt;
&lt;td style=&quot;width: 50.8139%;&quot;&gt;import { useCounterStore } from '@/stores/counter' &lt;br /&gt;const&amp;nbsp;store&amp;nbsp;=&amp;nbsp;useCounterStore() &lt;br /&gt;watch(() =&amp;gt; store.count, (newVal) =&amp;gt; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;console.log('store.count&amp;nbsp;changed:',&amp;nbsp;newVal) &lt;br /&gt;}) &lt;br /&gt;const { count } = store&amp;nbsp; // &amp;gt; 구조가 분해됨. 최초이후 반응성 없음 &lt;br /&gt;watch(() =&amp;gt; count, (newVal) =&amp;gt; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;console.log('count&amp;nbsp;changed:',&amp;nbsp;newVal)&amp;nbsp;&amp;nbsp;//&amp;nbsp;❌&amp;nbsp;작동안함 &lt;br /&gt;})&lt;br /&gt;&lt;br /&gt;import { useCounterStore } from '@/stores/counter'&lt;br /&gt;const&amp;nbsp;store&amp;nbsp;=&amp;nbsp;useCounterStore()&lt;br /&gt;watch(() =&amp;gt; store.count, (newVal) =&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;console.log('store.count&amp;nbsp;changed:',&amp;nbsp;newVal)&lt;br /&gt;})&lt;br /&gt;&lt;b&gt;const { count } = storeToRefs(store)&lt;/b&gt; //&amp;gt;구조분해 반응성 유지 &lt;br /&gt;watch(() =&amp;gt; count, (newVal) =&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;console.log('count changed:', newVal)&amp;nbsp;&amp;nbsp;// ✅&amp;nbsp;이제&amp;nbsp;count는&amp;nbsp;ref&lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.9535%;&quot;&gt;state, getters를 ref로 안전하게 추출&lt;br /&gt;&lt;br /&gt;**actions 는 반응형이 아님&lt;br /&gt;const { increment } = store&amp;nbsp; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 87.4419%;&quot; colspan=&quot;3&quot;&gt;Option Store vs Setup Store :&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;Option Store&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%;&quot; colspan=&quot;2&quot;&gt;Vue2 : state, getters, actions 객체로 나눔&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;stores/counter.js &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;defineStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'pinia' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;const&amp;nbsp;useCounterStore&amp;nbsp;=&amp;nbsp;defineStore('counter',&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;state:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count:&amp;nbsp;0, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'피니아' &lt;br /&gt;&amp;nbsp;&amp;nbsp;}), &lt;br /&gt;&amp;nbsp;&amp;nbsp;getters:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;doubleCount:&amp;nbsp;(state)&amp;nbsp;=&amp;gt;&amp;nbsp;state.count&amp;nbsp;*&amp;nbsp;2 &lt;br /&gt;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;actions:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;increment()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.count++ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;-----------------------------------------------------&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;useCounterStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'@/stores/counter'&lt;br /&gt;const&amp;nbsp;store&amp;nbsp;=&amp;nbsp;useCounterStore() &lt;br /&gt;const&amp;nbsp;{&amp;nbsp;count,&amp;nbsp;name,&amp;nbsp;doubleCount&amp;nbsp;}&amp;nbsp;=&amp;nbsp;storeToRefs(store)&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;반응형&amp;nbsp;유지 &lt;br /&gt;const&amp;nbsp;{&amp;nbsp;increment&amp;nbsp;}&amp;nbsp;=&amp;nbsp;store&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;메서드는&amp;nbsp;그냥 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.5581%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;Setup Store&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%;&quot; colspan=&quot;2&quot;&gt;Vue3 : ref, computed, function을 setup()처럼 사용&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;stores/counter.js &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;defineStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'pinia' &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;ref,&amp;nbsp;computed&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;const&amp;nbsp;useCounterStore&amp;nbsp;=&amp;nbsp;defineStore('counter',&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;count&amp;nbsp;=&amp;nbsp;ref(0) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;name&amp;nbsp;=&amp;nbsp;ref('피니아') &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;doubleCount&amp;nbsp;=&amp;nbsp;computed(()&amp;nbsp;=&amp;gt;&amp;nbsp;count.value&amp;nbsp;*&amp;nbsp;2) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;function increment() { // this 사용안함&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count.value++ &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;count,&amp;nbsp;name,&amp;nbsp;doubleCount,&amp;nbsp;increment&amp;nbsp;} &lt;br /&gt;})&lt;br /&gt;--------------------------------------------&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;useCounterStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'@/stores/counter'&lt;br /&gt;const&amp;nbsp;store&amp;nbsp;=&amp;nbsp;useCounterStore() &lt;br /&gt;//&amp;nbsp;✅&amp;nbsp;모든&amp;nbsp;속성이&amp;nbsp;ref나&amp;nbsp;computed&amp;nbsp;이므로,&amp;nbsp;구조분해&amp;nbsp;바로&amp;nbsp;사용해도&amp;nbsp;반응형&amp;nbsp;유지 &lt;br /&gt;const&amp;nbsp;{&amp;nbsp;count,&amp;nbsp;doubleCount,&amp;nbsp;increment&amp;nbsp;}&amp;nbsp;=&amp;nbsp;store &lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 120px;&quot;&gt;
&lt;td style=&quot;width: 12.5581%; height: 934px;&quot; rowspan=&quot;3&quot;&gt;기본구현&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%; height: 120px;&quot;&gt;main.js&lt;/td&gt;
&lt;td style=&quot;width: 50.8139%; height: 120px;&quot;&gt;import&amp;nbsp;{&amp;nbsp;createApp&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;&lt;b&gt;import&amp;nbsp;{&amp;nbsp;createPinia&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'pinia'&lt;/b&gt; &lt;br /&gt;import&amp;nbsp;App&amp;nbsp;from&amp;nbsp;'./App.vue' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;app&amp;nbsp;=&amp;nbsp;createApp(App) &lt;br /&gt;&lt;b&gt;app.use(createPinia())&lt;/b&gt; &lt;br /&gt;app.mount('#app') &lt;/td&gt;
&lt;td style=&quot;width: 18.9535%; height: 120px;&quot;&gt;npm&amp;nbsp;install&amp;nbsp;pinia&lt;br /&gt;&lt;br /&gt;npm create vue@latest 사용시 여부 물어봄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 407px;&quot;&gt;
&lt;td style=&quot;width: 17.6745%; height: 407px;&quot;&gt;&lt;b&gt; stores&lt;/b&gt;/counter.js&lt;br /&gt;&lt;br /&gt;src/ &lt;br /&gt;├──&amp;nbsp;main.js &lt;br /&gt;├──&amp;nbsp;App.vue &lt;br /&gt;├──&amp;nbsp;stores/ &lt;br /&gt;│&amp;nbsp;&amp;nbsp;&amp;nbsp;└──&amp;nbsp;counter.js&lt;/td&gt;
&lt;td style=&quot;width: 50.8139%; height: 407px;&quot;&gt;&lt;b&gt;import&amp;nbsp;{&amp;nbsp;defineStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'pinia'&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;//&amp;nbsp;스토어&amp;nbsp;정의 &lt;br /&gt;&lt;b&gt;export&amp;nbsp;const&amp;nbsp;useCounterStore&amp;nbsp;=&amp;nbsp;defineStore(&lt;/b&gt;'&lt;b&gt;counter', {// 이름 파일동일&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;state:&amp;nbsp;()&amp;nbsp;&lt;/b&gt;=&lt;b&gt;&amp;gt; ({&amp;nbsp; // data options 랑 같음&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count:&amp;nbsp;0, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'피니아' &lt;br /&gt;&amp;nbsp;&amp;nbsp;}), &lt;br /&gt;&amp;nbsp;&lt;b&gt; getters: { // computed options 랑 같음, status 에 매개변수전달&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;doubleCount:&amp;nbsp;(state)&amp;nbsp;=&amp;gt;&amp;nbsp;state.count&amp;nbsp;*&amp;nbsp;2 &lt;br /&gt;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;actions: { //methods 같음, status this.로전달, 반응형아님&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;increment()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.count++ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;async&amp;nbsp;incrementLater()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;await&amp;nbsp;new&amp;nbsp;Promise(resolve&amp;nbsp;=&amp;gt;&amp;nbsp;setTimeout(resolve,&amp;nbsp;1000)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.increment() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}) &lt;/td&gt;
&lt;td style=&quot;width: 18.9535%; height: 407px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 407px;&quot;&gt;
&lt;td style=&quot;width: 17.6745%; height: 407px;&quot;&gt;App.vue&lt;/td&gt;
&lt;td style=&quot;width: 50.8139%; height: 407px;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;style=&quot;padding:&amp;nbsp;2rem&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h1&amp;gt; Pinia 샘플&amp;lt;/h1&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;이름:&amp;nbsp;{{&amp;nbsp;counter.name&amp;nbsp;}}&amp;lt;/p&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;카운트:&amp;nbsp;{{&amp;nbsp;counter.count&amp;nbsp;}}&amp;lt;/p&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;2배&amp;nbsp;카운트:&amp;nbsp;{{&amp;nbsp;counter.doubleCount&amp;nbsp;}}&amp;lt;/p&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;@click=&quot;counter.increment&quot;&amp;gt;+1&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;@click=&quot;counter.incrementLater&quot;&amp;gt;1초&amp;nbsp;후&amp;nbsp;+1&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;&lt;b&gt;import&amp;nbsp;{&amp;nbsp;useCounterStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'./stores/counter'&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;//&amp;nbsp;스토어&amp;nbsp;인스턴스&amp;nbsp;불러오기 &lt;br /&gt;&lt;b&gt;const&amp;nbsp;counter&amp;nbsp;=&amp;nbsp;useCounterStore()&lt;/b&gt; &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.9535%; height: 407px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/286</guid>
      <comments>https://freewebsite1028.tistory.com/entry/vue-Pinia#entry286comment</comments>
      <pubDate>Tue, 5 Aug 2025 17:17:34 +0900</pubDate>
    </item>
    <item>
      <title>[핵심만 골라 배우는 Vue.js by 수코딩] 9. 라우팅</title>
      <link>https://freewebsite1028.tistory.com/entry/vue-router</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 274px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 65px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 65px;&quot;&gt;라우팅 &lt;br /&gt;Routing&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%; height: 65px;&quot;&gt;서버측 라우팅&lt;/td&gt;
&lt;td style=&quot;width: 80.2325%; height: 65px;&quot; colspan=&quot;2&quot;&gt;하나의 네트워크 에서 다른 네트워크로 데이터 패킷이 전달되는 경로를 결정하는 과정&lt;br /&gt;ex) 웹사이트를 열면 요청이 여러 라우터를 거쳐 해당 서버까지 도달&lt;br /&gt;* 라우터&amp;nbsp; : 이 경로를 결정해주는 장비&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 43px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%; height: 124px;&quot; rowspan=&quot;3&quot;&gt;클라이언트측 라우팅&lt;/td&gt;
&lt;td style=&quot;width: 80.2325%; height: 43px;&quot; colspan=&quot;2&quot;&gt;사용자가 요청한 URL 에 따라 어떤 코드(페이지, 함수)를 실행할지 정하는 것 .&lt;br /&gt;주소 호출시 어떤 코드로 연결할지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 60px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 60px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%; height: 60px;&quot;&gt;해시 라우팅&amp;nbsp;&lt;br /&gt;( Hash Routing )&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%; height: 60px;&quot;&gt;&lt;a href=&quot;http://example.com/#/about&quot;&gt;http://example.com/#/about&lt;/a&gt;&lt;br /&gt;해시(#) 뒤의 내용을 클라이언트 에서만 해석&lt;br /&gt;URL이 # 포함이라 미관상 별로고 SEO에 약함&lt;br /&gt;* SEO 검색엔진 최적화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%; height: 21px;&quot;&gt;브라우저 라우팅&lt;br /&gt;( History Mode &lt;br /&gt;/ HTML5 History API 사용 )&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%; height: 21px;&quot;&gt;실제 URL 경로를 사용 history.pushState() 이용해 페이지를 바꾸지만 전체 새로고침 없이 처리&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%; height: 17px;&quot;&gt;방식 (실전사용X)&lt;/td&gt;
&lt;td style=&quot;width: 80.2325%; height: 17px;&quot; colspan=&quot;2&quot;&gt;src/ &lt;br /&gt;├──&amp;nbsp;BrowserRouter.vue &lt;br /&gt;├──&amp;nbsp;pages/ &lt;br /&gt;│&amp;nbsp;&amp;nbsp;&amp;nbsp;├──&amp;nbsp;Home.vue &lt;br /&gt;│&amp;nbsp;&amp;nbsp;&amp;nbsp;├──&amp;nbsp;About.vue &lt;br /&gt;│&amp;nbsp;&amp;nbsp;&amp;nbsp;└──&amp;nbsp;NotFound.vue&amp;nbsp;&amp;nbsp;&amp;larr;&amp;nbsp;이거&amp;nbsp;추가! &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;ref,&amp;nbsp;computed&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;Home&amp;nbsp;from&amp;nbsp;'./pages/Home.vue' &lt;br /&gt;import&amp;nbsp;About&amp;nbsp;from&amp;nbsp;'./pages/About.vue' &lt;br /&gt;import&amp;nbsp;NotFound&amp;nbsp;from&amp;nbsp;'./pages/NotFound.vue'&amp;nbsp;&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;경로&amp;nbsp;&amp;rarr;&amp;nbsp;컴포넌트&amp;nbsp;매핑 &lt;br /&gt;&lt;b&gt;const&amp;nbsp;routeMap&amp;nbsp;=&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;'/':&amp;nbsp;Home, &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;'/about':&amp;nbsp;About &lt;/b&gt;&lt;br /&gt;&lt;b&gt;}&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;//&amp;nbsp;현재&amp;nbsp;경로&amp;nbsp;추적 &lt;br /&gt;&lt;b&gt;const currentPath = ref(window.location.pathname) // 주소가져옴 default &quot;/&quot;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;페이지&amp;nbsp;이동&amp;nbsp;함수 &lt;br /&gt;&lt;b&gt;function navigate(path) { // 현재 주소로 등록&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;window.history.pushState({},&amp;nbsp;'',&amp;nbsp;path) &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;currentPath.value&amp;nbsp;=&amp;nbsp;path &lt;/b&gt;&lt;br /&gt;&lt;b&gt;}&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;//&amp;nbsp;현재&amp;nbsp;컴포넌트&amp;nbsp;가져오기 &lt;br /&gt;&lt;b&gt;const&amp;nbsp;CurrentView&amp;nbsp;=&amp;nbsp;computed(()&amp;nbsp;=&amp;gt;&amp;nbsp;routeMap[currentPath.value]&amp;nbsp;||&amp;nbsp;NotFound)&lt;/b&gt; &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h2&amp;gt;Current&amp;nbsp;Path:&amp;nbsp;{{&amp;nbsp;currentPath&amp;nbsp;}}&amp;lt;/h2&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;nav&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;href=&quot;/&quot;&lt;/span&gt; &amp;nbsp;@click=&quot;navigate('/')&quot;&amp;gt;Home&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button href=&quot;/about&quot; &lt;b&gt;@click=&quot;navigate('/about')&lt;/b&gt;&quot;&amp;gt;About&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/nav&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;hr&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;component&amp;nbsp;:is=&quot;CurrentView&quot;&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.7209%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%;&quot; rowspan=&quot;4&quot;&gt;Vue-router 라이브러리&lt;/td&gt;
&lt;td style=&quot;width: 80.2325%;&quot; colspan=&quot;2&quot;&gt;1.&amp;nbsp; &amp;nbsp;스케폴드 설치시 이미 vue-router 설치 필요없음&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - npm install vue-router@4&amp;nbsp; &amp;nbsp; 4점대 버전 로 설치&lt;br /&gt;2. lazy loading : 설정 안하면 초기로딩히 모든페이지 로딩&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- component: () =&amp;gt; import('../pages/About.vue')&lt;br /&gt;3. routers 의 name 속성 중복 금지.&amp;nbsp;&lt;br /&gt;4. router-link 생성시 name, params 등록 가능&lt;br /&gt;5. 동적경로 매칭 . URLL 의 일부분을 동적으로 변할 수 있게 해줌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 18.8372%;&quot;&gt;main.js&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%;&quot;&gt;import&amp;nbsp;{&amp;nbsp;createApp&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;App&amp;nbsp;from&amp;nbsp;'./App.vue' &lt;br /&gt;&lt;b&gt;import routers from './routers'&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;createApp(App)&lt;b&gt;.use( routers )&lt;/b&gt;.mount('#app') &lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%; height: 17px;&quot;&gt;router/index.js 권장&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%; height: 17px;&quot;&gt;import&amp;nbsp;{&amp;nbsp;createRouter,&amp;nbsp;createWebHistory&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue-router' &lt;br /&gt;import&amp;nbsp;Home&amp;nbsp;from&amp;nbsp;'../pages/Home.vue' &lt;br /&gt;import&amp;nbsp;About&amp;nbsp;from&amp;nbsp;'../pages/About.vue' &lt;br /&gt;import&amp;nbsp;NotFound&amp;nbsp;from&amp;nbsp;'../pages/NotFound.vue' &lt;br /&gt;&lt;br /&gt;&lt;b&gt;const router = createRouter({&lt;/b&gt;&lt;br /&gt;&lt;b&gt; &amp;nbsp; // HTML5 History API 사용= 브라우저 라우팅 , 해시방식 적용 가능&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;history: createWebHistory(import.meta.env.BASE_URL), //baseurl 설정&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;routes: &amp;nbsp;[&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;{ path: '/',&amp;nbsp; name='home' , component: Home },&lt;br /&gt;&amp;nbsp; { path:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;'/about&lt;/span&gt;' , name='about', component: () =&amp;gt; import('../pages/About.vue') // ✅ lazy load},&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;{ path: &lt;span style=&quot;color: #ee2323;&quot;&gt;'/about/:id/contexts/:index&lt;/span&gt;' , name='aboutDetail', component: () =&amp;gt; import('../pages/AboutDetail.vue') // ✅ lazy load},&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;{&amp;nbsp;path:&amp;nbsp;'/:pathMatch(.*)*',&amp;nbsp;name:&amp;nbsp;'NotFound',&amp;nbsp;component:&amp;nbsp;NotFound&amp;nbsp;},&amp;nbsp;//&amp;nbsp;404&lt;/b&gt;&lt;br /&gt;&lt;b&gt;] &lt;/b&gt;&lt;br /&gt;&lt;b&gt;})&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;router &lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.7209%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%; height: 17px;&quot;&gt;App.vue&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%; height: 17px;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h2&amp;gt;라우터&amp;nbsp;예제&amp;lt;/h2&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;nav&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;lt;router-link to=&quot;/&quot;&amp;gt;Home&amp;lt;/router-link&amp;gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;lt;router-link :to=&quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;{name:'about', params:{id:12}}&lt;/span&gt;&quot;&amp;gt;About&amp;lt;/router-link&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;router-link :to=&quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;`/about/${id}/contexts/${index}`&lt;/span&gt;&quot;&amp;gt;AboutDetail&amp;lt;/router-link&amp;gt;&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/nav&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;hr&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;nbsp;&amp;lt;router-view&amp;nbsp;/&amp;gt;&lt;/b&gt;&amp;nbsp;&amp;lt;!--&amp;nbsp;현재&amp;nbsp;라우트에&amp;nbsp;해당하는&amp;nbsp;컴포넌트를&amp;nbsp;렌더링&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.7209%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;useRoute(); &lt;br /&gt;동적 경로 매칭&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%;&quot;&gt;import&amp;nbsp;{&amp;nbsp;&lt;b&gt;createRouter,&amp;nbsp;createWebHistory&amp;nbsp;&lt;/b&gt;}&amp;nbsp;from&amp;nbsp;'vue-router' &lt;br /&gt;const route = useRoute();&lt;br /&gt;const ids =Number( &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;route.params.id&lt;/span&gt;&lt;/span&gt; );&lt;br /&gt;const index=Number(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;route.params.index&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;);&lt;br /&gt;&lt;br /&gt;const&amp;nbsp;router&amp;nbsp;=&amp;nbsp;createRouter({&lt;br /&gt;&amp;nbsp;&amp;nbsp;history:&amp;nbsp;&lt;b&gt;createWebHistory&lt;/b&gt;(),&lt;br /&gt;&amp;nbsp;&amp;nbsp;routes&lt;br /&gt;}) &lt;/span&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.7209%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;useRoute();&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%;&quot;&gt;Proxy&amp;nbsp;&lt;br /&gt;속성&lt;br /&gt;fullPath&lt;br /&gt;hash&lt;br /&gt;meta&amp;nbsp; &amp;lt;&amp;lt; 라우트정의 시 meta 정보로 원하는 사용자 지정속성 가능.&amp;nbsp;&lt;br /&gt;name&lt;br /&gt;params&lt;br /&gt;path&lt;br /&gt;query&amp;nbsp; &amp;lt;&amp;lt; URL ? 다음&amp;nbsp; 문자 = 쿼리 스트링&lt;br /&gt;redirectedFrom&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.7209%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;meta 속성&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%;&quot;&gt;라우트에 부가적인 정보 넣는 속성&lt;br /&gt;&lt;br /&gt;const&amp;nbsp;routes&amp;nbsp;=&amp;nbsp;[ &lt;br /&gt;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path:&amp;nbsp;'/about', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;component:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;import('../pages/About.vue'), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;meta:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;'About&amp;nbsp;Page',&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;문서&amp;nbsp;제목&amp;nbsp;설정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;requiresAuth:&amp;nbsp;true,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;로그인&amp;nbsp;여부&amp;nbsp;확인 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;layout:&amp;nbsp;'admin',&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;특정&amp;nbsp;레이아웃&amp;nbsp;지정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;transition:&amp;nbsp;'fade-slide'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;페이지&amp;nbsp;전환&amp;nbsp;효과 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;] &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;computed&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;useRoute&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue-router' &lt;br /&gt;import&amp;nbsp;DefaultLayout&amp;nbsp;from&amp;nbsp;'./layouts/DefaultLayout.vue' &lt;br /&gt;import&amp;nbsp;AdminLayout&amp;nbsp;from&amp;nbsp;'./layouts/AdminLayout.vue' &lt;br /&gt;&lt;br /&gt;&lt;b&gt;const&amp;nbsp;route&amp;nbsp;=&amp;nbsp;useRoute() &lt;/b&gt;&lt;br /&gt;&lt;b&gt;const layout = computed(() =&amp;gt; { &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;route.meta.layout&amp;nbsp;===&amp;nbsp;'admin'&amp;nbsp;?&amp;nbsp;AdminLayout&amp;nbsp;:&amp;nbsp;DefaultLayout &lt;/b&gt;&lt;br /&gt;&lt;b&gt;})&lt;/b&gt; &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.7209%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.0466%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;중첩 라우트&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 61.3953%;&quot;&gt;* name 속성은&amp;nbsp; children 에만 추가 가능, 부모X&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;createRouter,&amp;nbsp;createWebHistory&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue-router' &lt;br /&gt;import Users from '../pages/Users.vue'&lt;br /&gt;const&amp;nbsp;routes&amp;nbsp;=&amp;nbsp;[ &lt;br /&gt;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path:&amp;nbsp;'/users', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;component:&amp;nbsp;Users,&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;부모&amp;nbsp;라우트 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;children:&amp;nbsp;[ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path:&amp;nbsp;'',&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;/users&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; name : 'users',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;component:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;import('../pages/UserList.vue') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path:&amp;nbsp;':id',&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;/users/123&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; name : 'userDetail'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;component:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;import('../pages/UserDetail.vue') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;] &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;]&lt;br /&gt;const&amp;nbsp;router&amp;nbsp;=&amp;nbsp;createRouter({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;history:&amp;nbsp;createWebHistory(), &lt;br /&gt;&amp;nbsp;&amp;nbsp;routes &lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;router&lt;br /&gt;Users.vue&amp;nbsp; ------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h1&amp;gt; &amp;nbsp;사용자&amp;nbsp;영역&amp;lt;/h1&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;router-view&amp;nbsp;/&amp;gt;&amp;nbsp;&amp;lt;!--&amp;nbsp;자식&amp;nbsp;라우트가&amp;nbsp;여기&amp;nbsp;들어옴&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const comma = (price) =&amp;gt; price.toLocaleString();&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;prive: {{comma(productDetail.price)}} 원&lt;/p&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/285</guid>
      <comments>https://freewebsite1028.tistory.com/entry/vue-router#entry285comment</comments>
      <pubDate>Tue, 5 Aug 2025 16:21:08 +0900</pubDate>
    </item>
    <item>
      <title>[핵심만 골라 배우는 Vue.js by 수코딩] 8. Options API vs Composition API,  컴포저블 패턴</title>
      <link>https://freewebsite1028.tistory.com/entry/vue-Composition-API</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.3022%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;Options&amp;nbsp;API&lt;/td&gt;
&lt;td style=&quot;width: 30.9303%;&quot;&gt;Composition API (vue3)&lt;/td&gt;
&lt;td style=&quot;width: 22.9069%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.3022%;&quot;&gt;ref&lt;br /&gt;reactive&lt;/td&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;name:'',&amp;nbsp;//&amp;nbsp;컴포넌트&amp;nbsp;이름 &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:{},&amp;nbsp;//&amp;nbsp;자식&amp;nbsp;컴포넌트&amp;nbsp;등록 &lt;br /&gt;&amp;nbsp;&amp;nbsp;props:{},&amp;nbsp;//&amp;nbsp;부모로부터&amp;nbsp;받는&amp;nbsp;속성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;emits:[],&amp;nbsp;//&amp;nbsp;자식&amp;nbsp;&amp;rarr;&amp;nbsp;부모&amp;nbsp;이벤트 &lt;br /&gt;&amp;nbsp;&amp;nbsp;data(){return{};},&amp;nbsp;//&amp;nbsp;반응형&amp;nbsp;데이터 &lt;br /&gt;&amp;nbsp;&amp;nbsp;computed:{},&amp;nbsp;//&amp;nbsp;계산된&amp;nbsp;속성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;watch:{},&amp;nbsp;//&amp;nbsp;감시자 &lt;br /&gt;&amp;nbsp;&amp;nbsp;methods:{},&amp;nbsp;//&amp;nbsp;메서드&amp;nbsp;정의 &lt;br /&gt;&amp;nbsp;&amp;nbsp;provide(){return{};}, // 하위 컴포넌트 제공 &lt;br /&gt;&amp;nbsp;&amp;nbsp;inject:[],&amp;nbsp;//&amp;nbsp;상위&amp;nbsp;컴포넌트에서&amp;nbsp;주입 &lt;br /&gt;&amp;nbsp;&amp;nbsp;mixins:[],&amp;nbsp;//&amp;nbsp;믹스인 &lt;br /&gt;&amp;nbsp;&amp;nbsp;extends:{},&amp;nbsp;//&amp;nbsp;확장할&amp;nbsp;컴포넌트 &lt;br /&gt;&amp;nbsp;&amp;nbsp;created(){},&amp;nbsp;//&amp;nbsp;생성&amp;nbsp;시 &lt;br /&gt;&amp;nbsp;&amp;nbsp;mounted(){}&amp;nbsp;//&amp;nbsp;마운트&amp;nbsp;시 &lt;br /&gt;};&lt;/td&gt;
&lt;td style=&quot;width: 30.9303%;&quot;&gt;&lt;b&gt;&amp;lt;script&amp;gt;&lt;/b&gt;&lt;br /&gt;import {ref, reactive, comupted } from &quot;vue&quot;;&lt;br /&gt;export default{&lt;br /&gt;&amp;nbsp; const count = ref(0);&lt;br /&gt;&amp;nbsp; //RefImpl 형태 value로접근이유&lt;br /&gt;&amp;nbsp; console.log(count);&lt;br /&gt;&amp;nbsp; const increment = comupted(()=&amp;gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; return `count: ${count.value}`++;&lt;br /&gt;&amp;nbsp; });&lt;br /&gt;&amp;nbsp; &lt;b&gt;setup(){&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; return{ &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// 객체로 반환해야 정상사용&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; count,&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; increment,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; message&lt;br /&gt;&amp;nbsp; &amp;nbsp; };&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;};&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;template&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;h1&amp;gt;{{message}}&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;button @click=&quot;increament&quot;&amp;gt;증가&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;/button&amp;gt;&lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 22.9069%;&quot;&gt;ref&amp;nbsp; : 기본자료형&lt;br /&gt;reactive : 참조자료형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.3022%;&quot;&gt;watch&lt;/td&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;data()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;user:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'홍길동' &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}; &lt;br /&gt;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&lt;b&gt;&amp;nbsp;watch:&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;user:&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handler(newVal,&amp;nbsp;oldVal)&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('깊은:', newVal.name); &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}, &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;deep: true, immediate:&amp;nbsp;true&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;}&lt;/b&gt; &lt;br /&gt;};&lt;/td&gt;
&lt;td style=&quot;width: 30.9303%;&quot;&gt;&lt;br /&gt;&amp;lt;&lt;b&gt;script&amp;nbsp;setup&lt;/b&gt;&amp;gt;&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;reactive,&amp;nbsp;watch&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue'; &lt;br /&gt;&lt;br /&gt;const user = reactive({&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'홍길동' &lt;br /&gt;}); &lt;br /&gt;console.log( user&amp;nbsp; ) //proxy 객체&lt;br /&gt;&lt;br /&gt;watch( &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;user, &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;(newVal,&amp;nbsp;oldVal)&lt;/b&gt;&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('깊은', newVal.name); &lt;br /&gt;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&amp;nbsp;deep:&amp;nbsp;true&amp;nbsp;} &lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;or&amp;nbsp;&lt;br /&gt;&lt;br /&gt;watch(&lt;br /&gt;&lt;b&gt;()=&amp;gt;user.value.name&lt;/b&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;(newVal,&amp;nbsp;oldVal)&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('깊은', newVal.name);&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;{ deep: false, immediate:&amp;nbsp;true&amp;nbsp;}&lt;br /&gt;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 22.9069%;&quot;&gt;객체 내부 속성 변화를 감지&lt;br /&gt;1. deep:&amp;nbsp;true&lt;br /&gt;깊은 감시여부 선택가능&lt;br /&gt;2. immediate:&amp;nbsp;true&amp;nbsp;&lt;br /&gt;감지여부 상관없이 처음 무조건 실행&lt;br /&gt;3. flush&amp;nbsp; 옵션&lt;br /&gt;pre : Dom 업데이트이전, 기본&lt;br /&gt;post :Dom 업데이트 이후 , css 적용시 고려&lt;br /&gt;sync :&amp;nbsp; 반응형상태 변경과 동시&lt;br /&gt;4. 배열로 지정가능&lt;br /&gt;const x = ref(0);&lt;br /&gt;const y = ref(0); &lt;br /&gt;const z = ref(0); &lt;br /&gt;watch( [x, y, z],&lt;br /&gt;&amp;nbsp;&amp;nbsp;(newVal, oldVal) =&amp;gt; {&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;감시대상이 감지안되면 callback 함수 호출안함&lt;br /&gt;&lt;br /&gt;* getter함수 : &lt;br /&gt;()=&amp;gt;user.value.name&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.3022%;&quot;&gt;watchEffect()&lt;/td&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;없음&lt;/td&gt;
&lt;td style=&quot;width: 30.9303%;&quot;&gt;import&amp;nbsp;{&amp;nbsp;ref,&amp;nbsp;watchEffect&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue'; &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;message&amp;nbsp;=&amp;nbsp;ref('안녕'); &lt;br /&gt;&lt;br /&gt;watchEffect(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp; console.log(user.value.name);&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;# name 만 추적&lt;br /&gt;});&lt;/td&gt;
&lt;td style=&quot;width: 22.9069%;&quot;&gt;watchEffect()&amp;nbsp;안에서&amp;nbsp;사용된&amp;nbsp;반응형&amp;nbsp;변수들을&amp;nbsp;Vue가&amp;nbsp;자동으로&amp;nbsp;추적&lt;br /&gt;1. 즉시실행&lt;br /&gt;2. 자동추적&lt;br /&gt;3. 사용된 값만 추적&lt;br /&gt;4. 각각 의 값을 추적할때 공통된 콜백함수 실행&lt;br /&gt;5. flush&amp;nbsp; 옵션&lt;br /&gt;pre : Dom 업데이트이전&lt;br /&gt;post :Dom 업데이트 이후 , css 적용시 고려&lt;br /&gt;sync :&amp;nbsp; 반응형상태 변경과 동시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.3022%;&quot;&gt;watchposteffect()&lt;/td&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 30.9303%;&quot;&gt;watchPostEffect(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(box.value)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('렌더링&amp;nbsp;후&amp;nbsp;박스&amp;nbsp;높이:',&amp;nbsp;box.value.offsetHeight); &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;});&lt;/td&gt;
&lt;td style=&quot;width: 22.9069%;&quot;&gt;watchEffect() 와 비슷하지만 DOM&amp;nbsp; 업데이트 이후 실행,&lt;br /&gt;offsetHeight, scrollTop, focus &amp;nbsp;같은 css 요소 읽을때 유리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.3022%;&quot;&gt;watch 해지&lt;/td&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;var unwatch = watch()&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;var unwatch =&lt;span&gt; watchEffect &lt;/span&gt;&lt;/span&gt;()&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;var unwatch =&lt;span&gt;&lt;span&gt; watchposteffect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;() &lt;br /&gt;unwatch()&amp;nbsp; // 해지&lt;/td&gt;
&lt;td style=&quot;width: 30.9303%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 22.9069%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 225px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 65px;&quot;&gt;
&lt;td style=&quot;width: 13.9535%; height: 65px;&quot;&gt;컴포저블 패턴&lt;/td&gt;
&lt;td style=&quot;width: 86.0465%; height: 65px;&quot; colspan=&quot;3&quot;&gt;Vue Composition API(vue3)를 이용해 &lt;b&gt;반복되는 로직을 재사용 가능한 함수로 분리하는 방식&lt;/b&gt;&lt;br /&gt;setup()&amp;nbsp;안에&amp;nbsp;자주&amp;nbsp;쓰는&amp;nbsp;ref,&amp;nbsp;watch,&amp;nbsp;api&amp;nbsp;호출,&amp;nbsp;유효성&amp;nbsp;검사,&amp;nbsp;토스트&amp;nbsp;알림&amp;nbsp;등등을&amp;nbsp;밖으로&amp;nbsp;빼서&amp;nbsp;따로&amp;nbsp;함수화해두고,&amp;nbsp;필요한&amp;nbsp;컴포넌트에서&amp;nbsp;불러다&amp;nbsp;재사용하는&amp;nbsp;패턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 13.9535%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%; height: 21px;&quot;&gt;상태 비저장 로직&lt;/td&gt;
&lt;td style=&quot;width: 46.8604%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 21.8605%; height: 21px;&quot;&gt;어떤 입력에 따른 결과값을 즉시 반환 &lt;br /&gt;ex) 날짜 포멧팅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 13.9535%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%; height: 21px;&quot;&gt;상태 저장 로직&lt;/td&gt;
&lt;td style=&quot;width: 46.8604%; height: 21px;&quot;&gt;마우스포인터위치&lt;br /&gt;composables/useMouse.js --------------------------------&lt;br /&gt;&lt;b&gt;import { ref, onMounted, onUnmounted } from 'vue'&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;function&amp;nbsp;useMouse()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;x&amp;nbsp;=&amp;nbsp;ref(0) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;y&amp;nbsp;=&amp;nbsp;ref(0) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;function&amp;nbsp;updateMouse(e)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x.value&amp;nbsp;=&amp;nbsp;e.pageX &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y.value&amp;nbsp;=&amp;nbsp;e.pageY &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;onMounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;window.addEventListener('mousemove',&amp;nbsp;updateMouse) &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;onUnmounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;window.removeEventListener('mousemove',&amp;nbsp;updateMouse) &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;x,&amp;nbsp;y&amp;nbsp;} &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;components/MouseTracker.vue -----------------------------&lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;useMouse&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'@/composables/useMouse' &lt;br /&gt;&lt;br /&gt;&lt;b&gt;const&amp;nbsp;{&amp;nbsp;x,&amp;nbsp;y&amp;nbsp;}&amp;nbsp;=&amp;nbsp;useMouse()&lt;/b&gt; &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;마우스&amp;nbsp;위치:&amp;nbsp;X&amp;nbsp;=&amp;nbsp;{{&amp;nbsp;x&amp;nbsp;}},&amp;nbsp;Y&amp;nbsp;=&amp;nbsp;{{&amp;nbsp;y&amp;nbsp;}}&amp;lt;/p&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 21.8605%; height: 21px;&quot;&gt;시간이 지나면서 변경되는 상태를 다루는 로직&lt;br /&gt;- 반응형&lt;br /&gt;&lt;br /&gt;localStorage 구현시 새로고침때유지 확인가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.9535%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%; height: 17px;&quot;&gt;상태 저장및 비동기&lt;br /&gt;( axios 사용 )&lt;/td&gt;
&lt;td style=&quot;width: 46.8604%; height: 17px;&quot;&gt;//&amp;nbsp;plugins/api.js &lt;br /&gt;import&amp;nbsp;axios&amp;nbsp;from&amp;nbsp;'axios' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;api&amp;nbsp;=&amp;nbsp;axios.create({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;baseURL:&amp;nbsp;'&lt;a href=&quot;https://example.com/api',&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://example.com/api',&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;headers:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'Content-Type':&amp;nbsp;'application/json' &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;api&lt;br /&gt;//&amp;nbsp;composables/useAxios.js &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;ref&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;api&amp;nbsp;from&amp;nbsp;'@/plugins/api'&amp;nbsp;//&amp;nbsp;Axios&amp;nbsp;인스턴스&amp;nbsp;import &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;function&amp;nbsp;useAxios()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;data&amp;nbsp;=&amp;nbsp;ref(null) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;error&amp;nbsp;=&amp;nbsp;ref(null) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;loading&amp;nbsp;=&amp;nbsp;ref(false) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;const&amp;nbsp;request&amp;nbsp;=&amp;nbsp;async&amp;nbsp;(config)&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;true &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;null &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;await&amp;nbsp;api.request(config)&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data.value&amp;nbsp;=&amp;nbsp;res.data &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(err)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;err &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;finally&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;false &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;request &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;onMounted&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;useAxios&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'@/composables/useAxios' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;{&amp;nbsp;data,&amp;nbsp;error,&amp;nbsp;loading,&amp;nbsp;request&amp;nbsp;}&amp;nbsp;=&amp;nbsp;useAxios() &lt;br /&gt;&lt;br /&gt;onMounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;request({&amp;nbsp;method:&amp;nbsp;'get',&amp;nbsp;url:&amp;nbsp;'/posts'&amp;nbsp;})&lt;/b&gt; &lt;br /&gt;}) &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;v-if=&quot;loading&quot;&amp;gt;로딩&amp;nbsp;중...&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;v-else-if=&quot;error&quot;&amp;gt;에러:&amp;nbsp;{{&amp;nbsp;error.message&amp;nbsp;}}&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;ul&amp;nbsp;v-else&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;v-for=&quot;item&amp;nbsp;in&amp;nbsp;data&quot;&amp;nbsp;:key=&quot;item.id&quot;&amp;gt;{{&amp;nbsp;item.title&amp;nbsp;}}&amp;lt;/li&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/ul&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 21.8605%; height: 17px;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;await&amp;nbsp;api.request(config)&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data.value&amp;nbsp;=&amp;nbsp;res.data&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(err)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;err&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;finally&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;false&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp; &amp;nbsp;는&amp;nbsp;&lt;br /&gt;&lt;br /&gt;api.request(config) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.then(res&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data.value&amp;nbsp;=&amp;nbsp;res.data &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.catch(err&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;err &lt;br /&gt;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;.finally(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;false &lt;br /&gt;&amp;nbsp;&amp;nbsp;})&amp;nbsp; 으로 구현가능&lt;br /&gt;&lt;br /&gt;watchEffect(()=&amp;gt;{&lt;br /&gt;&amp;nbsp; request();&lt;br /&gt;})&lt;br /&gt;결과값을 watch 로 변경된값을 받아야함.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 13.9535%; height: 16px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%; height: 16px;&quot;&gt;pinia 사용&lt;/td&gt;
&lt;td style=&quot;width: 46.8604%; height: 16px;&quot;&gt;//&amp;nbsp;stores/post.js &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;defineStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'pinia' &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;ref&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;api&amp;nbsp;from&amp;nbsp;'@/plugins/api' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;const&amp;nbsp;usePostStore&amp;nbsp;=&amp;nbsp;defineStore('post',&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;posts&amp;nbsp;=&amp;nbsp;ref([]) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;loading&amp;nbsp;=&amp;nbsp;ref(false) &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;error&amp;nbsp;=&amp;nbsp;ref(null) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;fetchPosts&amp;nbsp;=&amp;nbsp;async&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;true &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;null &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;res&amp;nbsp;=&amp;nbsp;await&amp;nbsp;api.get('/posts') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;posts.value&amp;nbsp;=&amp;nbsp;res.data &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;catch&amp;nbsp;(err)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error.value&amp;nbsp;=&amp;nbsp;err &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;finally&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading.value&amp;nbsp;=&amp;nbsp;false &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;posts, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loading, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fetchPosts &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;})&lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;onMounted&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;usePostStore&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'@/stores/post' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;postStore&amp;nbsp;=&amp;nbsp;usePostStore() &lt;br /&gt;&lt;br /&gt;onMounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;postStore.fetchPosts() &lt;br /&gt;}) &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;v-if=&quot;postStore.loading&quot;&amp;gt;로딩&amp;nbsp;중...&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;v-else-if=&quot;postStore.error&quot;&amp;gt;에러:&amp;nbsp;{{&amp;nbsp;postStore.error.message&amp;nbsp;}}&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;ul&amp;nbsp;v-else&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;v-for=&quot;post&amp;nbsp;in&amp;nbsp;postStore.posts&quot;&amp;nbsp;:key=&quot;post.id&quot;&amp;gt;{{&amp;nbsp;post.title&amp;nbsp;}}&amp;lt;/li&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/ul&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 21.8605%; height: 16px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/283</guid>
      <comments>https://freewebsite1028.tistory.com/entry/vue-Composition-API#entry283comment</comments>
      <pubDate>Mon, 4 Aug 2025 18:00:51 +0900</pubDate>
    </item>
    <item>
      <title>[핵심만 골라 배우는 Vue.js by 수코딩] 7. 컴포넌트 심화- 상속, 동적렌더링</title>
      <link>https://freewebsite1028.tistory.com/entry/vue-components-more</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.06977%;&quot; rowspan=&quot;7&quot;&gt;컴포넌트&lt;/td&gt;
&lt;td style=&quot;width: 12.3255%;&quot; rowspan=&quot;4&quot;&gt;상속&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;inheritance&lt;/span&gt; &lt;/td&gt;
&lt;td style=&quot;width: 39.6512%;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;MyButton class=&quot;red&quot; id=&quot;main&quot; label=&quot;클릭!&quot; @click=&quot;handleClick&quot; /&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;import&amp;nbsp;MyButton&amp;nbsp;from&amp;nbsp;'./MyButton.vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;MyButton&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;methods:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handleClick()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert('부모가&amp;nbsp;클릭&amp;nbsp;받음!') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;---------------------------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;button v-bind=&quot;$attrs&quot; @click=&quot;$emit('click')&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{{&amp;nbsp;label&amp;nbsp;}} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;inheritAttrs:&amp;nbsp;false,&amp;nbsp;//&amp;nbsp;자동&amp;nbsp;전달&amp;nbsp;방지 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;props:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label:&amp;nbsp;String &lt;br /&gt;&amp;nbsp;&amp;nbsp;}, &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;emits:&amp;nbsp;['click'] &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;속성&lt;span&gt; &lt;/span&gt;&lt;/span&gt;상속&lt;br /&gt;1. root node 가 한개만 있을때&amp;nbsp;&lt;br /&gt;하기를 제외하고 모두 속성이 상속됨&lt;br /&gt;- 자식 클래스에서 &lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;props, emits&lt;/span&gt; 로 선언하지 않은것들 : 이벤트, v-model&amp;nbsp;&lt;br /&gt;- 상속 불가 특수속성 : ref, key, slot&lt;br /&gt;- scope style : 부모 style 은 자식에 영향없음&lt;br /&gt;&lt;br /&gt;2. &lt;b&gt;상속금지 ==&amp;nbsp; inheritAttrs: false 설정&lt;/b&gt;&lt;br /&gt;자동 속성 상속 비활성화&lt;br /&gt;&amp;lt;button v-bind=&quot;$attrs&quot;&amp;gt;Click&amp;lt;/button&amp;gt; 로 수동입력&lt;br /&gt;&lt;br /&gt;3. &lt;b&gt;$attrs&lt;/b&gt;: 부모에서 전달된 props가 아닌 모든 속성들을 담은 객체, props 로 선언되지 않은 속성들만 $attrs 에 들어감. &lt;br /&gt;&lt;br /&gt;4. &lt;b&gt;멀티루트 상속 == root node 가 두개이상&lt;/b&gt;일때&amp;nbsp;&lt;br /&gt;v-bind=&quot;$attrs&quot; 지정시 상속 일어남&lt;br /&gt;&lt;br /&gt;5. 중첩 컴포넌트 상속 ==상속이 반복되는 구조에서도 상속이 됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 39.6512%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot;&gt;병합 속성&lt;br /&gt;class, stayle 속성은 자동으로 병합됨&lt;br /&gt;그외 속성은 자식 우선 적용, 없으면 부모속성적용&lt;br /&gt;cf) 부모, 자식 컴포넌트에서 각각 id 지정시 자식 컴포넌트 정보를 따름.&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 39.6512%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot;&gt;이벤트속성 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;props, emits&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; 선언안할때&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 39.6512%;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;class=&quot;box&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;lt;slot &amp;gt;&amp;lt;/slot&amp;gt; &lt;/b&gt;&amp;lt;!--&amp;nbsp;부모가&amp;nbsp;넣는&amp;nbsp;콘텐츠&amp;nbsp;자리&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;lt;SimpleBox&amp;gt; &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;이&amp;nbsp;내용은&amp;nbsp;부모에서&amp;nbsp;넣었어요!&amp;lt;/p&amp;gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt; &amp;nbsp; &amp;nbsp; &amp;lt;p&amp;gt;여러줄 가능 {{click}} &amp;lt;/p&amp;gt;&lt;/b&gt; &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/SimpleBox&amp;gt;&lt;/b&gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;import&amp;nbsp;SimpleBox&amp;nbsp;from&amp;nbsp;'./components/SimpleBox.vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;SimpleBox&amp;nbsp;}&lt;br /&gt;&amp;nbsp; data(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;click:&amp;nbsp;&quot;클릭&quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;-------------------------결과&lt;br /&gt;&amp;lt;div&amp;nbsp;class=&quot;box&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;이&amp;nbsp;내용은&amp;nbsp;부모에서&amp;nbsp;넣었어요!&amp;lt;/p&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;여러줄 가능 클릭&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot;&gt;1.&amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;&lt;br /&gt;템플릿 구조를 자유도가 높게 구성&lt;br /&gt;- 컴포넌트 템플릿부분에서 다른 컴포넌트, html 요소 콘텐츠 동적으로 삽입위한 기능&lt;br /&gt;** 단일 루트요소일 필요 없음, 이벤트, 변수 모두 전달.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;2. v-slot&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;template&amp;nbsp;v-slot:top&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h3&amp;gt; 여긴 top slot&amp;lt;/h3&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;slot name=&quot;top&quot;&amp;gt;&amp;lt;/slot&amp;gt;&amp;nbsp; name 지정사용&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;3. 변경가능&lt;br /&gt;&amp;lt;!--&amp;nbsp;v-slot:header&amp;nbsp;&amp;rarr;&amp;nbsp;#header&amp;nbsp;로&amp;nbsp;줄여쓸&amp;nbsp;수&amp;nbsp;있어요&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;lt;template&amp;nbsp;#header&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;h2&amp;gt;제목&amp;lt;/h2&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;직역 : 구멍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.3255%;&quot;&gt;다이나믹 컴포넌트&lt;br /&gt;&lt;br /&gt;동적 렌더링&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 39.6512%;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h2&amp;gt;동적&amp;nbsp;컴포넌트&amp;nbsp;예제&amp;lt;/h2&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;@click=&quot;current&amp;nbsp;=&amp;nbsp;'One'&quot;&amp;gt;One&amp;nbsp;보기&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;@click=&quot;current&amp;nbsp;=&amp;nbsp;'Two'&quot;&amp;gt;Two&amp;nbsp;보기&amp;lt;/button&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;동적&amp;nbsp;컴포넌트&amp;nbsp;--&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;component&amp;nbsp;:is=&quot;current&quot;&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;import&amp;nbsp;One&amp;nbsp;from&amp;nbsp;'./components/One.vue' &lt;br /&gt;import&amp;nbsp;Two&amp;nbsp;from&amp;nbsp;'./components/Two.vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;One,&amp;nbsp;Two&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;data()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;current:&amp;nbsp;'One'&amp;nbsp;//&amp;nbsp;시작은&amp;nbsp;One&amp;nbsp;컴포넌트 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot;&gt;&amp;lt;component&amp;nbsp;:is=&quot;컴포넌트명&quot;&amp;nbsp;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button :class=&quot;{ active: 'One'== current}&quot; @click=&quot;toggleActive&quot;&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.3255%;&quot;&gt;provide&lt;/td&gt;
&lt;td style=&quot;width: 39.6512%;&quot; rowspan=&quot;2&quot;&gt;A.vue&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;larr;&amp;nbsp;provide&amp;nbsp;(상위&amp;nbsp;컴포넌트) &lt;br /&gt;└──&amp;nbsp;B.vue&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└──&amp;nbsp;C.vue&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└──&amp;nbsp;D.vue&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└──&amp;nbsp;E.vue&amp;nbsp;&amp;larr;&amp;nbsp;inject&amp;nbsp;(하위&amp;nbsp;컴포넌트) &lt;br /&gt;A.vue -----------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h1&amp;gt;A&amp;nbsp;컴포넌트&amp;lt;/h1&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;B&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;import&amp;nbsp;B&amp;nbsp;from&amp;nbsp;'./components/B.vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;B&amp;nbsp;}, &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;provide()&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sharedMessage: 'A에서 제공된 메시지입니다!' &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;E.vue ----------------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h5&amp;gt;E&amp;nbsp;컴포넌트&amp;lt;/h5&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;수신한&amp;nbsp;메시지:&amp;nbsp;{{&amp;nbsp;sharedMessage&amp;nbsp;}}&amp;lt;/p&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;inject:&amp;nbsp;['sharedMessage']&lt;/b&gt; &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot; rowspan=&quot;2&quot;&gt;데이터를 제공&lt;br /&gt;- 여러 컴포넌트를 상속하는구조일때 컴포넌트의 속성이아닌 privide - inject 를 이용해 빠르게 등록가능&lt;br /&gt;&lt;br /&gt;데이터를 주입 , 변수&amp;amp;함수 가능&lt;br /&gt;1. provide 하위관계에서만 주입가능&lt;br /&gt;2. 어플리케이션 단위 provide 사용.&amp;nbsp;&lt;br /&gt;main.js 에서&amp;nbsp; app 에 직접 provide 주입&lt;br /&gt;3. 객체 형태로 전달&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h5&amp;gt;E&amp;nbsp;컴포넌트&amp;lt;/h5&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;이름:&amp;nbsp;{{&amp;nbsp;member.name&amp;nbsp;}}&amp;lt;/p&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;나이:&amp;nbsp;{{&amp;nbsp;member.age&amp;nbsp;}}&amp;lt;/p&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;inject:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;member:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt; from: 'userInfo', // provide에서 받은 키- 키값 별도 js 로 관리가능&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;({&amp;nbsp;name:&amp;nbsp;'기본값',&amp;nbsp;age:&amp;nbsp;0&amp;nbsp;})&amp;nbsp;//&amp;nbsp;fallback &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}&lt;br /&gt;4. computed(반응형) 도 전달가능 -composition API&amp;nbsp; - vue에서 가져옴&lt;br /&gt;- 부모 컴포넌트 변경시 자식 자동업데이트가능&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;setup()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;count&amp;nbsp;=&amp;nbsp;ref(1) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;double&amp;nbsp;=&amp;nbsp;computed(()&amp;nbsp;=&amp;gt;&amp;nbsp;count.value&amp;nbsp;*&amp;nbsp;2) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;provide로&amp;nbsp;computed&amp;nbsp;값도&amp;nbsp;전달&amp;nbsp;가능 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;provide('doubleCount',&amp;nbsp;double) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;count&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.3255%;&quot;&gt;inject&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/282</guid>
      <comments>https://freewebsite1028.tistory.com/entry/vue-components-more#entry282comment</comments>
      <pubDate>Mon, 4 Aug 2025 16:06:19 +0900</pubDate>
    </item>
    <item>
      <title>[핵심만 골라 배우는 Vue.js by 수코딩] 6. 컴포넌트 기본- 스타일, 템플릿, 렌더함수</title>
      <link>https://freewebsite1028.tistory.com/entry/vue-components</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;컴포넌트 &amp;gt; 템플릿 &amp;gt; 렌더함수&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;nbsp;컴포넌트 정의 &amp;gt; 템플릿 작성(template) &amp;gt; 랜더 함수로 컴파일됨(rander function) &amp;gt; 가상 DOM 트리 생성 &amp;gt; 실제 DOM에 반영(mount)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;컴포넌트&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 225px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 9.30236%; height: 43px;&quot; rowspan=&quot;6&quot;&gt;컴포넌트&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90.6976%; height: 43px;&quot; colspan=&quot;3&quot;&gt;재사용 가능한 화면 단위 (UI 조각)&lt;br /&gt;Vue는 컴포넌트를 조립해서 &lt;b&gt;SPA ( Single Page Application 단일 페이지 애플리케이션)&lt;/b&gt; 을 만듬&lt;br /&gt;&lt;br /&gt;1. Vue 의 기본단위&amp;nbsp;&lt;br /&gt;2. HTML + JS +CSS&amp;nbsp; UI 블록&lt;br /&gt;&lt;br /&gt;장점&amp;nbsp;&lt;br /&gt;1. 재사용성 여러 곳에서 같은 UI/로직을 재사용 가능 Button, Modal, Card, ProductItem 등 &lt;br /&gt;2.&amp;nbsp;코드&amp;nbsp;분리&amp;nbsp;(관심사의&amp;nbsp;분리) UI&amp;nbsp;단위를&amp;nbsp;역할별로&amp;nbsp;나누어&amp;nbsp;관리 Header&amp;nbsp;/&amp;nbsp;Footer&amp;nbsp;/&amp;nbsp;Sidebar&amp;nbsp;컴포넌트&amp;nbsp;분리 &lt;br /&gt;3.&amp;nbsp;유지보수성&amp;nbsp;향상 하나의&amp;nbsp;컴포넌트만&amp;nbsp;수정하면&amp;nbsp;전체&amp;nbsp;반영 UserCard.vue만&amp;nbsp;수정하면&amp;nbsp;전체&amp;nbsp;사용자&amp;nbsp;카드&amp;nbsp;일괄&amp;nbsp;변경 &lt;br /&gt;4.&amp;nbsp;테스트&amp;nbsp;용이성 컴포넌트&amp;nbsp;단위로&amp;nbsp;유닛&amp;nbsp;테스트&amp;nbsp;가능 LoginForm.vue&amp;nbsp;단독&amp;nbsp;테스트 &lt;br /&gt;5.&amp;nbsp;구조적&amp;nbsp;설계&amp;nbsp;가능 트리&amp;nbsp;구조로&amp;nbsp;앱을&amp;nbsp;구성,&amp;nbsp;관리가&amp;nbsp;쉬움 App&amp;nbsp;&amp;rarr;&amp;nbsp;Layout&amp;nbsp;&amp;rarr;&amp;nbsp;Page&amp;nbsp;&amp;rarr;&amp;nbsp;Item&amp;nbsp;구조&amp;nbsp;등&lt;br /&gt;&lt;br /&gt;연결&lt;br /&gt;1. props : 부모-&amp;gt; 자식&lt;br /&gt;2. emit : 자식-&amp;gt; 부모&lt;br /&gt;3. v-model : 양방향&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 46px;&quot;&gt;
&lt;td style=&quot;width: 12.4418%; height: 46px;&quot;&gt;&lt;span&gt; 파일명 규칙 &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.2558%; height: 46px;&quot; colspan=&quot;2&quot;&gt;최소 2개의 단어연결&amp;nbsp; , 케이스는 프로젝트당 사용하는걸로.&amp;nbsp;&lt;br /&gt;MyComponent.vue&amp;nbsp; - 파스칼케이스&lt;br /&gt;my-component.vue - 케밥케이스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.4418%; height: 17px;&quot;&gt;&lt;span&gt;위치&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 78.2558%;&quot; colspan=&quot;2&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;components&lt;span&gt;&amp;nbsp;하위생성&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;150&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NlG72/btsPEtrHjuz/ZYIhhD5krnwl70s51je4tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NlG72/btsPEtrHjuz/ZYIhhD5krnwl70s51je4tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NlG72/btsPEtrHjuz/ZYIhhD5krnwl70s51je4tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNlG72%2FbtsPEtrHjuz%2FZYIhhD5krnwl70s51je4tk%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;150&quot; height=&quot;140&quot; data-origin-width=&quot;150&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.4418%;&quot; rowspan=&quot;3&quot;&gt;연결&lt;/td&gt;
&lt;td style=&quot;width: 78.2558%;&quot; colspan=&quot;2&quot;&gt;** 자기 자신을 컴포넌트로 재귀적으로 등록하면 루프(순환 참조) 오류&lt;br /&gt;&lt;br /&gt;import MyButton from './components/MyButton.vue' 하고&lt;br /&gt;import MyButton from '@/components/MyButton.vue' 하고 같음&lt;br /&gt;vite.config.js 에 설정&lt;br /&gt;
&lt;div style=&quot;background-color: #1f1f1f; color: #cccccc;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'@'&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;fileURLToPath&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;URL&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'./src'&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; },&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 51.6279%; height: 17px;&quot;&gt;import { createApp } from 'vue' &lt;br /&gt;import&amp;nbsp;App&amp;nbsp;from&amp;nbsp;'./App.vue' &lt;br /&gt;import&amp;nbsp;MyButton&amp;nbsp;from&amp;nbsp;'./components/MyButton.vue' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;app&amp;nbsp;=&amp;nbsp;createApp(App) &lt;br /&gt;app.component('MyButton',&amp;nbsp;MyButton)&amp;nbsp;&amp;nbsp;//&amp;nbsp;전역&amp;nbsp;등록 &lt;br /&gt;app.mount('#app') &lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MyButton&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%; height: 17px;&quot;&gt;&amp;nbsp;전역&amp;nbsp;등록&amp;nbsp;&lt;br /&gt;(Global&amp;nbsp;Registration)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 51.6279%; height: 17px;&quot;&gt;&amp;lt;!-- ParentComponent.vue --&amp;gt; &lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MyButton&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;import&amp;nbsp;MyButton&amp;nbsp;from&amp;nbsp;'./MyButton.vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyButton&amp;nbsp;&amp;nbsp;//&amp;nbsp;지역&amp;nbsp;등록 &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;or&amp;nbsp; &lt;br /&gt;&amp;lt;script&amp;nbsp;setup&amp;gt; &lt;br /&gt;import&amp;nbsp;MyButton&amp;nbsp;from&amp;nbsp;'./MyButton.vue'&amp;nbsp;//&amp;nbsp;지역&amp;nbsp;등록&amp;nbsp;(자동&amp;nbsp;인식) &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%; height: 17px;&quot;&gt;지역&amp;nbsp;등록&amp;nbsp;&lt;br /&gt;(Local&amp;nbsp;Registration)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 225px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.30236%;&quot; rowspan=&quot;5&quot;&gt;컴포넌트&amp;nbsp;&lt;br /&gt;사용&lt;/td&gt;
&lt;td style=&quot;width: 12.4418%;&quot; rowspan=&quot;4&quot;&gt;부모 -&amp;gt; 자식&lt;br /&gt;props&lt;/td&gt;
&lt;td style=&quot;width: 51.6279%;&quot;&gt;src/&lt;br /&gt;├──&amp;nbsp;App.vue&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;larr;&amp;nbsp;부모&amp;nbsp;컴포넌트&lt;br /&gt;└──&amp;nbsp;components/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└── InfoBox.vue&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;larr; 자식 컴포넌트&lt;br /&gt;&lt;br /&gt;App.vue --------------------------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h1&amp;gt;부모&amp;nbsp;컴포넌트&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; //1.&amp;nbsp; 문자열 전달&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;InfoBox title=&quot;공지사항입니다.&quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; //2.&amp;nbsp; 바인딩 전달&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;lt;InfoBox&amp;nbsp;:score=&quot;userScore&quot;&amp;nbsp;/&amp;gt;&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; //3.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;객체&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;lt;InfoBox&amp;nbsp;:profile=&quot;userProfile&quot;&amp;nbsp;/&amp;gt;&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;!-- 혼합 전달 --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;InfoBox&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title=&quot;사용자&amp;nbsp;정보&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:score=&quot;userScore&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:profile=&quot;userProfile&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;import&amp;nbsp;InfoBox&amp;nbsp;from&amp;nbsp;'./components/InfoBox.vue'&lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;InfoBox&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;data()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;userScore:&amp;nbsp;88,&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;userProfile:&amp;nbsp;{&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'홍길동',&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;age:&amp;nbsp;30&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;InfoBox.vue --------------------------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;class=&quot;box&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h2&amp;gt;자식&amp;nbsp;컴포넌트&amp;lt;/h2&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p v-if=&quot;title&quot;&amp;gt;[제목] {{ title }}&amp;lt;/p&amp;gt; // 공지사항입니다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;p v-if=&quot;score !== undefined&quot;&amp;gt;[점수] {{ score }}&amp;lt;/p&amp;gt;//88&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;p v-if=&quot;profile&quot;&amp;gt;[프로필] 이름: {{ profile.name }}, 나이: {{ profile.age }}&amp;lt;/p&amp;gt; // 홍길동 30&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;props:&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;String,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;score:&amp;nbsp;Number,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;profile:&amp;nbsp;Object&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;props 사용 &lt;br /&gt;&lt;br /&gt;1. 문자&lt;br /&gt;2. 바인딩 전달&lt;br /&gt;3. 객체전달&lt;br /&gt;4. mounted()&amp;nbsp;안에서는&amp;nbsp;props를&amp;nbsp;안전하게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다. &lt;br /&gt;5. 자식컴포넌트에서 수정 불가. 데이터 흐름 단방향성 유지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 51.6279%;&quot;&gt;props&lt;br /&gt;1. 정의 : 부모 &amp;rarr; 자식으로 데이터 전달하는 방법&lt;br /&gt;2. 목적 : 컴포넌틔 재사용성, 유현성 향상&lt;br /&gt;3. 주의 : 자식에서 직접 수정안됨. 읽기전용&lt;br /&gt;4. 선언방법&amp;nbsp;&lt;br /&gt;배열 : props: ['title'] &lt;br /&gt;&amp;lt;MyComponent&amp;nbsp;속성명1=&quot;값1&quot;&amp;nbsp;속성명2=&quot;값2&quot;&amp;nbsp;속성명N=&quot;값N&quot;&amp;nbsp;/&amp;gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;props:['속성명1',&amp;nbsp;'속성명2',&amp;nbsp;...'속성명N'] &lt;br /&gt;}&lt;br /&gt;&lt;b&gt;객체 : props: { title: {&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&amp;lt; 권장&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; type: String, &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; required: true,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 필수 여부 &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; default: '기본 제목',&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 기본값&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// 유효성 검사 &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; validator: value =&amp;gt; value.length &amp;lt;= 10&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // or&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//validator(value) { &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//&amp;nbsp; &amp;nbsp; return ['black', 'blue'].includes(value) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//}&lt;br /&gt;&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;},&lt;br /&gt;4. 사용&lt;br /&gt;템플릿 : {{ title }} or :style=&quot;{ backgroundColor: title }&quot; &lt;br /&gt;스크립트 : this.title &lt;br /&gt;mounted() : console.log(this.title)&lt;br /&gt;5. 유효성검사&lt;br /&gt;&amp;nbsp; - type, required, validator&amp;nbsp; &amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp; 개발자 콘솔&amp;nbsp; warning&amp;nbsp; 발생&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;props 와&lt;br /&gt;mounted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 51.6279%;&quot;&gt;&amp;lt;template&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h1&amp;gt;부모&amp;nbsp;컴포넌트&amp;lt;/h1&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;1번&amp;nbsp;InfoBox&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;InfoBox&amp;nbsp;bgcolor=&quot;red&quot;&amp;nbsp;size=&quot;3&quot;&amp;nbsp;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;2번&amp;nbsp;InfoBox&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;InfoBox&amp;nbsp;bgcolor=&quot;yellow&quot;&amp;nbsp;size=&quot;5&quot;&amp;nbsp;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;import&amp;nbsp;InfoBox&amp;nbsp;from&amp;nbsp;'./components/InfoBox.vue'&lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;InfoBox&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;-------------------------------------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;class=&quot;box&quot;&amp;nbsp;:style=&quot;{&amp;nbsp;backgroundColor:&amp;nbsp;bgcolor,&amp;nbsp;fontSize:&amp;nbsp;size&amp;nbsp;+&amp;nbsp;'rem'&amp;nbsp;}&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;배경색:&amp;nbsp;{{&amp;nbsp;bgcolor&amp;nbsp;}}&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;gt;글자&amp;nbsp;크기:&amp;nbsp;{{&amp;nbsp;size&amp;nbsp;}}rem&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;props:&amp;nbsp;['bgcolor',&amp;nbsp;'size'],&lt;br /&gt;&amp;nbsp;&amp;nbsp;mounted()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('✅&amp;nbsp;InfoBox&amp;nbsp;mounted')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(' &amp;nbsp;배경색:',&amp;nbsp;this.bgcolor)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(' &amp;nbsp;글자크기:',&amp;nbsp;this.size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;재사용이 가능한&lt;br /&gt;css 에 적용가능&lt;br /&gt;&lt;br /&gt;*&lt;span&gt;&amp;nbsp;&lt;/span&gt;mounted()&amp;nbsp;안에서는&amp;nbsp;props를&amp;nbsp;안전하게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. props&lt;br /&gt;{&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;bgcolor: tring,&lt;br /&gt;&amp;nbsp; size : string&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 51.6279%;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h2&amp;gt;부모&amp;nbsp;컴포넌트&amp;lt;/h2&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;lt;PropsChild&amp;nbsp;:onClickButton=&quot;handleChildClick&quot;&amp;nbsp;/&amp;gt;&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;import&amp;nbsp;PropsChild&amp;nbsp;from&amp;nbsp;'./components/PropsChild.vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;PropsChild&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;methods:&amp;nbsp;{ &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handleChildClick()&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert('부모&amp;nbsp;함수가&amp;nbsp;자식에&amp;nbsp;의해&amp;nbsp;실행됨!') &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------&lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h3&amp;gt;자식&amp;nbsp;컴포넌트&amp;lt;/h3&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;lt;button&amp;nbsp;@click=&quot;onClickButton&quot;&amp;gt;버튼&amp;nbsp;클릭&amp;lt;/button&amp;gt;&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;props:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClickButton:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type:&amp;nbsp;Function, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;required:&amp;nbsp;true &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;&lt;br /&gt;부모 -&amp;gt; 자식 &lt;br /&gt;1. 부모 컴포넌트에서 온 데이터 자식컴포넌트에서 수정불가.&amp;nbsp; props 읽기전용&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.4418%;&quot;&gt;자식-&amp;gt; 부모&lt;br /&gt;emits&lt;/td&gt;
&lt;td style=&quot;width: 51.6279%;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h2&amp;gt;부모&amp;nbsp;컴포넌트&amp;lt;/h2&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MessageChild&amp;nbsp;&lt;b&gt;@send-message=&quot;receiveMessage&quot;&amp;nbsp;&lt;/b&gt;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;import&amp;nbsp;MessageChild&amp;nbsp;from&amp;nbsp;'./components/MessageChild.vue' &lt;br /&gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;components:&amp;nbsp;{&amp;nbsp;MessageChild&amp;nbsp;}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;methods:&amp;nbsp;{ &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;receiveMessage(payload)&amp;nbsp;{ &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert('자식이&amp;nbsp;보낸&amp;nbsp;메시지:&amp;nbsp;'&amp;nbsp;+&amp;nbsp;payload) &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------- &lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h3&amp;gt;자식&amp;nbsp;컴포넌트&amp;lt;/h3&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&lt;b&gt;&amp;nbsp;@click=&quot;emitToParent&quot;&amp;gt;&lt;/b&gt;메시지&amp;nbsp;전송&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&lt;b&gt;&amp;nbsp;emits:&amp;nbsp;['send-message'],&amp;nbsp;&lt;/b&gt;// 이벤트 이름 명시적 선언, 생략가능&lt;br /&gt;&amp;nbsp;&amp;nbsp;methods:&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt; &amp;nbsp;emitToParent() {&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;this.$emit('send-message', '안녕하세요, 부모님!')// 두번째 부터 매개변수&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;&lt;br /&gt;부모 &amp;lt;- 자식 &lt;br /&gt;1. &lt;br /&gt;emit : 자식이 부모에게 결과를 알림, 자식컴포넌트 수정가능&amp;nbsp; =&amp;gt; 권장&lt;br /&gt;&lt;br /&gt;2. 인라인 실행가능&lt;br /&gt;&amp;lt;button @click=&quot;$emit('send-message', 'Hello inline emit!')&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;인라인&amp;nbsp;emit&amp;nbsp;실행 &lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.30236%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.4418%;&quot;&gt;양방향&lt;br /&gt;v-model&lt;/td&gt;
&lt;td style=&quot;width: 51.6279%;&quot;&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&lt;b&gt;&amp;nbsp;&amp;lt;ChildComp&amp;nbsp;v-model:title=&quot;title&quot;&amp;nbsp;v-model:content=&quot;content&quot;&amp;nbsp;/&amp;gt;&lt;/b&gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------- &lt;br /&gt;&amp;lt;template&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;label&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;제목: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;:value=&quot;title&quot; &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@input=&quot;$emit('update:title',&amp;nbsp;$event.target.value)&quot;&lt;/b&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/label&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;label&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;내용: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;textarea &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:value=&quot;content&quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@input=&quot;$emit('update:content',&amp;nbsp;$event.target.value)&quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;gt;&amp;lt;/textarea&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/label&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/template&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt; &lt;br /&gt;&lt;b&gt;props:&amp;nbsp;['title',&amp;nbsp;'content'], &lt;/b&gt;&lt;br /&gt;&lt;b&gt;emits:&amp;nbsp;['update:title',&amp;nbsp;'update:content']&lt;/b&gt;&lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;&lt;span&gt;1. v-model은 다음을 자동화해주는 &lt;b&gt;편의 문법&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;:value &amp;rarr; modelValue &lt;br /&gt;(또는 v-model:foo &amp;rarr; foo)&lt;br /&gt;@input &amp;rarr; @update:modelValue&lt;br /&gt;&lt;br /&gt;2. v-model 디렉티브 사용 수식어는 온전히 개발자가 직접 구현&lt;br /&gt;- &lt;a href=&quot;http://%20https://freewebsite1028.tistory.com/entry/vue-directive &quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;뷰 디렉티브&lt;/a&gt; 참고&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;스타일&lt;/h2&gt;
&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;4&quot;&gt;스타일&lt;/td&gt;
&lt;td colspan=&quot;3&quot;&gt;&lt;b&gt;1. 지역은 style scoped 속성 적용하여 사용.&amp;nbsp;&lt;br /&gt;2. 전역은 src/assets 폴더 하위 별도 css 파일만들고 src/main.js 파일에서 import 하여 적용.&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1. 외부스타일&lt;/td&gt;
&lt;td&gt;&lt;b&gt;//&amp;nbsp;main.js&lt;/b&gt;&lt;br /&gt;import&amp;nbsp;'./assets/main.css'&lt;/td&gt;
&lt;td&gt;모든 컴포넌트 전역적용&lt;br /&gt;공통, 초기화, reset.css&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. SFC 내부 스타일&lt;/td&gt;
&lt;td&gt;&amp;lt;template&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;class=&quot;box&quot;&amp;gt;Hello&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'MyComponent'&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&amp;lt;style&amp;nbsp;scoped&amp;gt;&lt;/b&gt;&lt;br /&gt;.box&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;color:&amp;nbsp;blue;&lt;br /&gt;}&lt;br /&gt;&lt;b&gt;&amp;lt;/style&amp;gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;전역 or 지역 (scoped)&lt;br /&gt;&lt;br /&gt;*&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&amp;lt;style scoped&amp;gt; 사용 안하면 정의 하지 않은 components 에도 적용됨 = 전역처리&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. 인라인 스타일&lt;/td&gt;
&lt;td&gt;&amp;lt;template&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;1.&amp;nbsp;기본&amp;nbsp;객체&amp;nbsp;형태&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&lt;b&gt;&amp;nbsp;:style=&quot;{&amp;nbsp;color:&amp;nbsp;'blue',&amp;nbsp;fontSize:&amp;nbsp;'18px'&amp;nbsp;}&lt;/b&gt;&quot;&amp;gt;기본&amp;nbsp;객체형&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;2.&amp;nbsp;data로&amp;nbsp;스타일&amp;nbsp;정의&amp;nbsp;후&amp;nbsp;바인딩&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;:style=&quot;&lt;b&gt;myStyle&lt;/b&gt;&quot;&amp;gt;data&amp;nbsp;스타일&amp;nbsp;바인딩&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;3.&amp;nbsp;여러&amp;nbsp;스타일&amp;nbsp;객체&amp;nbsp;배열로&amp;nbsp;적용&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;:style=&quot;[myStyle,&amp;nbsp;&lt;b&gt;yourStyle&lt;/b&gt;]&quot;&amp;gt;여러&amp;nbsp;스타일&amp;nbsp;합치기&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;4.&amp;nbsp;조건부&amp;nbsp;스타일&amp;nbsp;적용&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;:style=&quot;{&amp;nbsp;backgroundColor:&amp;nbsp;&lt;b&gt;isActive&amp;nbsp;&lt;/b&gt;?&amp;nbsp;'yellow'&amp;nbsp;:&amp;nbsp;'white'&amp;nbsp;}&quot;&amp;gt;조건부&amp;nbsp;스타일&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;5.&amp;nbsp;계산된&amp;nbsp;스타일&amp;nbsp;(computed)&amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;:style=&quot;&lt;b&gt;computedStyle&lt;/b&gt;&quot;&amp;gt;계산된&amp;nbsp;스타일&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;data()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;isActive&lt;/b&gt;:&amp;nbsp;true,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;myStyle&lt;/b&gt;:&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;color:&amp;nbsp;'red',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fontSize:&amp;nbsp;'20px'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;yourStyle&lt;/b&gt;:&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border:&amp;nbsp;'1px&amp;nbsp;solid&amp;nbsp;gray',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;padding:&amp;nbsp;'4px'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;computed:&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;computedStyle&lt;/b&gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;color:&amp;nbsp;this.isActive&amp;nbsp;?&amp;nbsp;'green'&amp;nbsp;:&amp;nbsp;'gray',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fontWeight:&amp;nbsp;'bold'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;td&gt;해당 요소에만 적용&lt;br /&gt;1.&amp;nbsp;기본&amp;nbsp;객체&amp;nbsp;형태&lt;br /&gt;2.&amp;nbsp;data로&amp;nbsp;스타일&amp;nbsp;정의&amp;nbsp;후&amp;nbsp;바인딩&lt;br /&gt;3.&amp;nbsp;여러&amp;nbsp;스타일&amp;nbsp;객체&amp;nbsp;배열로&amp;nbsp;적용&amp;nbsp;&lt;br /&gt;4.&amp;nbsp;조건부&amp;nbsp;스타일&amp;nbsp;적용&lt;br /&gt;5.&amp;nbsp;계산된&amp;nbsp;스타일&amp;nbsp;(computed)&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;뷰 컴포넌트 생성 &amp;amp; 등록&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 10%;&quot; rowspan=&quot;3&quot;&gt;뷰&amp;nbsp;컴포넌트&amp;nbsp;생성&amp;nbsp;&amp;amp;&amp;nbsp;등록&lt;/td&gt;
&lt;td style=&quot;width: 9.53488%;&quot; rowspan=&quot;2&quot;&gt;템플릿 &lt;br /&gt;속성&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.4652%;&quot; colspan=&quot;2&quot;&gt;컴포넌트의 내부 구조&lt;br /&gt;&lt;br /&gt;1. HTML 처럼 생긴 UI 정의 영역&lt;br /&gt;2. Vue 컴파일러가 이 템플릿을 렌더 함수로 변환함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 44.6512%;&quot;&gt;import&amp;nbsp;{&amp;nbsp;createApp&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue/dist/vue.esm-bundler.js' &lt;br /&gt;&lt;br /&gt;const app = createApp({&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;template&lt;/b&gt;:&amp;nbsp;`&amp;lt;div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;h1&amp;gt;{{&amp;nbsp;message&amp;nbsp;}}&amp;lt;/h1&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;@click=&quot;count++&quot;&amp;gt;Clicked&amp;nbsp;{{&amp;nbsp;count&amp;nbsp;}}&amp;nbsp;times&amp;lt;/button&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;`, &lt;br /&gt;&amp;nbsp;&amp;nbsp;data()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;message:&amp;nbsp;'Hello&amp;nbsp;from&amp;nbsp;runtime-compiled&amp;nbsp;template!', &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count:&amp;nbsp;0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;app.mount('#app')&lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE&amp;nbsp;html&amp;gt; &lt;br /&gt;&amp;lt;html&amp;nbsp;lang=&quot;en&quot;&amp;gt; &lt;br /&gt;&amp;lt;head&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;meta&amp;nbsp;charset=&quot;UTF-8&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;title&amp;gt;Vue&amp;nbsp;Runtime&amp;nbsp;Compile&amp;lt;/title&amp;gt; &lt;br /&gt;&amp;lt;/head&amp;gt; &lt;br /&gt;&amp;lt;body&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;id=&quot;app&quot;&amp;gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;script&amp;nbsp;type=&quot;module&quot;&amp;nbsp;src=&quot;/main.js&quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&amp;lt;/body&amp;gt; &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.814%;&quot;&gt;( 가능하지만 추천안함 )&lt;br /&gt;- 런타임 환경에서 컴파일은&lt;br /&gt;vue/dist/vue.esm-bundler 패키지 사용&lt;br /&gt;&lt;br /&gt;data, methods 도 가능&amp;nbsp;&lt;br /&gt;&lt;br /&gt;컴파일과정에서 (최초 주소호출시실행)&lt;br /&gt;SFC (Single File Component&amp;nbsp; &amp;nbsp;ex .vue) 형식의 파일은 vite에 의해 사전컴파일 런타임 환경에 제공&lt;br /&gt;&lt;br /&gt;template 속성은 런타임 환경에서 컴파일&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oZQzW/btsPF6vPnqe/s5NSe2xGhwgSkW94vGhZyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oZQzW/btsPF6vPnqe/s5NSe2xGhwgSkW94vGhZyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oZQzW/btsPF6vPnqe/s5NSe2xGhwgSkW94vGhZyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoZQzW%2FbtsPF6vPnqe%2Fs5NSe2xGhwgSkW94vGhZyk%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;223&quot; height=&quot;133&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.53488%;&quot;&gt;랜더 속성&lt;br /&gt;(render)&lt;/td&gt;
&lt;td style=&quot;width: 44.6512%;&quot;&gt;import&amp;nbsp;{&amp;nbsp;createApp,&amp;nbsp;h&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'vue' &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;MyComponent&amp;nbsp;=&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;props:&amp;nbsp;['msg'], &lt;br /&gt;&amp;nbsp;&amp;nbsp;render()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;h('div',&amp;nbsp;{&amp;nbsp;class:&amp;nbsp;'box'&amp;nbsp;},&amp;nbsp;[ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;h('h2',&amp;nbsp;`메시지:&amp;nbsp;${this.msg}`), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;h('button',&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;alert('버튼&amp;nbsp;클릭됨!') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&amp;nbsp;'클릭') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]) &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;const&amp;nbsp;app&amp;nbsp;=&amp;nbsp;createApp({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;render()&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;h(MyComponent,&amp;nbsp;{&amp;nbsp;msg:&amp;nbsp;'안녕하세요&amp;nbsp;Vue!'&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;app.mount('#app')&lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE&amp;nbsp;html&amp;gt; &lt;br /&gt;&amp;lt;html&amp;nbsp;lang=&quot;ko&quot;&amp;gt; &lt;br /&gt;&amp;lt;head&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;meta&amp;nbsp;charset=&quot;UTF-8&quot;&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;title&amp;gt;Vue&amp;nbsp;h()&amp;nbsp;렌더&amp;nbsp;예제&amp;lt;/title&amp;gt; &lt;br /&gt;&amp;lt;/head&amp;gt; &lt;br /&gt;&amp;lt;body&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;id=&quot;app&quot;&amp;gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;script&amp;nbsp;type=&quot;module&quot;&amp;nbsp;src=&quot;/main.js&quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&amp;lt;/body&amp;gt; &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.814%;&quot;&gt;(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;가능하지만 추천안함 )&lt;br /&gt;- 템플릿 컴파일러 필요없음(vue) 사용&lt;br /&gt;- h함수는 vue 에서 가져옴&lt;br /&gt;&lt;br /&gt;data, methods 도 가능&amp;nbsp; &lt;br /&gt;&lt;br /&gt;템플릿은 내부적으로 JS 함수(rander)로 바뀜&lt;br /&gt;이 함수는 Virtual DOM 트리를 생성함 &lt;br /&gt;&lt;br /&gt;랜더링되는 요소를 만들기 위한 함수h&lt;br /&gt;h(태그명, 태그의 속성, 자식요소)&lt;br /&gt;ex) &lt;br /&gt;h('div')&lt;br /&gt;h('div', null, 'hello') &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = &amp;lt;div&amp;gt;hello&amp;lt;/div&amp;gt; &lt;br /&gt;h('div', { class: 'red' }, 'hello')&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = &amp;lt;div class=&quot;red&quot;&amp;gt;hello&amp;lt;/div&amp;gt; &lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/281</guid>
      <comments>https://freewebsite1028.tistory.com/entry/vue-components#entry281comment</comments>
      <pubDate>Fri, 1 Aug 2025 18:00:44 +0900</pubDate>
    </item>
    <item>
      <title>[핵심만 골라 배우는 Vue.js by 수코딩] 5. 라이프사이클 훅</title>
      <link>https://freewebsite1028.tistory.com/entry/lifecycle-hook</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그림출처 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://vuejs.org/guide/essentials/lifecycle.html&quot;&gt;https://vuejs.org/guide/essentials/lifecycle.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;br /&gt;라이프사이클 훅&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.1628%;&quot; rowspan=&quot;17&quot;&gt;라이프사이클 훅&lt;br /&gt;&lt;br /&gt;lifecycle hook&lt;/td&gt;
&lt;td style=&quot;width: 88.8371%;&quot; colspan=&quot;4&quot;&gt;라이프사이클 훅은 브라우저가 Vue앱을 &quot;실행&quot;할 때&lt;br /&gt;&lt;br /&gt;Vue&amp;nbsp;컴포넌트가&amp;nbsp;생성되고,&amp;nbsp;DOM에&amp;nbsp;붙고,&amp;nbsp;갱신되고,&amp;nbsp;제거되는&amp;nbsp;과정&amp;nbsp;그&amp;nbsp;각&amp;nbsp;단계마다&amp;nbsp;호출되는&amp;nbsp;함수(훅,&amp;nbsp;hook)&lt;br /&gt;* hook&amp;nbsp; 낚시바늘&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot;&gt;진행순서&lt;/td&gt;
&lt;td style=&quot;width: 70.6976%;&quot; colspan=&quot;3&quot;&gt;npm run dev -&amp;gt; local : http://localhost:5173 -&amp;gt; 브라우저 주소 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot;&gt;호출방법&lt;/td&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;Options&amp;nbsp;API&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Composition API&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;공통설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'LifecycleDemo',&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;data()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;message:&amp;nbsp;'Hello&amp;nbsp;Vue!',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;beforeCreate()&amp;nbsp;{},&lt;br /&gt;&amp;nbsp;&amp;nbsp;created()&amp;nbsp;{},&lt;br /&gt;&amp;nbsp;&amp;nbsp;beforeMount()&amp;nbsp;{},&lt;br /&gt;&amp;nbsp;&amp;nbsp;mounted()&amp;nbsp;{},&lt;br /&gt;&amp;nbsp;&amp;nbsp;beforeUpdate()&amp;nbsp;{},&lt;br /&gt;&amp;nbsp;&amp;nbsp;updated()&amp;nbsp;{},&lt;br /&gt;&amp;nbsp;&amp;nbsp;beforeUnmount()&amp;nbsp;{},&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; // Vue 3&lt;br /&gt;&amp;nbsp;&amp;nbsp;unmounted() {},&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; // Vue 3&lt;br /&gt;&amp;nbsp; methods: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;updateMessage()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.message&amp;nbsp;=&amp;nbsp;'Updated!'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.6511%;&quot; colspan=&quot;2&quot;&gt;&amp;lt;script&amp;nbsp;setup&amp;gt;&lt;br /&gt;import&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;onBeforeMount,&amp;nbsp;onMounted,&lt;br /&gt;&amp;nbsp;&amp;nbsp;onBeforeUpdate,&amp;nbsp;onUpdated,&lt;br /&gt;&amp;nbsp;&amp;nbsp;onBeforeUnmount,&amp;nbsp;onUnmounted&lt;br /&gt;}&amp;nbsp;from&amp;nbsp;'vue'&lt;br /&gt;onBeforeMount(() =&amp;gt; console.log('beforeMount'))&lt;br /&gt;onMounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;console.log('mounted'))&lt;br /&gt;onBeforeUpdate(()&amp;nbsp;=&amp;gt;&amp;nbsp;console.log('beforeUpdate'))&lt;br /&gt;onUpdated(()&amp;nbsp;=&amp;gt;&amp;nbsp;console.log('updated'))&lt;br /&gt;onBeforeUnmount(()&amp;nbsp;=&amp;gt;&amp;nbsp;console.log('beforeUnmount'))&lt;br /&gt;onUnmounted(()&amp;nbsp;=&amp;gt;&amp;nbsp;console.log('unmounted'))&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;or&amp;nbsp;&lt;br /&gt;export&amp;nbsp;default&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;'LifecycleExample',&lt;br /&gt;&amp;nbsp; setup() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onBeforeMount(()&amp;nbsp;=&amp;gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('beforeMount')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})&lt;br /&gt;&amp;nbsp; &amp;nbsp; onMounted(() =&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('mounted')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})&lt;br /&gt;&amp;nbsp; &amp;nbsp; onBeforeUpdate(() =&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('beforeUpdate')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})&lt;br /&gt;&amp;nbsp; &amp;nbsp; onUpdated(() =&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('updated')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})&lt;br /&gt;&amp;nbsp; &amp;nbsp; onBeforeUnmount(() =&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('beforeUnmount')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})&lt;br /&gt;&amp;nbsp; &amp;nbsp; onUnmounted(() =&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log('unmounted')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})&lt;br /&gt;&amp;nbsp; &amp;nbsp; return {}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot;&gt;설명&lt;/td&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;Vue2 부터 사용&lt;br /&gt;vue 내부에서 자동사용&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Vue 3 새롭게 도입(권장)&lt;br /&gt;사용자가 직접&amp;nbsp; 사용&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot; rowspan=&quot;3&quot;&gt;creation( 생성 )&lt;/td&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;beforeCreate&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot; rowspan=&quot;3&quot;&gt;setup()&lt;br /&gt;: Vue가&amp;nbsp;Composition&amp;nbsp;API를&amp;nbsp;통해&amp;nbsp;개발자가&amp;nbsp;만든&amp;nbsp;반응형&amp;nbsp;상태를&amp;nbsp;로드하는&amp;nbsp;함수&lt;br /&gt;값은 return 으로 전달&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;인스턴스 초기화 전. data, props 사용 불가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Init Options API&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;created&lt;br /&gt;: 반응형 API 기반 객체 모두 준비&amp;nbsp;&lt;br /&gt;this. 접근가능&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;생성&amp;nbsp;후.&amp;nbsp;data,&amp;nbsp;props,&amp;nbsp;methods&amp;nbsp;접근&amp;nbsp;가능&lt;br /&gt;- 페이지 진입 시 사용자 정보 불러오기, 서버에서 목록 로딩 등&lt;br /&gt;* 일찍 로딩하는게 이득인 데이터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 70.6976%;&quot; colspan=&quot;3&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jco5q/btsPFETjqwA/wEXxmmBxneJXW7oVyKrzl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jco5q/btsPFETjqwA/wEXxmmBxneJXW7oVyKrzl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jco5q/btsPFETjqwA/wEXxmmBxneJXW7oVyKrzl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJco5q%2FbtsPFETjqwA%2FwEXxmmBxneJXW7oVyKrzl0%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;300&quot; height=&quot;167&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;br /&gt;&lt;/span&gt;템플릿이 이미 js 변환되었나?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;NO-&amp;gt; 실행중에 템플릿 컴파일&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;YES -&amp;gt; beforeMount 진행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot; rowspan=&quot;3&quot;&gt;mounting (연결)&lt;/td&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;beforeMount()&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;onBeforeMount()&lt;br /&gt;: setup 내부에서 사용&lt;br /&gt;this 사용불가&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;DOM에&amp;nbsp;붙기&amp;nbsp;전.&amp;nbsp;가상&amp;nbsp;DOM은&amp;nbsp;만들어짐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 70.6976%; height: 59px;&quot; colspan=&quot;3&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;171&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMUb4N/btsPDPBP8st/2PrZ52MD7XT5LOsuaNjR91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMUb4N/btsPDPBP8st/2PrZ52MD7XT5LOsuaNjR91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMUb4N/btsPDPBP8st/2PrZ52MD7XT5LOsuaNjR91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMUb4N%2FbtsPDPBP8st%2F2PrZ52MD7XT5LOsuaNjR91%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;224&quot; height=&quot;103&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;171&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;초기 랜더링 &amp;amp; DOM 노드 생성 및 삽입&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;mounted()&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;onMounted()&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;DOM에&amp;nbsp;붙은&amp;nbsp;후.&amp;nbsp;$el,&amp;nbsp;ref&amp;nbsp;접근&amp;nbsp;가능&lt;br /&gt;- 차트 그리기, 3rd-party 라이브러리 연동, focus 지정 등 dom 에 의존하는작업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot; rowspan=&quot;3&quot;&gt;updating(수정)&lt;br /&gt;&lt;b&gt;&lt;b&gt;사용자 사용중 상태&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70.6976%; height: 184px;&quot; colspan=&quot;3&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lIfbw/btsPFwnAHlg/Cjx05pc1U6dzrbR3cdEKpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lIfbw/btsPFwnAHlg/Cjx05pc1U6dzrbR3cdEKpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lIfbw/btsPFwnAHlg/Cjx05pc1U6dzrbR3cdEKpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlIfbw%2FbtsPFwnAHlg%2FCjx05pc1U6dzrbR3cdEKpK%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;365&quot; height=&quot;178&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;반응형 데이터가 바뀌면 Vue는 컴포넌트를 다시 렌더링하고, 변경된 부분만 DOM에 패치(수정)합니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;beforeUpdate()&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;onBeforeUpdate()&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;반응형&amp;nbsp;데이터&amp;nbsp;변경&amp;nbsp;&amp;rarr;&amp;nbsp;DOM&amp;nbsp;업데이트&amp;nbsp;직전&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;updated()&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;onUpdated()&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;DOM 업데이트 완료 후&lt;br /&gt;- 데이터 바뀔 때 UI 애니메이션 트리거 데이터가 갱신된 후 DOM 작업 필요할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.1395%;&quot; rowspan=&quot;2&quot;&gt;해제&lt;br /&gt;(unmounting)&lt;/td&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;beforeUnmount()&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;onBeforeUnmount()&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;컴포넌트&amp;nbsp;제거&amp;nbsp;직전&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.0465%;&quot;&gt;unmounted()&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;onUnmounted()&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;컴포넌트&amp;nbsp;제거&amp;nbsp;완료&amp;nbsp;후&lt;br /&gt;- WebSocket 연결 종료, 타이머 해제, 이벤트 제거, 서비스 종료 또는 페이지 이탈 시 정리 작업&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web</category>
      <author>Sweat100</author>
      <guid isPermaLink="true">https://freewebsite1028.tistory.com/280</guid>
      <comments>https://freewebsite1028.tistory.com/entry/lifecycle-hook#entry280comment</comments>
      <pubDate>Fri, 1 Aug 2025 17:07:30 +0900</pubDate>
    </item>
  </channel>
</rss>