<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>맨땅에 ho-ding</title>
    <link>https://ho-ding.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 13 Aug 2026 17:35:28 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>hojun</managingEditor>
    <item>
      <title>[VUE] Vue.js 자주 사용하는 ES6 문법 정리</title>
      <link>https://ho-ding.tistory.com/89</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;화살표 함수 (Arrow function)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 함수에서는 this를 사용, 화살표 함수에서는 this없이 사용&lt;/li&gt;
&lt;li&gt;함수 로직이 한 줄이면 { } 생략 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1743597498460&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
    // ES5 일반 함수 문법
    function fncES5(val) {
        console.log(val);
    }
    // ES6 화살표 함수 문법
    const fncES6_1 = (val) =&amp;gt; {
        console.log(val);
    }

    // 함수 로직이 1줄이면 {} 생략 가능
    const fncES6_2 = (val) =&amp;gt; console.log(val);
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 템플릿 리터럴 (Template literals)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;백틱( ` ) 을 사용&lt;/li&gt;
&lt;li&gt;문자열과 자바스크립트 표현식 혼용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1743598060271&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
    let text = 'ES6!';
    
    const fncES6 = () =&amp;gt; {
        console.log(`Hello, ${text}`);  // Hello, ES6!
    }     
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 모듈 (Modules)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;import, expert 문법 사용&lt;/li&gt;
&lt;li&gt;다른 js 파일에서 파일 내용을 가져옴&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1743599197397&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// component.js
const  component = {
    fncES6() {
        console.log('hello, ES6!');
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1743599333338&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;!-- vue --&amp;gt;
&amp;lt;script setup&amp;gt;
    import es6Comp  from './component.js'
    es6Comp.fncES6();   // hello, ES6!
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 분해와 확장 문법&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분해 문법은 { , } 사용&lt;/li&gt;
&lt;li&gt;확장 문법은&amp;nbsp; ... 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1743600018399&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
    let obj = {
        prop1 : 'hello, ',
        prop2 : 'ES5!',
        prop3 : 'hello, ',
        prop4 : 'ES6!',
    }

    // ES5 분해 문법
    const prop1 = obj.prop1;
    const prop2 = obj.prop2;

    // ES6 분해 문법
    const {prop3, prop4} = obj;
    
    console.log(prop1 + prop2); // hello, ES5!
    console.log(prop3 + prop4); // hello, ES6!
    
    // ES5 확장 문법
    let objES5 = {
        name : 'Alice',
        prop1 : obj.prop1,
        prop2 : obj.prop2
    }

    console.log(objES5.prop1 + objES5.name); // hello, Alice

    // ES6 확장 문법
    let objES6 = {
        name : 'John',
        ...obj  
    }

    console.log(objES6.prop3 + objES6.name) // hello, John
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/VUE</category>
      <category>arrow function</category>
      <category>ES6</category>
      <category>modules</category>
      <category>template literals</category>
      <category>Vue</category>
      <category>Vue3</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/89</guid>
      <comments>https://ho-ding.tistory.com/89#entry89comment</comments>
      <pubDate>Wed, 2 Apr 2025 22:38:48 +0900</pubDate>
    </item>
    <item>
      <title>[VUE] Composition API - axios</title>
      <link>https://ho-ding.tistory.com/88</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Composition API에서 axios를 사용하는 기본적인 방법을 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  ref, onMounted를 활용한 axios.get&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1743170499261&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;jsonplaceholder REST API axios.get&amp;lt;/h2&amp;gt;
    &amp;lt;p v-if=&quot;loading&quot;&amp;gt;Loading...&amp;lt;/p&amp;gt;
    &amp;lt;p v-else-if=&quot;error&quot;&amp;gt;Error : {{ error }}&amp;lt;/p&amp;gt;
    &amp;lt;pre v-else&amp;gt;{{ data }}&amp;lt;/pre&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { ref, onMounted } from 'vue';
    import axios from 'axios';

    const data = ref(null);
    const loading = ref(true);
    const error = ref(null);
    
    async function fetchData() {
        try {
            const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
            data.value = response.data;
        } catch(err) {
            error.value = err.message;
        } finally {
            loading.value = false;
        }
    }

    onMounted(fetchData);
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ &lt;/b&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1004&quot; data-start=&quot;822&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;873&quot; data-start=&quot;822&quot;&gt;onMounted()에서 fetchData()를 호출하여 API 데이터를 가져옴&lt;/li&gt;
&lt;li data-end=&quot;923&quot; data-start=&quot;874&quot;&gt;ref()를 활용해 data, loading, error 상태를 관리&lt;/li&gt;
&lt;li data-end=&quot;958&quot; data-start=&quot;924&quot;&gt;axios.get(url)을 통해 비동기 요청을 실행&lt;/li&gt;
&lt;li data-end=&quot;1004&quot; data-start=&quot;959&quot;&gt;try-catch-finally를 사용하여 오류 처리 및 로딩 상태 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&amp;nbsp;결과&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;822&quot; data-end=&quot;1004&quot;&gt;
&lt;li data-end=&quot;3869&quot; data-start=&quot;3823&quot;&gt;axios 성공 여부에 따른 responMessage 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzLEl1/btsM19n5VRr/gXNI1uF8fvkf5roMCVWhe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzLEl1/btsM19n5VRr/gXNI1uF8fvkf5roMCVWhe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzLEl1/btsM19n5VRr/gXNI1uF8fvkf5roMCVWhe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzLEl1%2FbtsM19n5VRr%2FgXNI1uF8fvkf5roMCVWhe0%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;945&quot; height=&quot;183&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;ref 를 활용한 axios.post&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1743259966800&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;jsonplaceholder REST API axios.post&amp;lt;/h2&amp;gt;
    &amp;lt;input v-model=&quot;title&quot; placeholder=&quot;title&quot; /&amp;gt;
    &amp;lt;textarea v-model=&quot;body&quot; placeholder=&quot;body&quot;&amp;gt;&amp;lt;/textarea&amp;gt;
    &amp;lt;button @click=&quot;sendData&quot;&amp;gt;submit&amp;lt;/button&amp;gt;
    &amp;lt;p&amp;gt;{{ responMessage }}&amp;lt;/p&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { ref } from 'vue';
    import axios from 'axios';

    const title = ref('');
    const body = ref('');
    const responMessage = ref(null);
    
    async function sendData() {
        try {
            const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
                title: title.value,
                body : body.value,
                userId : 1
            })
            responMessage.value = `Post created with ID: ${response.data.id}`;
        } catch (err) {
            responMessage.value = `Error: ${err.message}`;
        }
    }

&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;822&quot; data-end=&quot;1004&quot;&gt;
&lt;li data-end=&quot;3869&quot; data-start=&quot;3823&quot;&gt;v-model을 사용해 사용자 입력을 받아 axios.post() 실행&lt;/li&gt;
&lt;li data-end=&quot;3902&quot; data-start=&quot;3870&quot;&gt;응답 메시지를 responseMessage에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&amp;nbsp;결과&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1004&quot; data-start=&quot;822&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start=&quot;3823&quot; data-end=&quot;3869&quot;&gt;button submit 후 axios 성공 여부에 따른 responMessage 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/badUHn/btsM19hyZJp/SW7MSRBRmFLoisDUmpvyT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/badUHn/btsM19hyZJp/SW7MSRBRmFLoisDUmpvyT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/badUHn/btsM19hyZJp/SW7MSRBRmFLoisDUmpvyT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbadUHn%2FbtsM19hyZJp%2FSW7MSRBRmFLoisDUmpvyT0%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;949&quot; height=&quot;217&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/VUE</category>
      <category>axios</category>
      <category>Composition</category>
      <category>GET</category>
      <category>jsonplaceholder</category>
      <category>post</category>
      <category>rest api</category>
      <category>Vue</category>
      <category>Vue3</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/88</guid>
      <comments>https://ho-ding.tistory.com/88#entry88comment</comments>
      <pubDate>Sun, 30 Mar 2025 00:02:39 +0900</pubDate>
    </item>
    <item>
      <title>[VUE] Composition API - provide, inject</title>
      <link>https://ho-ding.tistory.com/87</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Composition API에서 provide와 inject는 부모 컴포넌트에서 데이터를 제공(provide)하고, 하위 컴포넌트에서 이를 주입(inject)받아 사용할 수 있도록 하는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; provide와 inject의 핵심 개념&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;327&quot; data-start=&quot;163&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;211&quot; data-start=&quot;163&quot;&gt;&lt;b&gt;provide(key, value)&lt;/b&gt;: 부모 컴포넌트에서 데이터를 제공&lt;/li&gt;
&lt;li data-end=&quot;272&quot; data-start=&quot;212&quot;&gt;&lt;b&gt;inject(key, default value(없이도 사용 가능) )&lt;/b&gt;: 자식 컴포넌트에서 데이터를 주입받아 사용&lt;/li&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;273&quot;&gt;깊은 컴포넌트 트리에서도 데이터를 쉽게 전달 가능 (props를 여러 단계 거칠 필요 없음)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; provide, inject 기본 사용 방법&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 부모 컴포넌트에서 데이터 제공 (provide) &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743156124842&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- parentComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;parentComponent&amp;lt;/h2&amp;gt;
    &amp;lt;childComponent /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { provide, ref } from 'vue'
    import childComponent from './childComponent.vue'

    const message = ref('parent message')
    
    // provide로 자식 컴포넌트에 데이터를 제공
    provide('requestMessage', message)
    
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt; 자식 컴포넌트에서 데이터 주입 (inject) &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743156238197&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- childComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;childComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;receive message : {{ requestMessage }}&amp;lt;/p&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { inject } from 'vue';

    // inject로 부모 컴포넌트의 데이터를 주입
    const requestMessage = inject('requestMessage')
    
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 결과(parentComponent.vue)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 컴포넌트의 requstMessage를 받아와 자식 컴포넌트 내 Received message 영역에서 'parent message' 를 출력합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/95fnC/btsMZIMsjKz/60kvd4ocpCibO6FKVBQlgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/95fnC/btsMZIMsjKz/60kvd4ocpCibO6FKVBQlgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/95fnC/btsMZIMsjKz/60kvd4ocpCibO6FKVBQlgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F95fnC%2FbtsMZIMsjKz%2F60kvd4ocpCibO6FKVBQlgk%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;528&quot; height=&quot;225&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 반응형 데이터 전달 (provide + reactive or ref)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1217&quot; data-start=&quot;1179&quot; data-ke-size=&quot;size16&quot;&gt;provide는 반응형 상태를 그대로 전달할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1217&quot; data-start=&quot;1179&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 부모 컴포넌트에서 데이터 제공 (provide + ref)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743157204380&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- parentComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;parentComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
    &amp;lt;button @click=&quot;increment&quot;&amp;gt;증가&amp;lt;/button&amp;gt;
    &amp;lt;childComponent /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { provide, ref } from 'vue';
    import childComponent from './childComponent.vue';

    const count = ref(0);

    // provide로 자식 컴포넌트에 데이터를 제공
    provide('count', count);

    // count를 증가시키는 함수
    function increment() {
        count.value++;
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;자식 컴포넌트에서 데이터 주입 (inject)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743157243819&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- childComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;childComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;count from parent : {{ count }}&amp;lt;/p&amp;gt; 
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { inject } from 'vue';

    // inject로 부모 컴포넌트의 데이터를 주입
    const count = inject('count')
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 결과(parentComponent.vue)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 컴포넌트의 증가 버튼을 눌러 count가 증가하면 자식 컴포넌트에도 즉시 반영됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CI6WU/btsM2gHqKiQ/2kOLlX890jWiaJHYmnRWFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CI6WU/btsM2gHqKiQ/2kOLlX890jWiaJHYmnRWFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CI6WU/btsM2gHqKiQ/2kOLlX890jWiaJHYmnRWFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCI6WU%2FbtsM2gHqKiQ%2F2kOLlX890jWiaJHYmnRWFk%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;591&quot; height=&quot;202&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; inject 기본값 설정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2158&quot; data-start=&quot;2082&quot; data-ke-size=&quot;size16&quot;&gt;만약 부모에서 provide하지 않았다면 inject 시 undefined가 될 수 있습니다.&lt;br /&gt;이때 기본값을 설정할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2158&quot; data-start=&quot;2082&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2158&quot; data-start=&quot;2082&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 부모 컴포넌트에서 데이터 &lt;span style=&quot;color: #ee2323;&quot;&gt;미제공&lt;/span&gt; (&lt;s&gt;provide&lt;/s&gt; + ref)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743157985498&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- parentComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;parentComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
    &amp;lt;button @click=&quot;increment&quot;&amp;gt;증가&amp;lt;/button&amp;gt;
    &amp;lt;childComponent /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { ref } from 'vue';
    import childComponent from './childComponent.vue';

    const count = ref(0);

    // provide로 자식 컴포넌트에 데이터를 미제공
    // provide('count', count);

    // count를 증가시키는 함수
    function increment() {
        count.value++;
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;자식 컴포넌트에서 데이터 주입 (inject)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743158048769&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- childComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;childComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;count from parent : {{ count }}&amp;lt;/p&amp;gt; 
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { inject } from 'vue';

    // inject로 부모 컴포넌트의 데이터를 주입
    const count = inject('count', 123) // default value로 123을 설정
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 결과(parentComponent.vue)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 컴포넌트에서 provide를 제공하지 않아 자식 컴포넌트에서 설정한 디폴트 값인 123 이 출력됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWRlVF/btsMZpTW1WG/gipHsap216GGsqtHbVGx71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWRlVF/btsMZpTW1WG/gipHsap216GGsqtHbVGx71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWRlVF/btsMZpTW1WG/gipHsap216GGsqtHbVGx71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWRlVF%2FbtsMZpTW1WG%2FgipHsap216GGsqtHbVGx71%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;471&quot; height=&quot;252&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2537&quot; data-start=&quot;2514&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; provide 함수 전달&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2581&quot; data-start=&quot;2538&quot; data-ke-size=&quot;size16&quot;&gt;단순한 값뿐만 아니라 함수도 provide를 통해 전달할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2581&quot; data-start=&quot;2538&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2581&quot; data-start=&quot;2538&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 부모 컴포넌트에서 데이터&lt;span&gt;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제공&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;(provide&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ ref)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743158543756&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- parentComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;parentComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
    &amp;lt;button @click=&quot;increment&quot;&amp;gt;증가&amp;lt;/button&amp;gt;
    &amp;lt;childComponent /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { provide, ref } from 'vue';
    import childComponent from './childComponent.vue';

    const count = ref(0);

    
    provide('count', count); // provide로 자식 컴포넌트에 데이터를 제공
    provide('increment', increment) // provide로 자식 컴포넌트에 함수 제공

    // count를 증가시키는 함수
    function increment() {
        count.value++;
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;자식 컴포넌트에서 데이터 주입 (inject)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743158569632&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- childComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;childComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;count from parent : {{ count }}&amp;lt;/p&amp;gt; 
    &amp;lt;button @click=&quot;increment&quot;&amp;gt;증가(부모 함수)&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { inject } from 'vue';

    const count = inject('count'); // inject로 부모 컴포넌트의 데이터를 주입
    const increment = inject('increment'); // inject로 부모 컴포넌트의 함수 주입
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 결과(parentComponent.vue)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식 컴포넌트에서도 부모가 제공한 increment() 함수를 실행하여 count를 변경할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwlyRq/btsMZ6M7UPm/qke5E9T4LaGdtCtnuP92zK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwlyRq/btsMZ6M7UPm/qke5E9T4LaGdtCtnuP92zK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwlyRq/btsMZ6M7UPm/qke5E9T4LaGdtCtnuP92zK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwlyRq%2FbtsMZ6M7UPm%2Fqke5E9T4LaGdtCtnuP92zK%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;572&quot; height=&quot;190&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; provide, inject 글로벌 상태 관리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;3561&quot; data-start=&quot;3494&quot; data-ke-size=&quot;size16&quot;&gt;Composition API에서 provide와 inject를 사용하면 간단한 글로벌 상태 관리가 가능합니다.&lt;b&gt;&lt;/b&gt;&lt;br /&gt;부모 &amp;rarr; 자식&amp;rarr; 손자 컴포넌트로 전달이 가능합니다.&lt;/p&gt;
&lt;p data-end=&quot;3624&quot; data-start=&quot;3563&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3624&quot; data-start=&quot;3563&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 부모 컴포넌트에서 데이터&lt;span&gt;&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;제공&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;(provide)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743159983241&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- parentComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;parentComponent&amp;lt;/h2&amp;gt;
    &amp;lt;childComponent /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { provide, ref } from 'vue'
    import childComponent from './childComponent.vue'

    const message = ref('parent message')
    
    // provide로 자식 컴포넌트에 데이터를 제공
    provide('requestMessage', message)
    
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;자식 컴포넌트에서 데이터 &lt;span style=&quot;color: #ee2323;&quot;&gt;미주입&lt;/span&gt; (&lt;s&gt;inject&lt;/s&gt;)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743160011237&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- childComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;childComponent&amp;lt;/h2&amp;gt;
    
    &amp;lt;!-- 손자 컴포넌트 --&amp;gt;
    &amp;lt;grandChildComponent /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import grandChildComponent from './grandChildComponent.vue';
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&lt;span&gt;&lt;span&gt;&amp;nbsp;손자&lt;/span&gt;&amp;nbsp;컴포넌트에서 데이터&lt;span&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;주입&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(&lt;span style=&quot;color: #000000;&quot;&gt;inject&lt;/span&gt;)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743160030249&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- grandChildComponent.vue --&amp;gt;
&amp;lt;template&amp;gt;
    &amp;lt;h2&amp;gt;grandChildComponent&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;receive message : {{ requestMessage }}&amp;lt;/p&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
    import { inject } from 'vue';

    // 부모 컴포넌트에서 provide된 데이터를 자식 컴포넌트에서 사용하지 않고 손자 컴포넌트에서 inject
    const requestMessage = inject('requestMessage');
    
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 결과(parentComponent.vue)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 컴포넌트에서 제공한 데이터를 자식 컴포넌트에서 inject 하지 않고 손자 컴포넌트에서 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BLFDA/btsM2cSCDKv/k1sQkLKfur09Bji5O4VXtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BLFDA/btsM2cSCDKv/k1sQkLKfur09Bji5O4VXtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BLFDA/btsM2cSCDKv/k1sQkLKfur09Bji5O4VXtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBLFDA%2FbtsM2cSCDKv%2Fk1sQkLKfur09Bji5O4VXtK%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;488&quot; height=&quot;257&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 정리&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;5066&quot; data-start=&quot;4808&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;기능&lt;/td&gt;
&lt;td&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4880&quot; data-start=&quot;4836&quot;&gt;
&lt;td&gt;provide(key, value)&lt;/td&gt;
&lt;td&gt;부모 컴포넌트에서 데이터 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4932&quot; data-start=&quot;4881&quot;&gt;
&lt;td&gt;inject(key, defaultValue?)&lt;/td&gt;
&lt;td&gt;자식 컴포넌트에서 데이터 주입&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4985&quot; data-start=&quot;4933&quot;&gt;
&lt;td&gt;반응형 데이터 전달&lt;/td&gt;
&lt;td&gt;ref 또는 reactive로 선언한 데이터를 전달 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5028&quot; data-start=&quot;4986&quot;&gt;
&lt;td&gt;함수 제공&lt;/td&gt;
&lt;td&gt;provide로 함수를 전달하여 자식에서 실행 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5066&quot; data-start=&quot;5029&quot;&gt;
&lt;td&gt;기본값 설정&lt;/td&gt;
&lt;td&gt;inject에서 기본값을 설정할 수 있음&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>프로그래밍/VUE</category>
      <category>Composition</category>
      <category>inject</category>
      <category>PROVIDE</category>
      <category>Vue</category>
      <category>Vue3</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/87</guid>
      <comments>https://ho-ding.tistory.com/87#entry87comment</comments>
      <pubDate>Fri, 28 Mar 2025 20:22:03 +0900</pubDate>
    </item>
    <item>
      <title>[VUE] Composition API - toRef, toRefs</title>
      <link>https://ho-ding.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;reactive로 만든 객체는 반응형이지만 개별 속성을 구조 분해 할당하면 반응형을 잃어버릴 수 있습니다.&lt;br /&gt;이를 방지하기 위해 &lt;b&gt;toRef&lt;/b&gt;와 &lt;b&gt;toRefs&lt;/b&gt;를 사용하여 개별 속성을 ref로 변환할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; toRef 사용 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;227&quot; data-ke-size=&quot;size16&quot;&gt;toRef는 reactive 객체의 &lt;b&gt;특정 속성을 ref로 변환&lt;/b&gt;합니다.&lt;br /&gt;이렇게 하면 .value 없이 reactive 객체처럼 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742994466010&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
    &amp;lt;button @click=&quot;increment&quot;&amp;gt;증가&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

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

    const state = reactive({ 
        count : 0,
        name : 'John'
    });
    
    // state.count를 개별 ref로 변환
    const count = toRef(state, 'count');

    const increment = () =&amp;gt; {
        count.value++; // toRef를 사용했으므로 ref처럼 .value를 사용할 수 있음
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;227&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;227&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;227&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ toRef가 사용 이유&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start=&quot;839&quot; data-end=&quot;885&quot;&gt;reactive 객체의 속성을 직접 구조 분해 하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;반응형이 사라짐&lt;/li&gt;
&lt;li data-start=&quot;886&quot; data-end=&quot;925&quot;&gt;toRef를 사용하면 해당 속성을 ref로 유지할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1742994511566&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
    &amp;lt;button @click=&quot;increment&quot;&amp;gt;증가&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

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

    const state = reactive({ 
        count : 0
    });
    
    const count = state.count; // 반응형이 깨짐 (count는 그냥 숫자가 됨)

    const increment = () =&amp;gt; {
        count.value++; // count의 속성이 number가 되어 .value를 사용할 수 없음
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;227&quot; 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;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; toRefs 사용 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1050&quot; data-start=&quot;955&quot; data-ke-size=&quot;size16&quot;&gt;toRefs는 reactive 객체의 &lt;b&gt;모든 속성을 ref로 변환&lt;/b&gt;합니다.&lt;br /&gt;toRef를 여러 번 사용할 필요 없이 한 번에 변환할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742995035588&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;p&amp;gt;이름 : {{ name }}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;나이 : {{ age }}&amp;lt;/p&amp;gt;
    &amp;lt;button @click=&quot;updateAge&quot;&amp;gt;나이 변경&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

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

    const state = reactive({ 
        name : &quot;John&quot;,
        age : 35
    });
    
    // state의 모든 속성을 ref로 변환
    const { name, age } = toRefs(state);

    const updateAge = () =&amp;gt; {
        age.value = 17; // age가 toRefs로 인해 ref로 변환되어 .value 사용 가능
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ toRefs가 사용 이유&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;885&quot; data-start=&quot;839&quot;&gt;reactive 객체의 속성을 직접 구조 분해 하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;반응형이 사라짐&lt;/li&gt;
&lt;li data-end=&quot;925&quot; data-start=&quot;886&quot;&gt;toRef를 사용하면 모든 속성을 ref로 유지할 수 있음&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; toRef, toRefs 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1921&quot; data-start=&quot;1722&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;속성&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;toRef&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;toRefs&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1804&quot; data-start=&quot;1779&quot;&gt;
&lt;td&gt;&lt;b&gt;변환 대상&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;특정 속성&lt;/td&gt;
&lt;td&gt;모든 속성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1853&quot; data-start=&quot;1805&quot;&gt;
&lt;td&gt;&lt;b&gt;반환 타입&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;ref (단일 값)&lt;/td&gt;
&lt;td&gt;{ [key]: ref } (객체)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1921&quot; data-start=&quot;1854&quot;&gt;
&lt;td&gt;&lt;b&gt;사용 사례&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;특정 속성만 ref로 변환할 때&lt;/td&gt;
&lt;td&gt;reactive 객체 전체 속성을 ref로 변환할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;</description>
      <category>프로그래밍/VUE</category>
      <category>Composition</category>
      <category>toref</category>
      <category>torefs</category>
      <category>Vue</category>
      <category>Vue3</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/86</guid>
      <comments>https://ho-ding.tistory.com/86#entry86comment</comments>
      <pubDate>Wed, 26 Mar 2025 22:24:17 +0900</pubDate>
    </item>
    <item>
      <title>[VUE] Composition API - ref, reactive</title>
      <link>https://ho-ding.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Composition API에서 ref와 reactive는 반응형 상태를 만들기 위해 사용됩니다. 두 속성은 동작 방식과 사용법에 차이가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의-1&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ref (단일 값 또는 객체를 감싸는 반응형 래퍼)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;580&quot; data-ke-size=&quot;size16&quot;&gt;ref는 기본 자료형(&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;number, string, boolean 등&lt;/span&gt;) 또는 객체를 감싸서 반응형으로 만듭니다.&lt;/p&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;580&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;580&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ ref 예제 (기본 자료형) &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742986206023&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
        &amp;lt;button @click=&quot;increment&quot;&amp;gt;count 증가&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

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

    const count = ref(0); // 숫자형 타입

    // 값 증가
    const increment = () =&amp;gt; {
        count.value++; // .value를 사용해야 함
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ ref 예제 (객체)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742986746755&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;나이 : {{ user.age }}&amp;lt;/p&amp;gt;
        &amp;lt;button @click=&quot;updateAge&quot;&amp;gt;나이 변경&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

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

    const user = ref({
        name : 'james',
        age : 15
    })

    // 나이 변경
    const updateAge = () =&amp;gt; {
        user.value.age = 29; // 객체 안의 속성도 반응형
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ ref 특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1307&quot; data-start=&quot;1238&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1264&quot; data-start=&quot;1238&quot;&gt;.value를 사용해야 값에 접근 가능&lt;/li&gt;
&lt;li data-end=&quot;1307&quot; data-start=&quot;1265&quot;&gt;객체를 감쌀 수도 있지만, reactive보다 덜 직관적일 수 있음&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의-1&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; reactive (객체나 배열의 반응형 상태)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1423&quot; data-start=&quot;1349&quot; data-ke-size=&quot;size16&quot;&gt;reactive는 객체와 배열을 반응형으로 만듭니다. &lt;b&gt;기본 타입(&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;number, string, boolean&lt;/span&gt;&lt;/b&gt; 등)은 reactive로 만들 수 없습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1423&quot; data-start=&quot;1349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1423&quot; data-start=&quot;1349&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ reactive 예제 (객체)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742988716002&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;나이 : {{ user.age }}&amp;lt;/p&amp;gt;
        &amp;lt;button @click=&quot;updateAge&quot;&amp;gt;나이 변경&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

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

    const user = reactive({
        name : 'James',
        age : 15
    })

    // 값 변경
    const updateAge = () =&amp;gt; {
        user.age = 29;    // .value 필요 없음
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ reactive 예제 (배열)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742991649370&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;ul&amp;gt;
        &amp;lt;li v-for=&quot;item in items&quot; :key=&quot;item&quot;&amp;gt;{{ item }}&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
    &amp;lt;button @click=&quot;addItem&quot;&amp;gt;추가&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

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

    const items = reactive([&quot;James&quot;, &quot;Bob&quot;]);

    // 값 추가
    const addItem = () =&amp;gt; {
        items.push(&quot;Emma&quot;); // 반응형
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ reactive 특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2212&quot; data-start=&quot;2116&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2149&quot; data-start=&quot;2116&quot;&gt;.value를 사용하지 않고 직접 속성에 접근 가능&lt;/li&gt;
&lt;li data-end=&quot;2173&quot; data-start=&quot;2150&quot;&gt;객체/배열의 속성 변경도 자동 반응형&lt;/li&gt;
&lt;li data-end=&quot;2212&quot; data-start=&quot;2174&quot;&gt;&lt;b&gt;기본 자료형(&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;number, string, boolean 등&lt;/span&gt;)에는 사용할 수 없음&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의-1&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ref, reactive 주요 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;535&quot; data-start=&quot;144&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비교 항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;ref&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;reactive&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;272&quot; data-start=&quot;208&quot;&gt;
&lt;td&gt;&lt;b&gt;데이터 유형&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;기본형(&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;number, string, boolean 등&lt;/span&gt;) &amp;amp; 객체 가능&lt;/td&gt;
&lt;td&gt;객체, 배열 (배열도 객체로 취급)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;327&quot; data-start=&quot;273&quot;&gt;
&lt;td&gt;&lt;b&gt;반응형 구조&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;.value 사용 필요&lt;/td&gt;
&lt;td&gt;.value 없이 직접 접근 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;380&quot; data-start=&quot;328&quot;&gt;
&lt;td&gt;&lt;b&gt;배열 지원&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;가능 (ref([]))&lt;/td&gt;
&lt;td&gt;가능 (reactive([]))&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;472&quot; data-start=&quot;381&quot;&gt;
&lt;td&gt;&lt;b&gt;비구조화 할당&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;안됨 (const { count } = state는 반응형을 잃음)&lt;/td&gt;
&lt;td&gt;안됨 (객체의 속성을 직접 구조 분해하면 반응형을 잃음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;535&quot; data-start=&quot;473&quot;&gt;
&lt;td&gt;&lt;b&gt;주요 사용 사례&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;단일 값, 원시 타입, 간단한 상태 관리&lt;/td&gt;
&lt;td&gt;복잡한 객체나 배열의 반응형 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&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;h3 id=&quot;-정의-1&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ref vs reactive 선택 기준&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2268&quot; data-start=&quot;2253&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ ref 선택&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2382&quot; data-start=&quot;2269&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2305&quot; data-start=&quot;2269&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;number, string, boolean&lt;/span&gt; 과 같은 기본형 데이터를 다룰 때&lt;/li&gt;
&lt;li data-end=&quot;2340&quot; data-start=&quot;2306&quot;&gt;반응형 객체라도 .value 사용이 불편하지 않을 때&lt;/li&gt;
&lt;li data-end=&quot;2382&quot; data-start=&quot;2341&quot;&gt;단순한 상태 저장 (ref(0), ref('hello') 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2404&quot; data-start=&quot;2384&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ reactive 선택&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2480&quot; data-start=&quot;2405&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2426&quot; data-start=&quot;2405&quot;&gt;객체 또는 배열을 다룰 때&lt;/li&gt;
&lt;li data-end=&quot;2459&quot; data-start=&quot;2427&quot;&gt;.value 없이 직관적으로 속성 변경을 원할 때&lt;/li&gt;
&lt;li data-end=&quot;2480&quot; data-start=&quot;2460&quot;&gt;복잡한 상태 관리가 필요한 경우&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의-3&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 결론&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-start=&quot;2203&quot; data-end=&quot;2230&quot;&gt;기본 데이터(number, string, boolean 등)는 ref 사용합니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-start=&quot;2231&quot; data-end=&quot;2274&quot;&gt;객체/배열은 reactive를 사용하면 .value 없이 접근 가능합니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로그래밍/VUE</category>
      <category>Composition</category>
      <category>Reactive</category>
      <category>Ref</category>
      <category>Vue</category>
      <category>Vue3</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/85</guid>
      <comments>https://ho-ding.tistory.com/85#entry85comment</comments>
      <pubDate>Wed, 26 Mar 2025 21:30:17 +0900</pubDate>
    </item>
    <item>
      <title>[VUE] Composition API - watch, watchEffect</title>
      <link>https://ho-ding.tistory.com/84</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Composition API에서 &lt;b&gt;watch&lt;/b&gt;와 &lt;b&gt;watchEffect&lt;/b&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; watch (명시적인 감시 대상)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;644&quot; data-start=&quot;603&quot; data-ke-size=&quot;size16&quot;&gt;watch는 특정 반응형 변수를 감시하여 값이 변경될 때만 실행됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742979403558&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
        &amp;lt;button @click=&quot;count++&quot;&amp;gt;count 증가&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

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

    const count = ref(0);

    // count 값이 변경될 때마다 실행되는 watch
    watch(count, (newVal, oldVal) =&amp;gt; {
        console.log(`count값이 ${oldVal}에서 ${newVal}로 변경되었습니다.`)
    })
    
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 출력 값&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFdx9Q/btsMXyWBldQ/qdQ51FYkBay3lZkukBWwU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFdx9Q/btsMXyWBldQ/qdQ51FYkBay3lZkukBWwU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFdx9Q/btsMXyWBldQ/qdQ51FYkBay3lZkukBWwU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFdx9Q%2FbtsMXyWBldQ%2FqdQ51FYkBay3lZkukBWwU1%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;227&quot; height=&quot;99&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ button 클릭 후 출력 값&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U0mrs/btsMYxvDq04/jTpMckBKG94fKVPTWKST71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U0mrs/btsMYxvDq04/jTpMckBKG94fKVPTWKST71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U0mrs/btsMYxvDq04/jTpMckBKG94fKVPTWKST71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU0mrs%2FbtsMYxvDq04%2FjTpMckBKG94fKVPTWKST71%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;233&quot; height=&quot;106&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ button 클릭 후 콘솔&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;135&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uA1s1/btsMWZAkqHj/vePczUb29nTmOR8xdCht1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uA1s1/btsMWZAkqHj/vePczUb29nTmOR8xdCht1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uA1s1/btsMWZAkqHj/vePczUb29nTmOR8xdCht1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuA1s1%2FbtsMWZAkqHj%2FvePczUb29nTmOR8xdCht1k%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;684&quot; height=&quot;135&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;135&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;594&quot; data-end=&quot;659&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-start=&quot;627&quot; data-end=&quot;659&quot;&gt;count를 명시적으로 감시&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-start=&quot;627&quot; data-end=&quot;659&quot;&gt;값이 변경될 때만 콜백 실행&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-start=&quot;627&quot; data-end=&quot;659&quot;&gt;기본적으로 처음 한 번 실행되지 않음&lt;/li&gt;
&lt;/ul&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;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; watchEffect (자동 감지)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1083&quot; data-start=&quot;1034&quot; data-ke-size=&quot;size16&quot;&gt;watchEffect는 내부에서 사용된 반응형 데이터를 자동으로 감지하여 실행됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742979746428&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
        &amp;lt;button @click=&quot;count++&quot;&amp;gt;count 증가&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

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

    const count = ref(0);

    // count가 사용되었으므로 자동 감지됨
    watchEffect(() =&amp;gt; {
        console.log(`count 값 : ${count.value}`)
    })
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 출력 값&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/df7xep/btsMW8RunI1/mZwwwLy1K868xPMhZlkngk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/df7xep/btsMW8RunI1/mZwwwLy1K868xPMhZlkngk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/df7xep/btsMW8RunI1/mZwwwLy1K868xPMhZlkngk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdf7xep%2FbtsMW8RunI1%2FmZwwwLy1K868xPMhZlkngk%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;227&quot; height=&quot;99&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ button 클릭 &lt;span style=&quot;color: #ee2323;&quot;&gt;전&lt;/span&gt; 콘솔(컴포넌트가 마운트 될 때 watchEffect가 실행되므로 콘솔이 찍힙니다.)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf8M8F/btsMW5AqrfB/QIjqs7cLDeuU71HfmSy4rK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf8M8F/btsMW5AqrfB/QIjqs7cLDeuU71HfmSy4rK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf8M8F/btsMW5AqrfB/QIjqs7cLDeuU71HfmSy4rK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf8M8F%2FbtsMW5AqrfB%2FQIjqs7cLDeuU71HfmSy4rK%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;686&quot; height=&quot;141&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ button 클릭 후 출력 값&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qAikE/btsMYJ3KaOI/bQrkLmD2k35Ya7VNKF4YaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qAikE/btsMYJ3KaOI/bQrkLmD2k35Ya7VNKF4YaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qAikE/btsMYJ3KaOI/bQrkLmD2k35Ya7VNKF4YaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqAikE%2FbtsMYJ3KaOI%2FbQrkLmD2k35Ya7VNKF4YaK%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;233&quot; height=&quot;106&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ button 클릭&lt;span&gt;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;후&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;콘솔&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kFkoK/btsMYyagIRK/1naiW7675Waie1Goe1u3Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kFkoK/btsMYyagIRK/1naiW7675Waie1Goe1u3Ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kFkoK/btsMYyagIRK/1naiW7675Waie1Goe1u3Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkFkoK%2FbtsMYyagIRK%2F1naiW7675Waie1Goe1u3Ak%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;684&quot; height=&quot;181&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;659&quot; data-start=&quot;594&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-end=&quot;659&quot; data-start=&quot;627&quot;&gt;count를 명시적으로 지정하지 않아도 자동으로 추적&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-end=&quot;659&quot; data-start=&quot;627&quot;&gt;컴포넌트가 마운트될 때 즉시 실행&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-end=&quot;659&quot; data-start=&quot;627&quot;&gt;내부에서 사용된 반응형 변수를 모두 감지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; watch, watchEffect 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;566&quot; data-start=&quot;142&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비교항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;watch&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;watchEffect&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;284&quot; data-start=&quot;229&quot;&gt;
&lt;td&gt;&lt;b&gt;사용 목적&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;특정 반응형 데이터 변경 감지&lt;/td&gt;
&lt;td&gt;관련된 반응형 데이터 자동 감지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;336&quot; data-start=&quot;285&quot;&gt;
&lt;td&gt;&lt;b&gt;종속성 추적 방식&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;감시할 변수를 명시적으로 지정&lt;/td&gt;
&lt;td&gt;내부에서 자동으로 감지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;394&quot; data-start=&quot;337&quot;&gt;
&lt;td&gt;&lt;b&gt;콜백 실행 시점&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;값이 변경될 때 실행&lt;/td&gt;
&lt;td&gt;즉시 실행 후, 종속된 값이 변경될 때 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;461&quot; data-start=&quot;395&quot;&gt;
&lt;td&gt;&lt;b&gt;초기 실행 여부&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;기본적으로 X (immediate: true 옵션 필요)&lt;/td&gt;
&lt;td&gt;기본적으로 즉시 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;508&quot; data-start=&quot;462&quot;&gt;
&lt;td&gt;&lt;b&gt;비동기 처리&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;O (비동기 로직 가능)&lt;/td&gt;
&lt;td&gt;O (비동기 로직 가능)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;566&quot; data-start=&quot;509&quot;&gt;
&lt;td&gt;&lt;b&gt;Deep 감지 필요 여부&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;deep: true 옵션 필요&lt;/td&gt;
&lt;td&gt;자동으로 deep 감지&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; watch, watchEffect 선택 기준&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1502&quot; data-start=&quot;1483&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;watch 선택&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1580&quot; data-start=&quot;1503&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1528&quot; data-start=&quot;1503&quot;&gt;특정한 반응형 데이터만 감시하고 싶을 때&lt;/li&gt;
&lt;li data-end=&quot;1553&quot; data-start=&quot;1529&quot;&gt;이전 값과 새로운 값을 비교해야 할 때&lt;/li&gt;
&lt;li data-end=&quot;1580&quot; data-start=&quot;1554&quot;&gt;실행을 제어하고 싶을 때 (초기 실행 X)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1607&quot; data-start=&quot;1582&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;watchEffect 선택&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1709&quot; data-start=&quot;1608&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1645&quot; data-start=&quot;1608&quot;&gt;감시할 변수를 명확히 지정하지 않고 자동으로 추적하고 싶을 때&lt;/li&gt;
&lt;li data-end=&quot;1674&quot; data-start=&quot;1646&quot;&gt;여러 반응형 변수를 한 번에 감지하고 싶을 때&lt;/li&gt;
&lt;li data-end=&quot;1709&quot; data-start=&quot;1675&quot;&gt;반응형 데이터가 변경될 때 즉시 효과를 적용하고 싶을 때&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의-3&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 결론&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2230&quot; data-start=&quot;2203&quot;&gt;&lt;b&gt;watch&lt;/b&gt;는 특정 변수를 감시할 때 사용합니다.&lt;/li&gt;
&lt;li data-end=&quot;2274&quot; data-start=&quot;2231&quot;&gt;&lt;b&gt;watchEffect&lt;/b&gt;는 내부에서 사용된 모든 반응형 변수를 자동 감지합니다.&lt;/li&gt;
&lt;li data-end=&quot;2311&quot; data-start=&quot;2275&quot;&gt;초기 실행이 필요한 경우 &lt;b&gt;watchEffect&lt;/b&gt;가 더 적합합니다.&lt;/li&gt;
&lt;li data-end=&quot;2342&quot; data-start=&quot;2312&quot;&gt;이전 값과 비교해야 하면 &lt;b&gt;watch&lt;/b&gt;가 더 적합합니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로그래밍/VUE</category>
      <category>Composition</category>
      <category>Vue</category>
      <category>Vue3</category>
      <category>watch</category>
      <category>watcheffect</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/84</guid>
      <comments>https://ho-ding.tistory.com/84#entry84comment</comments>
      <pubDate>Wed, 26 Mar 2025 18:21:13 +0900</pubDate>
    </item>
    <item>
      <title>[VUE] Composition API - computed, watch</title>
      <link>https://ho-ding.tistory.com/83</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;computed와&amp;nbsp;watch는&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; computed (계산된 속성)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;222&quot; data-start=&quot;135&quot; data-ke-size=&quot;size16&quot;&gt;computed는 종속된 반응형 데이터가 변경될 때 자동으로 재계산되는 속성입니다. 주로 값의 캐싱과 의존성 기반 자동 업데이트가 필요할 때 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742976276485&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;가격 : {{ price }}&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;수량 : {{ quantity }}&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;총 가격 : {{ totalPrice }}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

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

    const price = ref(10000);   // 가격
    const quantity = ref(3);    // 수량
    
    // 총 가격을 계산할 computed
    const totalPrice = computed(() =&amp;gt; price.value * quantity.value);
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 출력 값&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btktDE/btsMXaav8Eg/VrOh4UhGbvXEheGlYka5IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btktDE/btsMXaav8Eg/VrOh4UhGbvXEheGlYka5IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btktDE/btsMXaav8Eg/VrOh4UhGbvXEheGlYka5IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtktDE%2FbtsMXaav8Eg%2FVrOh4UhGbvXEheGlYka5IK%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;253&quot; height=&quot;116&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;594&quot; data-end=&quot;659&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-start=&quot;627&quot; data-end=&quot;659&quot;&gt;종속된 반응형 값(price, quantity)이 변경될 때만 다시 계산 (캐싱 기능)&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-start=&quot;627&quot; data-end=&quot;659&quot;&gt;computed 값은 함수처럼 호출하지 않고 속성처럼 접근(totalPrice.value)&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; watch (감시자)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;780&quot; data-start=&quot;731&quot; data-ke-size=&quot;size16&quot;&gt;watch는 특정 반응형 데이터의 변화를 감지하고 특정 로직을 실행할 때 사용됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742976802931&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;count : {{ count }}&amp;lt;/p&amp;gt;
        &amp;lt;button @click=&quot;count++&quot;&amp;gt;count 증가&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

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

    const count = ref(0);

    // count 값이 변경될 때마다 실행되는 watch
    watch(count, (newVal, oldVal) =&amp;gt; {
        console.log(`count값이 ${oldVal}에서 ${newVal}로 변경되었습니다.`)
    })
    
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 출력 값&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coWd90/btsMYyusNam/XKXiDZLJplgv0SfmDWMX10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coWd90/btsMYyusNam/XKXiDZLJplgv0SfmDWMX10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coWd90/btsMYyusNam/XKXiDZLJplgv0SfmDWMX10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoWd90%2FbtsMYyusNam%2FXKXiDZLJplgv0SfmDWMX10%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;227&quot; height=&quot;99&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ button 클릭 후 출력 값&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZuHeR/btsMYt03llK/DP8HhYkGyrevU3ZKyffvy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZuHeR/btsMYt03llK/DP8HhYkGyrevU3ZKyffvy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZuHeR/btsMYt03llK/DP8HhYkGyrevU3ZKyffvy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZuHeR%2FbtsMYt03llK%2FDP8HhYkGyrevU3ZKyffvy0%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;233&quot; height=&quot;106&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ button 클릭 후 콘솔&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;135&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvN2vI/btsMXRn1LYK/kpHD0e79x3ioy0IBTN3k91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvN2vI/btsMXRn1LYK/kpHD0e79x3ioy0IBTN3k91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvN2vI/btsMXRn1LYK/kpHD0e79x3ioy0IBTN3k91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvN2vI%2FbtsMXRn1LYK%2FkpHD0e79x3ioy0IBTN3k91%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;684&quot; height=&quot;135&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;135&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;659&quot; data-start=&quot;594&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-end=&quot;659&quot; data-start=&quot;627&quot;&gt;첫 번째 인자로 감시할 반응형 데이터를 전달&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-end=&quot;659&quot; data-start=&quot;627&quot;&gt;두 번째 인자로 (newValue, oldValue) =&amp;gt; { ... } 형태의 콜백 함수를 전달&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot; data-end=&quot;659&quot; data-start=&quot;627&quot;&gt;반응형 데이터가 변경될 때마다 실행&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; computed, watch 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1537&quot; data-start=&quot;1278&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비교항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;computed&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;watch&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1405&quot; data-start=&quot;1348&quot;&gt;
&lt;td&gt;&lt;b&gt;사용 목적&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;종속된 값이 변경될 때 자동 계산&lt;/td&gt;
&lt;td&gt;특정 값이 변할 때 실행할 동작 수행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1445&quot; data-start=&quot;1406&quot;&gt;
&lt;td&gt;&lt;b&gt;리턴값&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;계산된 값&lt;/td&gt;
&lt;td&gt;콜백 함수 실행 (리턴값 없음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1492&quot; data-start=&quot;1446&quot;&gt;
&lt;td&gt;&lt;b&gt;캐싱 여부&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;O (같은 값이면 재계산 안 함)&lt;/td&gt;
&lt;td&gt;X (항상 실행)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1537&quot; data-start=&quot;1493&quot;&gt;
&lt;td&gt;&lt;b&gt;비동기 처리&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;X (권장되지 않음)&lt;/td&gt;
&lt;td&gt;O (비동기 처리 가능)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 결론&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2479&quot; data-start=&quot;2434&quot;&gt;&lt;b&gt;computed :&lt;/b&gt; 데이터의 변화에 따라 자동으로 계산되는 값을 생성할 때 사용합니다.&lt;/li&gt;
&lt;li data-end=&quot;2521&quot; data-start=&quot;2480&quot;&gt;&lt;b&gt;watch :&lt;/b&gt; 특정 데이터의 변화를 감지하여 특정 로직을 실행할 때 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/VUE</category>
      <category>Composition</category>
      <category>computed</category>
      <category>Vue</category>
      <category>Vue3</category>
      <category>watch</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/83</guid>
      <comments>https://ho-ding.tistory.com/83#entry83comment</comments>
      <pubDate>Wed, 26 Mar 2025 17:25:30 +0900</pubDate>
    </item>
    <item>
      <title>[VUE] Option API 방식과 Composition API 방식의 차이점</title>
      <link>https://ho-ding.tistory.com/82</link>
      <description>&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;옵셔널 API (Option API)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;330&quot; data-start=&quot;190&quot; data-ke-size=&quot;size16&quot;&gt;옵셔널 API는 Vue 2에서 사용되던 기본 API 스타일로, 컴포넌트의 상태와 로직을 &lt;b&gt;옵션&lt;/b&gt; 객체를 통해 정의합니다.&lt;/p&gt;
&lt;p data-end=&quot;330&quot; data-start=&quot;190&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, data, methods, computed, watch 등의 옵션을 사용하여 컴포넌트를 정의합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742832131464&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;{{ message }}&amp;lt;/div&amp;gt;
    &amp;lt;button type=&quot;button&quot; @click=&quot;updateMessage()&quot;&amp;gt;button&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
    // Option API 방식
    export default {
        data() {
        return {
            message: 'Hello, Vue2!'
        };
        },
        methods: {
        updateMessage() {
            this.message = 'updated message!';
        }
        }
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;580&quot; data-start=&quot;533&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;547&quot; data-start=&quot;533&quot;&gt;직관적이고 간단한 구조&lt;/li&gt;
&lt;li data-end=&quot;563&quot; data-start=&quot;550&quot;&gt;Vue 2와의 호환성&lt;/li&gt;
&lt;li data-end=&quot;580&quot; data-start=&quot;566&quot;&gt;작은 프로젝트에서 적합&lt;/li&gt;
&lt;/ul&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;b&gt; ✅ 단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;659&quot; data-start=&quot;594&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;624&quot; data-start=&quot;594&quot;&gt;대규모 애플리케이션에서 로직 분리가 어려울 수 있음&lt;/li&gt;
&lt;li data-end=&quot;659&quot; data-start=&quot;627&quot;&gt;복잡한 컴포넌트에서 상태와 로직을 재사용하는 것이 불편&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;컴포지션 API (Composition API)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;867&quot; data-start=&quot;704&quot; data-ke-size=&quot;size16&quot;&gt;컴포지션 API는 Vue 3에서 도입된 새로운 API 스타일로, 로직을 &lt;b&gt;함수&lt;/b&gt;로 구성하고, 이를 setup() 함수 안에서 정의합니다. ref, reactive, computed, watch와 같은 Composition API 기능을 사용하여 상태와 로직을 정의합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742833083325&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;{{ message }}&amp;lt;/div&amp;gt;
    &amp;lt;button type=&quot;button&quot; @click=&quot;updateMessage()&quot;&amp;gt;button&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
    // Composition API 방식
    import { ref } from 'vue';

    export default {
        setup() {
            const message = ref('Hello, Vue3!');
            const updateMessage = () =&amp;gt; {
                message.value = 'updated message!';
            };

            return { message, updateMessage};
        }
    }
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ✅ 장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1240&quot; data-start=&quot;1126&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1150&quot; data-start=&quot;1126&quot;&gt;로직을 더 유연하고 재사용 가능하게 관리&lt;/li&gt;
&lt;li data-end=&quot;1186&quot; data-start=&quot;1153&quot;&gt;복잡한 애플리케이션에서 코드가 잘 분리되고 유지보수 용이&lt;/li&gt;
&lt;li data-end=&quot;1240&quot; data-start=&quot;1189&quot;&gt;setup()을 사용하여 컴포지션에 필요한 모든 상태 및 메서드를 명확하게 정의 가능&lt;/li&gt;
&lt;/ul&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;b&gt; ✅ 단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1316&quot; data-start=&quot;1254&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1277&quot; data-start=&quot;1254&quot;&gt;처음에는 다소 복잡하게 느껴질 수 있음&lt;/li&gt;
&lt;li data-end=&quot;1316&quot; data-start=&quot;1280&quot;&gt;Vue 2와 호환되지 않음 (Vue 3 이상에서만 사용 가능)&lt;/li&gt;
&lt;/ul&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;h3 data-end=&quot;1329&quot; data-start=&quot;1323&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;script setup&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포지션 API 에서는 위와 같이 &amp;lt;script&amp;gt; 태그 안에 setup() 함수를 정의하는 방식이 아닌 &lt;b&gt;&amp;lt;script setup&amp;gt;&lt;/b&gt;을 사용하게 되면 export default, return을 사용하지 않고 코드를 작성할 수 있어 더욱 간결합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트를&amp;nbsp;처음&amp;nbsp;가져올&amp;nbsp;때&amp;nbsp;한&amp;nbsp;번만&amp;nbsp;실행되는&amp;nbsp;일반적인&amp;nbsp;&amp;lt;script&amp;gt;와&amp;nbsp;달리,&amp;nbsp;&amp;lt;script&amp;nbsp;setup&amp;gt;&amp;nbsp;내부의&amp;nbsp;코드는&amp;nbsp;&lt;b&gt;컴포넌트의&amp;nbsp;인스턴스가&amp;nbsp;생성될&amp;nbsp;때마다&amp;nbsp;실행&lt;/b&gt;합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742974792542&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;{{ message }}&amp;lt;/div&amp;gt;
    &amp;lt;button type=&quot;button&quot; @click=&quot;updateMessage()&quot;&amp;gt;button&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;!-- Composition API script setup 방식 --&amp;gt;
&amp;lt;script setup&amp;gt;
    import { ref } from 'vue';

    const message = ref('Hello, Vue3!');
    const updateMessage = () =&amp;gt; {
        message.value = 'updated message!';
    };
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 결론&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;1473&quot; data-start=&quot;1330&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1398&quot; data-start=&quot;1330&quot;&gt;&lt;b&gt;옵셔널 API&lt;/b&gt; &lt;b&gt;:&lt;/b&gt;&amp;nbsp;&amp;nbsp;간단하고 직관적인 코드 구조를 제공하지만, 복잡한 애플리케이션에서는 관리가 어려울 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;1473&quot; data-start=&quot;1399&quot;&gt;&lt;b&gt;컴포지션 API : &lt;/b&gt;&amp;nbsp;더 많은 유연성과 재사용성을 제공하며, 특히 대규모 애플리케이션에서 코드의 유지보수와 확장이 용이합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/VUE</category>
      <category>Composition api</category>
      <category>option api</category>
      <category>script setup</category>
      <category>Vue</category>
      <category>Vue3</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/82</guid>
      <comments>https://ho-ding.tistory.com/82#entry82comment</comments>
      <pubDate>Tue, 25 Mar 2025 01:25:24 +0900</pubDate>
    </item>
    <item>
      <title>티스토리 소스코드 예쁘게 출력하기</title>
      <link>https://ho-ding.tistory.com/81</link>
      <description>&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;1. 포스팅 시 코드블럭을 통해 코드 작성&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mFk6r/btsL3YCdfq1/UnL3HdPfn5loZ8J8W7f9QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mFk6r/btsL3YCdfq1/UnL3HdPfn5loZ8J8W7f9QK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mFk6r/btsL3YCdfq1/UnL3HdPfn5loZ8J8W7f9QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFk6r%2FbtsL3YCdfq1%2FUnL3HdPfn5loZ8J8W7f9QK%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;854&quot; height=&quot;469&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nxVJ9/btsL5BlflRr/7SmxMgzfOjDKSkRjkbXrz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nxVJ9/btsL5BlflRr/7SmxMgzfOjDKSkRjkbXrz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nxVJ9/btsL5BlflRr/7SmxMgzfOjDKSkRjkbXrz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnxVJ9%2FbtsL5BlflRr%2F7SmxMgzfOjDKSkRjkbXrz1%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;631&quot; height=&quot;736&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;2. 포스팅 저장 및 확인&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k3EtW/btsL4JK3rmo/V0uMiNNCKor2fbBlQBK7EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k3EtW/btsL4JK3rmo/V0uMiNNCKor2fbBlQBK7EK/img.png&quot; data-alt=&quot;포스팅 작성 중&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k3EtW/btsL4JK3rmo/V0uMiNNCKor2fbBlQBK7EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk3EtW%2FbtsL4JK3rmo%2FV0uMiNNCKor2fbBlQBK7EK%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;973&quot; height=&quot;771&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;포스팅 작성 중&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;※ 저장된 포스팅을 확인했을 때 작성한 코드가 아래와 같이 색깔 구분 없이 보여질 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이때 티스토리 플러그인에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;Syntax Highlight&lt;/span&gt; 를 적용해 줘야 합니다. (아래 3, 4번 확인)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AE9YY/btsL3p7XGsY/itkngj9N9O2q76anI77911/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AE9YY/btsL3p7XGsY/itkngj9N9O2q76anI77911/img.png&quot; data-alt=&quot;포스팅 작성 후&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AE9YY/btsL3p7XGsY/itkngj9N9O2q76anI77911/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAE9YY%2FbtsL3p7XGsY%2Fitkngj9N9O2q76anI77911%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;747&quot; height=&quot;425&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;포스팅 작성 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;3. 티스토리 플로그인에서 &lt;span style=&quot;color: #000000;&quot;&gt;Syntax Highlight&amp;nbsp;를&lt;/span&gt; 적용&lt;/b&gt;&lt;/h3&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;b&gt;1) 블로그 관리에서 '플러그인' 클릭&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciXsqM/btsL5DciyAa/pgwnD1yRHIyCSyekesmFK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciXsqM/btsL5DciyAa/pgwnD1yRHIyCSyekesmFK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciXsqM/btsL5DciyAa/pgwnD1yRHIyCSyekesmFK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciXsqM%2FbtsL5DciyAa%2FpgwnD1yRHIyCSyekesmFK1%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;804&quot; height=&quot;571&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;b&gt;2) '코드 문법 강조(Syntax Highlight)' 클릭&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;687&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Fi2D/btsL5jZp1s1/F6FhYhWr3zhMNynbi4lk7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Fi2D/btsL5jZp1s1/F6FhYhWr3zhMNynbi4lk7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Fi2D/btsL5jZp1s1/F6FhYhWr3zhMNynbi4lk7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Fi2D%2FbtsL5jZp1s1%2FF6FhYhWr3zhMNynbi4lk7k%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;787&quot; height=&quot;687&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;687&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;b&gt;3) 테마 선택 및 변경사항 적용&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KrOu6/btsL23RLObS/jdWRzzqVRC6wj5Ukq3CFU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KrOu6/btsL23RLObS/jdWRzzqVRC6wj5Ukq3CFU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KrOu6/btsL23RLObS/jdWRzzqVRC6wj5Ukq3CFU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKrOu6%2FbtsL23RLObS%2FjdWRzzqVRC6wj5Ukq3CFU0%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;826&quot; height=&quot;683&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;4. 포스팅 내 코드 영역 Syntax Highlight 적용 확인&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Syntax Highlight 적용 이전과 다르게 테마에 맞춰 예쁘게 적용된 것을 볼 수 있습니다 :)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K7CWD/btsL4xYp5p9/BvgbP9iLXZKxxezKE5kgeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K7CWD/btsL4xYp5p9/BvgbP9iLXZKxxezKE5kgeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K7CWD/btsL4xYp5p9/BvgbP9iLXZKxxezKE5kgeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK7CWD%2FbtsL4xYp5p9%2FBvgbP9iLXZKxxezKE5kgeK%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;650&quot; height=&quot;444&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Snmwr/btsL4LvkUmX/kCAMnEmhYkwgknRpQZzt9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Snmwr/btsL4LvkUmX/kCAMnEmhYkwgknRpQZzt9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Snmwr/btsL4LvkUmX/kCAMnEmhYkwgknRpQZzt9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSnmwr%2FbtsL4LvkUmX%2FkCAMnEmhYkwgknRpQZzt9k%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;1481&quot; height=&quot;644&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/ETC</category>
      <category>소스</category>
      <category>소스 예쁘게</category>
      <category>소스 출력</category>
      <category>소스블럭</category>
      <category>소스코드</category>
      <category>티스토리 소스</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/81</guid>
      <comments>https://ho-ding.tistory.com/81#entry81comment</comments>
      <pubDate>Sun, 2 Feb 2025 02:51:30 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 필터(Filter)</title>
      <link>https://ho-ding.tistory.com/80</link>
      <description>&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 필터란 무엇인가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필터(Filter)는 Java Servlet API에서 제공하는 기능으로, 클라이언트 요청이 서블릿에 도달하기 전에 요청을 가로채거나, 서블릿의 응답이 클라이언트로 보내지기 전에 응답을 가로채는 역할을 합니다.&lt;/li&gt;
&lt;li&gt;주로 다음과 같은 용도로 사용됩니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;로깅(Logging)&lt;/b&gt;: 요청과 응답을 로깅해서 추적&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안(Security)&lt;/b&gt;: 인증 및 권한 부여&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 압축(Data Compression)&lt;/b&gt;: 서버에서 클라이언트로 보내는 응답 데이터를 압축&lt;/li&gt;
&lt;li&gt;&lt;b&gt;요청 및 응답 인코딩&lt;/b&gt;: 문자 인코딩 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vy1JD/btsL4bOOZS6/rAuCXJwvwaJzj3GKrZt9kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vy1JD/btsL4bOOZS6/rAuCXJwvwaJzj3GKrZt9kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vy1JD/btsL4bOOZS6/rAuCXJwvwaJzj3GKrZt9kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvy1JD%2FbtsL4bOOZS6%2FrAuCXJwvwaJzj3GKrZt9kK%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;1182&quot; height=&quot;668&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 필터의 구조와 동작 원리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필터는 javax.servlet.Filter 인터페이스를 구현하여 사용합니다. 기본적으로 3개의 메서드를 구현해야 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;init(FilterConfig filterConfig): 필터 초기화 메서드로, 필터가 처음 생성될 때 호출됩니다.&lt;/li&gt;
&lt;li&gt;doFilter(ServletRequest request, ServletResponse response, FilterChain chain): 실제로 요청과 응답을 처리하는 메서드입니다. 요청이 필터를 통과할 때마다 이 메서드가 호출됩니다.&lt;/li&gt;
&lt;li&gt;destroy(): 필터가 종료될 때 호출되는 메서드로, 리소스 정리 등을 담당합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동작 흐름&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트가 요청을 보내면, 필터는 doFilter() 메서드를 통해 요청을 처리하고, 필요한 경우 FilterChain을 사용해 요청을 서블릿으로 넘기거나, 응답을 수정하여 클라이언트에게 전달할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738428114854&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        // 초기화 코드
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 요청 처리 (로깅, 보안 체크 등)
        chain.doFilter(request, response); // 서블릿으로 요청 전달
        // 응답 처리 (압축, 수정 등)
    }

    public void destroy() {
        // 정리 코드
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 필터의 장점과 사용 예&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;재사용성&lt;/b&gt;: 필터는 여러 서블릿에서 공통적으로 사용될 수 있기 때문에 중복 코드를 줄일 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유지보수성&lt;/b&gt;: 기능이 분리되어 있기 때문에 각 필터를 독립적으로 관리하고 수정할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;효율성&lt;/b&gt;: 서블릿을 거치기 전에 미리 필터를 사용하여 불필요한 작업을 줄이거나, 요청을 가공하는 등의 최적화가 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용 예&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;로그 필터&lt;/b&gt;: 요청이 들어올 때마다 어떤 요청이 있었는지 로그를 남기는 필터를 만들어 관리할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인증/권한 부여 필터&lt;/b&gt;: 요청이 올 때마다 인증 여부를 확인하여 인증되지 않은 사용자의 접근을 차단할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;성능 최적화 필터&lt;/b&gt;: 응답이 클라이언트에게 전송되기 전에 데이터 압축이나 캐시 처리 등을 통해 성능을 개선할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 필터 설정 및 주의사항&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;필터 설정&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필터는 web.xml에 설정하거나, @WebFilter 어노테이션을 사용하여 설정할 수 있습니다.&lt;/li&gt;
&lt;li&gt;예시 (web.xml 설정):
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1738428365335&quot; class=&quot;pgsql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;MyFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;com.example.MyFilter&amp;lt;/filter-class&amp;gt;
&amp;lt;/filter&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;MyFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/example/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;예시 (어노테이션 사용):
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1738428395776&quot; class=&quot;groovy&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@WebFilter(&quot;/example/*&quot;)
public class MyFilter implements Filter {
    // 필터 구현
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주의사항&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;필터 순서&lt;/b&gt;: 필터가 여러 개 있을 경우 실행 순서를 지정할 수 있으며, 순서에 따라 요청 및 응답 처리의 흐름이 달라질 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;필터 성능&lt;/b&gt;: 너무 많은 필터를 사용하거나, 각 필터의 처리 로직이 복잡하면 애플리케이션의 성능에 영향을 미칠 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;
&lt;h3 id=&quot;-정의&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 마무리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서 필터는 매우 강력한 도구로, 다양한 기능을 구현하고 요청과 응답을 유연하게 처리할 수 있습니다. 이를 통해 보안, 로깅, 데이터 처리 등 여러 분야에서 효율적이고 유지보수 가능한 방법을 제공할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/JAVA</category>
      <category>doFilter</category>
      <category>Filter</category>
      <category>Interceptor</category>
      <category>Java</category>
      <category>Servlet</category>
      <category>필터</category>
      <author>hojun</author>
      <guid isPermaLink="true">https://ho-ding.tistory.com/80</guid>
      <comments>https://ho-ding.tistory.com/80#entry80comment</comments>
      <pubDate>Sun, 2 Feb 2025 01:56:36 +0900</pubDate>
    </item>
  </channel>
</rss>