<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dayeonO_Odev.log</title>
        <link>https://velog.io/</link>
        <description>No sweat, No sweet.</description>
        <lastBuildDate>Tue, 24 May 2022 09:37:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dayeonO_Odev.log</title>
            <url>https://velog.velcdn.com/cloudflare/dayeon0_0dev/901f7238-03dd-45f8-9263-bfca730edfa2/sample-profile06.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dayeonO_Odev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dayeon0_0dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Vue3 변경점을 정리해보자 1탄 (기본)]]></title>
            <link>https://velog.io/@dayeon0_0dev/Vue3-%EB%B3%80%EA%B2%BD%EC%A0%90%EC%9D%84-%EC%A0%95%EB%A6%AC%ED%95%B4%EB%B3%B4%EC%9E%90-1%ED%83%84-%EA%B8%B0%EB%B3%B8</link>
            <guid>https://velog.io/@dayeon0_0dev/Vue3-%EB%B3%80%EA%B2%BD%EC%A0%90%EC%9D%84-%EC%A0%95%EB%A6%AC%ED%95%B4%EB%B3%B4%EC%9E%90-1%ED%83%84-%EA%B8%B0%EB%B3%B8</guid>
            <pubDate>Tue, 24 May 2022 09:37:34 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="요약">요약</h2>
<ul>
<li>Composition API가 들어오면서 데이터 선언, 함수 선언, 상태 관리 등의 변화</li>
<li>컴포넌트 내에서 데이터, 함수, 상태를 호출하는 방식도 변화</li>
<li>없던 종류의 컴포넌트, 내부적인 성능 향상을 위한 변화</li>
</ul>
<hr>
<h2 id="변화-요약">변화 요약</h2>
<p>요기 ✔️가 이번 게시글에서 다룰 내용!!</p>
<ul>
<li>Composition API (→ 기본적으로 영향을 미치는 변경점!) ✔️</li>
<li>템플릿 생성 방식의 변화 ✔️</li>
<li>data, method 작성 방식의 변화 ✔️</li>
<li>Lifecycle hook 호출의 변화 ✔️</li>
<li>computed 속성 사용 방법의 변화 ✔️</li>
<li>props와 this 바인딩의 분리 ✔️</li>
<li>emit과 this 바인딩의 분리</li>
<li>Suspended Component</li>
<li>Fragment</li>
<li>Portal</li>
<li>내부적인 변화</li>
<li>그 외..</li>
</ul>
<hr>
<h2 id="사전-지식">사전 지식</h2>
<h3 id="composition-api란">Composition API란?</h3>
<p>컴포넌트 내 특정 기능의 코드를 유연하게 구성하여 사용할 수 있도록 Vue3 버전에 추가된 함수 기반의 API</p>
<h4 id="배경">배경</h4>
<ul>
<li>Vue는 프로젝트 규모가 커질 수록 관리하기 힘들다는 단점이 있어 이를 보완하기 위해 생김</li>
<li>컴포넌트의 계층구조가 복잡할수록 코드에 대한 추적 및 관리의 어려움 등..</li>
</ul>
<h4 id="쓰윽-">쓰윽-</h4>
<ul>
<li>얼핏 보면 리액트의 Hooks와 매우 유사한 느낌</li>
<li>목적에 맞는 코드를 모듈화하여 기존의 단점을 보완할 수 있으며 더 유연하고 안전한 확장 가능</li>
<li>beforeCreate, created… → “setup”</li>
</ul>
<h4 id="목적--정리">목적 &amp; 정리</h4>
<ul>
<li>API라는 이름을 붙인 것처럼, 특정 기능을 갖는 함수를 정의하고 API처럼 사용할 수 있게 해주는 것</li>
<li>코드에 대한 재활용성을 높이고, 코드의 가독성을 높이기 위해 사용</li>
</ul>
<hr>
<h2 id="템플릿-생성-방식의-변화">템플릿 생성 방식의 변화</h2>
<h3 id="여러개의-루트-엘리먼트">여러개의 루트 엘리먼트</h3>
<ul>
<li>vue2의 템플릿은 하나의 루트 엘리먼트만 허용했지만, Vue3부터는 여러개의 루트 엘리먼트를 갖는 컴포넌트를 지원</li>
<li>⇒ 불필요한 감싸주기 용의 wrapper div가 없어도 될 것으로 보임!</li>
<li>하지만 언제나 그렇듯, 여러개의 루트 엘리먼트 사용을 권장하지는 않음! (BEM 하의 원활한 스타일링 고려)</li>
</ul>
<pre><code class="language-html">&lt;template&gt;
    &lt;div class=&quot;input-label&quot;&gt;
        {{inputLabel}}
    &lt;/div&gt;
    &lt;input type=&quot;text&quot;/&gt;
&lt;/template&gt;</code></pre>
<br/>

<h3 id="템플릿에서의-호출-방식">템플릿에서의 호출 방식</h3>
<ul>
<li>기존에는 props나 method 등을 구분없이 이름만으로 호출할 수 있었는데, 이제는 문맥상으로 이들을 조금 분리하는 것이 가능해짐</li>
<li>이 호출 방식에 대한 변화는 사실 템플릿의 변화라기 보다는 props, data, method를 다루는 방식의 변화와 연관! <font color="gray">후에 나옵니다!!</font></li>
</ul>
<pre><code class="language-html">&lt;template&gt;
    &lt;div&gt;
        &lt;div class=&quot;input-label&quot;&gt;
            &lt;!--{{inputLabel}}--&gt;
            {{state.inputLabe}}
        &lt;/div&gt;
        &lt;input type=&quot;text&quot;/&gt;
    &lt;/div&gt;
&lt;/template&gt;</code></pre>
<br />

<h3 id="data-method-작성-방식의-변화">data, method 작성 방식의 변화</h3>
<ul>
<li><font color="gray">코드 측면에서의 가장 큰 변화!</font></li>
<li>method 선언이 전부 setup이라는 메소드 안으로 편입</li>
<li>대부분의 도큐먼트에서 사용하는 기본적인 예시는 Options API 방식</li>
</ul>
<pre><code class="language-javascript">// Vue2.x → props, data, methods가 같은 계층에 존재

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: &#39;&#39;,
      password: &#39;&#39;
    }
  },
  methods: {
    login () {
      // login method
    }
  }
}</code></pre>
<pre><code class="language-javascript">// Vue 3.x 
// → props와 setup이 같은 계층에 존재, data는 state로, 
// method들은 각각의 기명함수로 작성되어 한번에 반환되도록 변화

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: &#39;&#39;,
      password: &#39;&#39;
    })

    const login = () =&gt; {
      // login method
    }
    return { 
      login,
      state
    }
  }
}</code></pre>
<ul>
<li>vue 3.x setup 이렇게도 적용해요! (script 사용, 개인적으로 더 선호)<pre><code class="language-typescript">// vue 3.x
</code></pre>
</li>
</ul>
<script setup lang="ts">
import { definedProps, reactive }

const props = defineProps<{
    fiterKeys: string[];
}>();

const state = reactive(() => {
    username: string;
    password: string;
});

const login = () => {
    // login method
}
</script>
<pre><code>
![](https://velog.velcdn.com/images/dayeon0_0dev/post/f1b0c183-faf1-4c48-b7c2-7a2e951d0837/image.png)

state의 경우에도 그냥 선언이 아닌, vue reactive 사용 가능

* **vue reactive** - 반응형, vue가 반응형 시스템을 유지하기 위해 사용하는 간단한 JS 객체
* **getter / setter**
  * Vue 종속성 추적 및 변경 알림 수행 가능
  * 사용자에게는 보이지 않지만, 개발자가 속성에 엑세스 하거나 수정할 때 사용
  * (변환된 데이터 객체 기록 시 브라우저의 getter/setter 형식 처리 방식이 다르므로 vue-devtools 설치 권장)
* **watcher**
  * 모든 컴포넌트 인스턴스는 해당 watcher 인스턴스가 있으며, 컴포넌트가 종속적으로 렌더링 되는 동안 수정된 모든 속성 기록
  * 나중에 종속적인 setter가 트리거되면 watcher에게 알리고 컴포넌트가 다시 렌더링 되는 방식

&lt;br /&gt;

### Lifecycle hook 호출의 변화

* data, method와 같은 hierarchy(계층)에서 선언 → setup 내부에서 선언
* 이때 state나 method들과는 달리 Lifecycle hook은 return할 필요가 없음

```javascript
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated, onErrorCaptured } from &#39;vue&#39;

export default {
  setup() {
    onBeforeMount(() =&gt; {
      // ... 
    })
    onMounted(() =&gt; {
      // ... 
    })
    onBeforeUpdate(() =&gt; {
      // ... 
    })
    onUpdated(() =&gt; {
      // ... 
    })
    onBeforeUnmount(() =&gt; {
      // ... 
    })
    onUnmounted(() =&gt; {
      // ... 
    })
    onActivated(() =&gt; {
      // ... 
    })
    onDeactivated(() =&gt; {
      // ... 
    })
    onErrorCaptured(() =&gt; {
            // ... 
    })
  }
}</code></pre><br />

<h3 id="computed-속성-사용의-변화">Computed 속성 사용의 변화</h3>
<ul>
<li>computed 속성은 이제 별도 옵션이 아닌, state 선언문 내에 computed 속성에 대한 선언 문구를 추가하는 방식으로 변경됨</li>
<li>사용하는 것만 import해 사용하도록 하고자 하는 철학이 담김</li>
<li>= computed나 lifecycle hook 등 다양한 옵션들을 함수 형태로 동작하도록 변경</li>
</ul>
<pre><code class="language-javascript">// vue2

export default {
  // .. 
  computed: {
    lowerCaseUsername () {
      return this.username.toLowerCase()
    }
  }
}</code></pre>
<pre><code class="language-javascript">// vue3

import { reactive, computed } from &#39;vue&#39;

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: &#39;&#39;,
      password: &#39;&#39;,
      lowerCaseUsername: computed(() =&gt; state.username.toLowerCase())
    })

    // ...
  }</code></pre>
<hr>
<p>** Tistory에서 보려면 ** 👉<a href="https://dev-dayeon.tistory.com/10">요기로 클릭!</a></p>
<hr>
<h4 id="레퍼런스">레퍼런스</h4>
<p><a href="https://choppadontbiteme.tistory.com/86">https://choppadontbiteme.tistory.com/86</a>
<a href="https://velog.io/@bluestragglr/Vue3-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%B0%94%EB%80%8C%EB%82%98%EC%9A%94">https://velog.io/@bluestragglr/Vue3-무엇이-바뀌나요</a></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[벨로그 이전 완료👋]]></title>
            <link>https://velog.io/@dayeon0_0dev/%EB%B2%A8%EB%A1%9C%EA%B7%B8-%EC%9D%B4%EC%A0%84-%EC%99%84%EB%A3%8C</link>
            <guid>https://velog.io/@dayeon0_0dev/%EB%B2%A8%EB%A1%9C%EA%B7%B8-%EC%9D%B4%EC%A0%84-%EC%99%84%EB%A3%8C</guid>
            <pubDate>Fri, 08 Apr 2022 10:15:58 GMT</pubDate>
            <description><![CDATA[<p>깃헙 계정으로 새 벨로그 시작 준비 완료!!</p>
<p>이전 벨로그: <a href="https://velog.io/@dayeon-choi">https://velog.io/@dayeon-choi</a></p>
]]></description>
        </item>
    </channel>
</rss>