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`는 체인 연결에 적합.
댓글
댓글 쓰기