컴포지션를 사용해 같은 기능들끼리 분류해 코드를 정리할 수 있다.

setup()을 사용해 코드를 작성한다.
다만, setup안에 작성된 데이터는 반응성을 가지지 않기 때문에 ref를 사용해 객체 데이터를 사용해야 하고
값을 사용하기 위해선 .value를 사용해야 한다.
그 다음 return 에 반환해 template에서 사용한다.
<template>
<div @click="increase">{{ count }}</div>
</template>
<script>
import {ref} from 'vue' //반응성을 위해
export default {
setup() {
let count = ref(0) //data() 안에 있던 count를 작성
function increase() { //method 안에 있던 함수 작성
count.value += 1 //ref를 사용해서 .value를 사용해야 값이 변경
}
return{ //return 으로 반환해서 사용. count.value로 안해도 댐
count,
increase
}
}
}
</script>
컴포지션을 적용해보자. 다음 두 예제는 같은 기능을 수행하나, 한쪽은 컴포지션이 추가되었다.
여기서 라이프싸이클도 컴포지션화 할 수 있다.

컴포지션은 DOM 에 연결되고 나서 컴포지션이 가능하다.
따라서 create는 따로 존재하지 않고 그냥 바로 실행하면 된다.
컴포지션 API 적용 안함, 여러 기능이 들어가면 보기 힘들다
<template>
<h1 @click="increase">
{{ count }} /{{ doubleCount }}
</h1>
<h1 @click="changeMessage">
{{ Message }} / {{ reverseMessage }}
</h1>
</template>
<script>
export default {
components: {
data() {
return {
count:0,
message: 'hello world!'
}
},
computed: {
doubleCount() {
return this.count *2
},
reverseMessage() {
return this.message.split('').reverse.join('')
}
},
watch: {
message(newValue){
console.log(newValue)
}
},
created() {
console.log(this.message)
},
mounted() {
console.log(this.count)
},
method: {
increase() {
this.count +=1
},
changeMessage() {
this.message = 'Good!'
}
}
}
}
</script>
컴포지션 API 적용
<template>
<h1 @click="increase">
{{ count }} /{{ doubleCount }}
</h1>
<h1 @click="changeMessage">
{{ Message }} / {{ reverseMessage }}
</h1>
</template>
<script>
import {ref, computed, watch, onMounted} from 'vue'
export default {
setup(){
//count 관련
const count = ref(0)
const doubleCount = computed(()=>{
return count.value*2
})
function increase() {
count.value
}
//msg관련
const message = ref('hello world!')
const reverseMessage = computed(()=>{
return message.value.split('').reverse.join('')
})
function changeMessage() {
message.value='Good?!'
}
watch(message, newValue=>{
console.log(newvalue)
})
//라이프 싸이클. mount
onMounted(() => {
console.log(count.value)
})
//create는 없다. DOM 에 연결되고 나서 컴포지션이 가능하다.
console.log(message.value)
return { // 다 만들고 리턴하면 사용이 가능하다.
count,
message,
increase,
doubleCount,
reverseMessage,
changeMessage
}
}
}
</script>
컴포지션 API안에 사용하는 setup에서는
this.~로 접근할 수 없다. 이를 대신해주기 위해 props, context를 사용한다.
<template>
<MyBtn
class = "na"
style = "color: red;"
color="#ff0000"
@hello = "log">
Apple
</MyBtn>
</template>
<script>
import MyBtn from './components/MyBtn.vue'
export default {
components: {
MyBtn
},
method: {
log() {
console.log('hello!')
}
}
}
</script>
<template>
<div
v-bind="$attrs"
class="btn"
@click="hello">
<slot></slot>
</div>
</template>
<script>
import { onMounted } from 'vue'
export default {
inheritAttrs:false,
props:{
color: {
type: String,
default: 'gray'
}
},
//emits: ['hello'],
//mounted() {
// console.log(this.color)
// console.log(this.$attrs)
//},
//methods: {
// hello(){
// this.$emit('hello')
// }
//},
setup(props, context) {
//this 대신 props, context
function hello() {
context.emit('hello')
}
onMounted(()=>{
console.log(props.color)
console.log(context.attrs)
})
return {
hello
}
}
}
</script>