vue

    

vue create vue3-project이름


vscode에 vetur 를 설치함


index.html있고


src에 main.js가 시작 포인트


템플릿


npm run serve로 시작


앱.뷰 단위 파일에


template


script


style이렇게 들어가 있다


컴포넌트

====


.vue를 쓰면 그게 뷰 컴포넌트


세가지로 구정


template


script


style


composition api는


스크립트 안에


export default {


setup(){


변수 선언이 가능해지는데


이걸로 템플릿안에서 사용 가능 → 변수인가?


{{ name }} 이런식으로 사용가능


함수는


{{ hello() }} 이런식으로 사용가능


return 에 setup함수의 변수나


}


}


이런식


vue2 → vue3로 바뀌면서 바뀐거


vue2에서는 템플릿 안에 하나의 태그(루트) 안에 모든 요소들이 있어야 했었는데


이제는 그럴 필요 없음


이벤트는 템플릿의 태그 속성으로 바로 들어감 이런식으로


v-on:click ="함수이름괄호없이"


변수는 스테이트가 아니라서 바뀌어도 템플릿 반영 안됨


그러니까 ref를 사용해 줘야한다


import ref from vue...대충 한다음에


ref()이렇게 해줘야한다. → value를 꼭적어줘야하고


reactive도 있음 → value 적을 필요 없고 기본자료형과 object array만 사용가능


뭔차이지..


단방향 바인딩


데이터 바인딩-데이터를 인풋이랑 연결하는거? 인데(유저 인풋을 받아가는건 아니고..)


태그의 속성들을 변경할 수 있게 한다 아무튼 이건 어떻게 하냐면


<input type="text" v-bind:value="name">


인풋의 value값을 name 변수랑 동기화 되게 한다..


v-bind:value="name"> 줄여서 :value="name"> 이렇게도 사용가능


v-on:click ="함수이름괄호없이" 이거도 줄여서 @click ="함수이름괄호없이"


양방향 바인딩은 이제 유저가 바꾼 값도 가져가는거


v-on으로 가져온거를 이벤트 타겟 값으로 직접 가져오고 v-bind로 업데이트를 바로 해도 되지만 두개다 해야해서 번거로우니까


v-model사용


v-model="name"으로 간단하게


음 그럼 왜 v-bind, on가 필요한거지 v-model로 한번에 하면 되는거 아닌가


form html 태그는 화면을 리로딩하는 특성 있음


이런 막기 위해서 preventDefault해주는데


뷰에서는 이렇게도 함


<form v-on:submit.prevent="onSubmit"> </form>← 함수에 안넣고 이렇게 바로 prevent만 써도 됨


이런걸 모디파이어라고 부르는데 이거 말고도 여러개 있음


v-for


<div v-for"todo in todos" : key="[todo.id](https://www.blogger.com/blog/post/edit/3471293612939652291/5513819181009864818#)(유니크한값이들어가야한다)">


이런식


v-show


00의 조건일때 보여줌


display none으로 가리고 보여줌


초기 랜더비용 많이듦


토글 자주할 때 사용


v-if v-else v-else-if


show랑 비슷한데 이건 아예 없애버림


토글 비용 많이 듦


토글 많이 안할때


class style 바인딩


스타일 바인딩


:style="스타일 오브젝트나 함수?"


? : 문법 많이 쓰는 듯


class바인딩


엥 왜 오브젝트 넣어주지? 잘 모르겠네


컴포넌트 import 해서도 사용가능


import로 가져오고


script의 export default 안에 components:{} 에 넣어주고


템플릿에 <Todo /> 이런식으로 가져옴


부모랑 자식 컴포넌트가 데이터 주고 받는 방식


setup(props,context){


이렇게 두개의 매개변수를 받아올 수 있는데


context.emit("이벤트 이름",{오브젝트?}); 이렇게 자식에서 올려주면


부모에서 태그의 이벤트로 가져올 수 있다


<Todo @addtodo="함수"


이 함수의 매개변수로 사용..


부모→자식은 props


<Todo :todos="todos"


vue3 부터 emits를 적어서 자식에서 이밋하는 것들을 명시해야ㅑ함


computed


state를 감시하고 있다가 적용해줌..


함수랑 다름 함수는 템플릿에서 {{함수이름()}} 이렇게 해줘야 하는데


computed는 값이 리턴되기 때문에 {{컴퓨티드}} 이렇게 하면 됨


그리고 computed는 인자를 못받아옴 값을 캐싱해서 한번 계산해서 같은 페이지면 그 값을 계속 씀


백앤드 없이 가짜 데이터베이스 패키지 json-server


fake rest api server


db.json에 데이터 넣어놓고 서버 실행해서 사용


post로 데이터 넣으면 자동으로 해줌..


axios로 포스트랑 겟 리퀘스트 사용


이건 비동기로 통신임


동기는 순서대로 하는거


비동기란 동시에 되는대로 하는거


async


await


...


then이랑 catch로도 할 수 있는데


이거를 async 함수로 바꾸고 await으로 바꿔서 쓸 수도 있다.


---


1.  `vue create vue3-project이름`

    -   Vue CLI로 새 프로젝트 생성.

    -   `npm install -g @vue/cli`로 Vue CLI 설치 필요.

    -   프로젝트 생성 시 기본 설정 또는 Babel, Vue Router 등 선택 가능.

2.  VS Code에 Vetur 설치

    -   Vue.js 개발 환경 확장 도구.

    -   코드 자동 완성, 문법 강조, 에러 검출 지원.

3.  `index.html`

    -   프로젝트의 메인 HTML 파일.

    -   Vue 앱은 여기에 렌더링됨.

4.  `src/main.js`

    -   Vue 앱의 진입점.

    -   Vue 인스턴스를 생성하고, `App.vue`를 연결함.

5.  `npm run serve`

    -   로컬 개발 서버 실행 명령어.

    -   기본 포트: `http://localhost:8080`.

6.  `App.vue` 단위 파일 구성

    -   `template`: HTML 구조 작성.

    -   `script`: JavaScript 로직 정의.

    -   `style`: CSS 스타일 정의.

    -   각 섹션은 `scoped`를 통해 독립 스타일 적용 가능.


컴포넌트

----


1.  **`.vue` 파일**

    -   `.vue` 파일 자체가 Vue 컴포넌트.

2.  **구성 요소 (3가지)**

    -   `template`: HTML 구조 정의.

    -   `script`: JavaScript 로직 작성.

    -   `style`: 컴포넌트의 CSS 스타일 지정.


### **Composition API**


-   **`setup()` 사용**


    -   `setup()` 함수 안에서 변수와 함수를 선언.

    -   선언한 변수는 템플릿에서 사용 가능.

-   **예시**:


    ```

    <script>

    export default {

      setup() {

        const name = 'Vue';

        const hello = () => `Hello, ${name}!`;


        return { name, hello }; // 템플릿에서 사용 가능

      }

    }

    </script>


    <template>

      <div>

        {{ name }} <!-- 'Vue' 출력 -->

        {{ hello() }} <!-- 'Hello, Vue!' 출력 -->

      </div>

    </template>


    ```


* * * * *


### **Vue 2 → Vue 3 변경점**


1.  **템플릿의 루트 태그 규칙 제거**


    -   Vue 2: 모든 요소는 하나의 루트 태그로 감싸야 했음.

    -   Vue 3: 여러 루트 요소 사용 가능.


    **예시**:


    ```

    <template>

      <div>첫 번째 요소</div>

      <p>두 번째 요소</p>

    </template>


    ```


2.  **이벤트 처리 (`v-on`)**


    -   Vue 2/3 공통: `v-on:click="함수"` 형식.

    -   축약형: `@click="함수"` 가능.

    -   함수 이름만 작성(괄호 없이).


    **예시**:


    ```

    <template>

      <button @click="handleClick">클릭</button>

    </template>


    <script>

    export default {

      setup() {

        const handleClick = () => alert('클릭!');

        return { handleClick };

      }

    };

    </script>


    ```


### **변수와 반응성 (`ref`, `reactive`)**


1.  **일반 변수**


    -   Vue 템플릿에서 일반 변수는 반응형이 아니기 때문에 값이 변경되어도 화면에 반영되지 않음.

2.  **`ref` 사용**


    -   기본 자료형에 반응성을 부여.

    -   값에 접근하려면 `.value`를 사용해야 함.


    **예시**:


    ```

    <script>

    import { ref } from 'vue';


    export default {

      setup() {

        const name = ref('Vue');

        name.value = 'Vue 3'; // 값 변경


        return { name };

      }

    };

    </script>


    <template>

      <p>{{ name }}</p> <!-- 화면에 'Vue 3' 출력 -->

    </template>


    ```


3.  **`reactive` 사용**


    -   객체, 배열 등 복잡한 데이터 구조에 반응성을 부여.

    -   `.value`를 사용하지 않고 바로 접근 가능.


    **예시**:


    ```

    <script>

    import { reactive } from 'vue';


    export default {

      setup() {

        const user = reactive({ name: 'Vue', age: 3 });

        user.name = 'Vue 3'; // 값 변경


        return { user };

      }

    };

    </script>


    <template>

      <p>{{ user.name }}</p> <!-- 화면에 'Vue 3' 출력 -->

    </template>


    ```


4.  **`ref` vs `reactive` 차이**


    | 특징 | `ref` | `reactive` |

    | --- | --- | --- |

    | 사용 대상 | 기본 자료형 (string, number 등) | 객체, 배열 등 복잡한 데이터 구조 |

    | 값 접근 방식 | `.value` 필요 | 바로 접근 가능 |

    | 내부적으로 작동 방식 | Wrapper 객체 생성 | Proxy 객체 생성 |


* * * * *


### **데이터 바인딩**


1.  **단방향 바인딩**


    -   데이터 → 템플릿으로 데이터 전달.


    -   유저가 데이터를 수정하더라도 Vue 데이터는 변경되지 않음.


    -   **예시**:


        ```

        <input type="text" :value="name">


        ```


    -   축약형 사용 가능:


        ```

        <input type="text" v-bind:value="name">


        ```


2.  **양방향 바인딩**


    -   유저 입력을 Vue 데이터에 동기화.

    -   `v-model` 사용.


    **예시**:


    ```

    <template>

      <input type="text" v-model="name">

      <p>{{ name }}</p>

    </template>


    <script>

    import { ref } from 'vue';


    export default {

      setup() {

        const name = ref('Vue');

        return { name };

      }

    };

    </script>


    ```


3.  **`v-bind`와 `v-on` 조합**


    -   `v-bind`와 `v-on`을 사용해도 양방향 바인딩 가능.

    -   그러나, 아래처럼 번거롭기 때문에 `v-model`을 사용하는 것이 편리함.


    **예시**:


    ```

    <template>

      <input

        :value="name"

        @input="(event) => name.value = event.target.value"

      >

    </template>


    ```


    → 이 과정을 `v-model`로 간단히 줄일 수 있음.


* * * * *


### **이벤트 핸들링 축약**


1.  **`v-on` 축약형**


    -   `v-on:click="함수이름"` → `@click="함수이름"`.


    -   **예시**:


        ```

        <button @click="handleClick">클릭</button>


        ```


2.  **`v-bind` 축약형**


    -   `v-bind:value="name"` → `:value="name"`.


    -   **예시**:


        ```

        <input :value="name">


        ```


* * * * *


### **요약**


-   일반 변수는 템플릿에 반영되지 않음 → 반응성을 위해 `ref`나 `reactive` 사용.

-   `ref`: 기본 자료형에 사용, `.value` 필요.

-   `reactive`: 객체/배열에 사용, 바로 접근 가능.

-   단방향 바인딩은 `v-bind` 사용, 양방향 바인딩은 `v-model` 사용.

-   이벤트와 바인딩은 축약형으로 깔끔하게 작성 가능.


`v-model` 이 있는데 `v-bind`와 `v-on` 을 사용하는 이유

------------------------------------------


좋은 질문이에요! `v-bind`와 `v-on`이 여전히 필요한 이유는 **유연성과 확장성** 때문입니다. `v-model`이 편리한 경우도 있지만, 모든 상황에서 적합하지는 않습니다. 아래에서 자세히 설명할게요.


* * * * *


### **1\. `v-model`은 특정한 상황에만 유용**


`v-model`은 양방향 바인딩을 단순화하기 위한 도구입니다. 하지만 모든 속성과 이벤트에 적용할 수 있는 것은 아닙니다.


-   **사용 사례**:

    -   주로 **폼 요소**에서 동작(예: `<input>`, `<textarea>`, `<select>`).

    -   Vue는 기본적으로 `value` 속성과 `input` 이벤트에 바인딩되도록 설계.

-   **제한 사항**:

    -   커스텀 속성이나 이벤트에는 기본적으로 `v-model`을 사용할 수 없음.

    -   특정한 바인딩 규칙이 필요한 경우 `v-bind`와 `v-on`이 필요.


* * * * *


### **2\. `v-bind`와 `v-on`이 필요한 이유**


### **a. `v-bind`: 커스텀 속성 바인딩**


-   `v-model`은 기본적으로 `value` 속성만 처리.

-   **커스텀 속성**(예: `aria-*`, `data-*`, `class`, `style`)은 `v-bind`로 처리해야 함.


**예시**:


```

<template>

  <button :aria-label="buttonLabel">클릭</button>

</template>


<script>

export default {

  setup() {

    const buttonLabel = 'Submit';

    return { buttonLabel };

  }

};

</script>


```


* * * * *


### **b. `v-on`: 이벤트 핸들링**


-   `v-model`은 기본 이벤트(`input`, `change`, `update:modelValue`)만 처리.

-   클릭, 키보드 이벤트 등 다양한 이벤트 핸들링에는 `v-on`이 필요.


**예시**:


```

<template>

  <button @click="handleClick">클릭</button>

</template>


<script>

export default {

  setup() {

    const handleClick = () => alert('버튼 클릭!');

    return { handleClick };

  }

};

</script>


```


* * * * *


### **3\. 커스텀 컴포넌트에서의 차이**


### **a. `v-model` 사용 제한**


-   Vue의 기본 컴포넌트(`input`, `textarea`) 외에, **커스텀 컴포넌트**에서 사용하려면 추가 설정 필요.

-   커스텀 컴포넌트의 속성과 이벤트는 `v-bind`와 `v-on`으로 직접 처리하는 게 더 직관적일 수 있음.


**예시**:


```

<template>

  <CustomInput :value="name" @update="updateName"></CustomInput>

</template>


<script>

export default {

  setup() {

    const name = ref('');

    const updateName = (newName) => { name.value = newName; };

    return { name, updateName };

  }

};

</script>


```


### **b. 확장성과 다중 바인딩**


-   `v-model`은 단일 속성만 처리 가능.

-   속성을 여러 개 동시 바인딩하려면 `v-bind`가 유리.


**예시**:


```

<template>

  <input :value="name" :placeholder="placeholder">

</template>


<script>

export default {

  setup() {

    const name = ref('Vue');

    const placeholder = '이름 입력';

    return { name, placeholder };

  }

};

</script>


```


* * * * *


### **4\. `v-bind`, `v-on`, `v-model` 비교**


| 기능 | `v-bind` | `v-on` | `v-model` |

| --- | --- | --- | --- |

| 목적 | 속성 바인딩 | 이벤트 핸들링 | 양방향 데이터 바인딩 |

| 적용 대상 | 모든 속성 | 모든 이벤트 | 기본 속성/이벤트 (폼 요소 등) |

| 사용 예시 | `:value="name"` | `@click="handleClick"` | `v-model="name"` |

| 제한 사항 | 이벤트는 처리 불가 | 속성은 처리 불가 | 특정 속성/이벤트만 사용 가능 |


* * * * *


### **요약**


-   `v-model`은 양방향 바인딩을 간단히 처리하는 도구지만, **특수한 속성이나 이벤트**, **커스텀 컴포넌트**에서는 한계가 있음.

-   이런 경우에는 `v-bind`와 `v-on`이 더 유용하고 강력한 도구임.

-   **즉, `v-model`은 간단한 작업을 위한 편의 기능이고, `v-bind`와 `v-on`은 모든 경우에 사용할 수 있는 유연한 기본 기능입니다.**


### **1\. `preventDefault`와 Vue의 이벤트 수식어**


-   HTML `<form>` 태그는 기본적으로 **제출 시 페이지를 새로 고침(리로드)**합니다. 이를 방지하려면 `preventDefault()`를 호출해야 합니다.

-   Vue에서는 `v-on`의 **수식어(modifier)**를 사용해 더 간단히 처리할 수 있습니다.


**예시**:


```

<template>

  <form @submit.prevent="onSubmit">

    <button type="submit">제출</button>

  </form>

</template>


<script>

export default {

  setup() {

    const onSubmit = () => {

      console.log("폼 제출!");

    };

    return { onSubmit };

  }

};

</script>


```


-   **장점**:

    -   `@submit.prevent`처럼 간단히 작성 가능.

    -   JavaScript 코드에서 `preventDefault()`를 직접 호출하지 않아도 됨.


* * * * *


### **2\. Vue의 수식어(modifier)**


-   Vue는 여러 수식어를 제공하여 이벤트 동작을 간단히 제어할 수 있습니다. 아래는 자주 사용하는 수식어입니다:


| 수식어 | 설명 | 예시 |

| --- | --- | --- |

| `.prevent` | 기본 동작 방지 (e.g., `preventDefault()`) | `@submit.prevent` |

| `.stop` | 이벤트 전파 방지 (e.g., `stopPropagation()`) | `@click.stop` |

| `.once` | 이벤트 한 번만 실행 | `@click.once` |

| `.capture` | 캡처 단계에서 이벤트 실행 | `@click.capture` |

| `.self` | 이벤트가 해당 요소에서만 실행 | `@click.self` |


* * * * *


### **3\. `v-for`: 반복 렌더링**


-   Vue에서 배열 데이터를 렌더링할 때 `v-for`를 사용합니다.

-   `key` 속성은 필수이며, **고유한 값(유니크한 값)**을 제공해야 성능 최적화와 업데이트가 정확히 이루어집니다.


**예시**:


```

<template>

  <ul>

    <li v-for="todo in todos" :key="todo.id">

      {{ todo.text }}

    </li>

  </ul>

</template>


<script>

export default {

  setup() {

    const todos = [

      { id: 1, text: "Vue 배우기" },

      { id: 2, text: "프로젝트 만들기" }

    ];

    return { todos };

  }

};

</script>


```


* * * * *


### **4\. `v-show`**


-   **특징**:

    -   조건에 따라 요소를 **보이거나 감춤** (`display: none`).

    -   DOM 요소는 그대로 유지되므로, 초기 렌더링 비용이 발생.

    -   토글이 자주 일어나는 경우 유리.


**예시**:


```

<template>

  <div v-show="isVisible">이 텍스트를 보여줍니다.</div>

  <button @click="isVisible = !isVisible">토글</button>

</template>


<script>

export default {

  setup() {

    const isVisible = ref(true);

    return { isVisible };

  }

};

</script>


```


* * * * *


### **5\. `v-if`, `v-else-if`, `v-else`**


-   **특징**:

    -   조건에 따라 요소를 **추가하거나 제거**.

    -   DOM 요소를 완전히 생성하거나 삭제하므로, 초기 렌더링 비용이 적음.

    -   하지만 토글 비용이 높아, **조건 변경이 자주 발생하지 않는 경우 적합**.


**예시**:


```

<template>

  <div v-if="status === 'loading'">로딩 중...</div>

  <div v-else-if="status === 'success'">성공!</div>

  <div v-else>오류 발생</div>

</template>


<script>

export default {

  setup() {

    const status = ref("loading");

    return { status };

  }

};

</script>


```


* * * * *


### **6\. `v-show` vs `v-if` 비교**


| 항목 | `v-show` | `v-if` |

| --- | --- | --- |

| 동작 방식 | `display: none`로 감춤 | DOM에서 요소 추가/제거 |

| 초기 렌더링 비용 | 높음 | 낮음 |

| 토글 비용 | 낮음 | 높음 |

| 사용 시기 | 토글이 자주 발생할 때 사용 | 조건 변경이 드물 때 사용 |


* * * * *


### **요약**


1.  기본 동작 방지, 이벤트 전파 등을 간단히 처리하려면 **수식어**(`.prevent`, `.stop` 등)를 사용.

2.  반복 렌더링 시 `v-for`를 사용하며, **`key` 속성은 반드시 고유 값**이어야 함.

3.  조건부 렌더링에서는:

    -   토글이 자주 발생하면 `v-show`.

    -   드물게 발생하면 `v-if`.


### **1\. Class와 Style 바인딩**


### **a. Style 바인딩**


-   Vue에서 `:style`을 사용하면 인라인 스타일을 동적으로 설정할 수 있음.

-   **스타일 객체 또는 함수**를 사용해 조건에 따라 동적으로 스타일 변경 가능.


**예시**:


```

<template>

  <div :style="styleObject">스타일 바인딩 예제</div>

</template>


<script>

export default {

  setup() {

    const styleObject = {

      color: "red",

      fontSize: "20px",

    };

    return { styleObject };

  }

};

</script>


```


-   **스타일 함수**:


    ```

    <template>

      <div :style="getStyle()">스타일 함수</div>

    </template>


    <script>

    export default {

      setup() {

        const getStyle = () => ({

          color: "blue",

          fontWeight: "bold",

        });

        return { getStyle };

      }

    };

    </script>


    ```


* * * * *


### **b. Class 바인딩**


-   동적으로 클래스를 추가하거나 제거할 때 사용.

-   **객체**를 사용하면 특정 클래스의 조건부 적용 가능.


**예시**:


```

<template>

  <div :class="{ active: isActive, error: hasError }">클래스 바인딩 예제</div>

</template>


<script>

export default {

  setup() {

    const isActive = ref(true);

    const hasError = ref(false);


    return { isActive, hasError };

  }

};

</script>


```


-   **배열 형태**도 가능:


    ```

    <template>

      <div :class="[isActive ? 'active' : '', 'default-class']">배열 클래스</div>

    </template>


    <script>

    export default {

      setup() {

        const isActive = ref(true);

        return { isActive };

      }

    };

    </script>


    ```


* * * * *


### **2\. 컴포넌트 사용하기**


### **a. 컴포넌트 Import**


-   컴포넌트를 가져와서 부모 컴포넌트에서 사용할 수 있음.

-   `export default` 안의 `components` 속성에 추가.


**예시**:


```

<script>

import Todo from './Todo.vue';


export default {

  components: {

    Todo

  }

};

</script>


<template>

  <Todo />

</template>


```


* * * * *


### **3\. 부모와 자식 간 데이터 주고받기**


### **a. 부모 → 자식 (Props)**


-   부모에서 자식으로 데이터를 전달할 때 `props` 사용.


**예시**:


```

<template>

  <Todo :todos="todos" />

</template>


<script>

import Todo from './Todo.vue';


export default {

  components: { Todo },

  setup() {

    const todos = ref(['할 일 1', '할 일 2']);

    return { todos };

  }

};

</script>


```


-   **자식 컴포넌트**:


    ```

    <template>

      <ul>

        <li v-for="todo in todos" :key="todo">{{ todo }}</li>

      </ul>

    </template>


    <script>

    export default {

      props: ['todos']

    };

    </script>


    ```


* * * * *


### **b. 자식 → 부모 (이벤트 emit)**


-   자식에서 부모로 데이터를 전달할 때 `emit` 사용.

-   `context.emit(이벤트 이름, 데이터)`로 부모에 이벤트 전달.


**예시**:


```

<template>

  <button @click="addTodo">추가</button>

</template>


<script>

export default {

  setup(props, { emit }) {

    const addTodo = () => {

      emit('addTodo', { id: Date.now(), text: '새로운 할 일' });

    };

    return { addTodo };

  }

};

</script>


```


-   **부모 컴포넌트**:


    ```

    <template>

      <Todo @addTodo="handleAddTodo" />

    </template>


    <script>

    import Todo from './Todo.vue';


    export default {

      components: { Todo },

      setup() {

        const handleAddTodo = (newTodo) => {

          console.log('새로운 할 일:', newTodo);

        };

        return { handleAddTodo };

      }

    };

    </script>


    ```


* * * * *


### **4\. 요약**


1.  **스타일 바인딩**: `:style`에 객체나 함수를 사용해 동적 스타일 설정.

2.  **클래스 바인딩**: `:class`에 객체, 배열을 사용해 조건부 클래스 적용.

3.  **컴포넌트**: `import`로 컴포넌트를 가져와 `components`에 등록 후 사용.

4.  **부모-자식 데이터 흐름**:

    -   부모 → 자식: `props` 사용.

    -   자식 → 부모: `context.emit` 사용.


궁금한 점이나 보완이 필요한 부분 있으면 알려주세요! 😊


### **1\. `emits` 사용 (Vue 3)**


-   **Vue 3에서 변경점**: 자식 컴포넌트에서 `emit`할 이벤트를 명시적으로 정의해야 함.

    -   `emits` 옵션을 사용하여 허용된 이벤트를 선언.

    -   명시하지 않으면 경고가 발생.


**예시**:


```

<template>

  <button @click="addTodo">추가</button>

</template>


<script>

export default {

  emits: ['addTodo'], // 이벤트 선언

  setup(props, { emit }) {

    const addTodo = () => {

      emit('addTodo', { id: Date.now(), text: '새로운 할 일' });

    };

    return { addTodo };

  }

};

</script>


```


-   **부모에서 이벤트 처리**:


    ```

    <template>

      <Todo @addTodo="handleAddTodo" />

    </template>


    <script>

    import Todo from './Todo.vue';


    export default {

      components: { Todo },

      setup() {

        const handleAddTodo = (newTodo) => {

          console.log('추가된 할 일:', newTodo);

        };

        return { handleAddTodo };

      }

    };

    </script>


    ```


* * * * *


### **2\. `computed`: 계산된 값**


-   **특징**:

    -   Vue의 **반응형 데이터**를 감시하고 계산된 값을 제공.

    -   **캐싱** 기능이 있어 데이터가 변경되지 않으면 재계산하지 않음.

    -   **템플릿에서 사용 방법**: 함수 호출처럼 `()`를 붙이지 않고 사용.


**예시**:


```

<template>

  <p>총합: {{ total }}</p>

</template>


<script>

import { ref, computed } from 'vue';


export default {

  setup() {

    const num1 = ref(10);

    const num2 = ref(20);


    const total = computed(() => num1.value + num2.value);


    return { num1, num2, total };

  }

};

</script>


```


-   **함수와 차이점**:

    -   함수는 호출될 때마다 실행.


        ```

        <template>

          <p>총합: {{ calculateTotal() }}</p>

        </template>


        <script>

        export default {

          setup() {

            const calculateTotal = () => num1.value + num2.value;

            return { calculateTotal };

          }

        };

        </script>


        ```


    -   `computed`는 값이 변경될 때만 재계산.


-   **제한 사항**:

    -   `computed`는 **인자를 받을 수 없음**.

    -   인자를 받아야 하는 경우 **함수**를 사용.


* * * * *


### **3\. JSON Server로 가짜 데이터베이스 만들기**


-   **JSON Server**는 REST API 서버를 쉽게 구축할 수 있는 패키지.

-   데이터를 테스트하거나 간단한 프로젝트에서 유용.


### **설치**


```

npm install -g json-server


```


### **`db.json` 파일 생성**


```

{

  "todos": [

    { "id": 1, "text": "Vue 배우기", "done": false },

    { "id": 2, "text": "프로젝트 시작하기", "done": true }

  ]

}


```


### **서버 실행**


```

json-server --watch db.json


```


-   기본적으로 `http://localhost:3000`에서 실행됨.


### **사용 예시**


-   `GET`: `http://localhost:3000/todos`

-   `POST`: 데이터를 추가하면 `db.json`에 자동으로 저장됨.


* * * * *


### **4\. Axios를 사용한 비동기 통신**


### **비동기와 동기의 차이**


-   **동기**: 작업이 순서대로 실행됨.

-   **비동기**: 작업이 동시에 실행될 수 있으며, 결과를 기다리지 않고 다음 작업 실행.


### **Axios 사용**


-   **`GET` 요청**:


    ```

    import axios from 'axios';


    async function fetchData() {

      try {

        const response = await axios.get('<http://localhost:3000/todos>');

        console.log(response.data);

      } catch (error) {

        console.error('Error fetching data:', error);

      }

    }

    fetchData();


    ```


-   **`POST` 요청**:


    ```

    async function addTodo(newTodo) {

      try {

        const response = await axios.post('<http://localhost:3000/todos>', newTodo);

        console.log('추가된 데이터:', response.data);

      } catch (error) {

        console.error('Error adding data:', error);

      }

    }


    addTodo({ id: 3, text: '새로운 할 일', done: false });


    ```


* * * * *


### **5\. `async/await`와 `then/catch` 비교**


### **`async/await` 사용**


-   코드가 동기적으로 보이게 작성 가능.

-   가독성이 높음.


```

async function fetchData() {

  try {

    const response = await axios.get('<http://localhost:3000/todos>');

    console.log(response.data);

  } catch (error) {

    console.error(error);

  }

}


```


### **`then/catch` 사용**


-   Promise 기반으로 작성.

-   체인 형태로 비동기 작업 연결.


```

axios.get('<http://localhost:3000/todos>')

  .then((response) => {

    console.log(response.data);

  })

  .catch((error) => {

    console.error(error);

  });


```


* * * * *


### **요약**


1.  Vue 3에서는 자식 컴포넌트의 `emit` 이벤트를 명시적으로 선언(`emits`)해야 함.

2.  `computed`는 **캐싱된 계산 값**을 제공하며, 인자를 받을 수 없고 값처럼 사용 가능.

3.  JSON Server는 간단히 REST API를 만들 수 있는 툴로, 테스트와 개발에 유용.

4.  Axios는 `async/await`과 `then/catch`로 비동기 요청 처리 가능.

5.  `async/await`은 가독성이 좋고, `then/catch`는 체인 연결에 적합.

댓글

이 블로그의 인기 게시물

js 스트링에서 요소 갯수 세기

STUDY

javascript cheatsheet