# Vue 3 Composition API ๊ฐ์ด๋
## ํ์ต ๋ชฉํ
Vue 3์ Composition API๋ก ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ญ๋๋ค.
## 1. Vue 3๋?
ํ๋ก๊ทธ๋ ์๋ธ JavaScript ํ๋ ์์ํฌ์
๋๋ค.
- Composition API ๋์
- ๋ ๋์ TypeScript ์ง์
- ํฅ์๋ ์ฑ๋ฅ
- ๋ ์์ ๋ฒ๋ค ํฌ๊ธฐ
## 2. ํ๋ก์ ํธ ์์ฑ
npm create vue@latest myapp
cd myapp
npm install
npm run dev
## 3. Composition API ๊ธฐ์ด
Options API (๊ธฐ์กด):
export default {
data() {
return { count: 0 }
},
methods: {
increment() { this.count++ }
}
}
Composition API (์๋ก์ด):
import { ref } from "vue"
export default {
setup() {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}
}
script setup (๊ถ์ฅ):
<script setup>
import { ref } from "vue"
const count = ref(0)
const increment = () => count.value++
</script>
## 4. ref์ reactive
ref - ๋จ์ผ ๊ฐ:
const count = ref(0)
const name = ref("Kim")
console.log(count.value)
count.value++
reactive - ๊ฐ์ฒด:
const state = reactive({
name: "Kim",
age: 25
})
console.log(state.name)
state.age++
์ฐจ์ด์ :
- ref๋ .value ํ์
- reactive๋ ๊ฐ์ฒด ์ ์ฒด๋ฅผ ๋ฐ์ํ์ผ๋ก
- ref๊ฐ ๋ ๋ช
์์ ์ด๋ผ ๊ถ์ฅ
## 5. computed
import { ref, computed } from "vue"
const firstName = ref("John")
const lastName = ref("Doe")
const fullName = computed(() => {
return firstName.value + " " + lastName.value
})
์ฐ๊ธฐ ๊ฐ๋ฅํ computed:
const fullName = computed({
get() {
return firstName.value + " " + lastName.value
},
set(newValue) {
[firstName.value, lastName.value] = newValue.split(" ")
}
})
## 6. watch์ watchEffect
watch - ํน์ ์์ค ๊ฐ์:
watch(count, (newVal, oldVal) => {
console.log("changed", newVal, oldVal)
})
watch(() => state.name, (newVal) => {
console.log("name changed", newVal)
})
watch([firstName, lastName], ([newFirst, newLast]) => {
console.log("changed", newFirst, newLast)
})
watchEffect - ์๋ ์์กด์ฑ ์ถ์ :
watchEffect(() => {
console.log("count is", count.value)
})
## 7. ๋ผ์ดํ์ฌ์ดํด ํ
import { onMounted, onUnmounted, onUpdated } from "vue"
onMounted(() => {
console.log("mounted")
fetchData()
})
onUnmounted(() => {
console.log("unmounted")
cleanup()
})
onUpdated(() => {
console.log("updated")
})
## 8. Props์ Emit
Props ๋ฐ๊ธฐ:
<script setup>
const props = defineProps({
title: String,
count: { type: Number, default: 0 }
})
</script>
Emit ๋ณด๋ด๊ธฐ:
<script setup>
const emit = defineEmits(["update", "delete"])
const handleClick = () => {
emit("update", { id: 1 })
}
</script>
## 9. provide/inject
๋ถ๋ชจ:
import { provide } from "vue"
const theme = ref("dark")
provide("theme", theme)
์์/์์:
import { inject } from "vue"
const theme = inject("theme")
const theme = inject("theme", "light") // ๊ธฐ๋ณธ๊ฐ
## 10. Composables (์ฌ์ฌ์ฉ ๋ก์ง)
composables/useFetch.js:
import { ref } from "vue"
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
const loading = ref(true)
fetch(url)
.then(res => res.json())
.then(json => data.value = json)
.catch(err => error.value = err)
.finally(() => loading.value = false)
return { data, error, loading }
}
์ฌ์ฉ:
<script setup>
import { useFetch } from "@/composables/useFetch"
const { data, loading } = useFetch("/api/users")
</script>
## 11. Vue Router
npm install vue-router@4
import { createRouter, createWebHistory } from "vue-router"
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: Home },
{ path: "/about", component: About },
{ path: "/user/:id", component: User }
]
})
์ปดํฌ๋ํธ์์:
import { useRouter, useRoute } from "vue-router"
const router = useRouter()
const route = useRoute()
router.push("/about")
console.log(route.params.id)
## 12. Pinia ์ํ๊ด๋ฆฌ
npm install pinia
stores/counter.js:
import { defineStore } from "pinia"
export const useCounterStore = defineStore("counter", {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2
},
actions: {
increment() { this.count++ }
}
})
์ฌ์ฉ:
<script setup>
import { useCounterStore } from "@/stores/counter"
const counter = useCounterStore()
counter.increment()
</script>
## ์ถ์ฒ ํ์ต ์์
1. ref์ reactive ์ดํด
2. computed์ watch
3. Composables ํจํด
4. Vue Router
5. Pinia ์ํ๊ด๋ฆฌ