data
,methods
,mounted
와 같은 옵션을 사용<template>
<div>
<button v-on:click="increment">Counter: {{ counter }}</button>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0,
};
},
methods: {
increment() {
this.counter++;
},
},
mounted() {
console.log('컴포넌트가 마운트 되었습니다!');
},
};
</script>
<style lang="scss" scoped></style>
setup
함수가 있다.data
, methods
, ...
)을 선언하는 대신 가져온 함수(ref
, onMounted
, ...
)를 사용하여 Vue 컴포넌트를 작성할 수 있는 API 세트<template>
<div>
<button v-on:click="increment">Counter: {{ counter }}</button>
</div>
</template>
<script>
import { onMounted, ref } from 'vue';
export default {
setup() {
const counter = ref(0);
const increment = () => counter.value++;
onMounted(() => {
console.log('컴포넌트가 마운트 되었습니다!');
});
return {
counter,
increment,
};
},
};
</script>
<style lang="scss" scoped></style>
Composition API는 옵션(data
, methos
, ...
)을 선언하는 대신 가져온 함수(ref
, onMounted
, ...
)를 사용하여 Vue 컴포넌트를 작성할 수 있는 API 세트를 말합니다.
예를 들어 ref()
, reactive()
와 같은 API를 사용하여 reactive state(반응 상태)
, computed state(계산된 상태)
, watchers(감시자)
와 같은 것들을 만들 수 있습니다.
예를 들어 onMounted()
, onUnmounted()
와 같은 API를 사용하여 프로그래밍 방식으로 컴포넌트 라이프사이클에 접근할 수 있습니다.
쉽게 말해서 라이프사이클 특정 시점에 이러한 함수로 코드를 삽입할 수 있습니다.
예를 들어 provide()
와 inject()
는 Reactivity API를 사용하는 동안 Vue의 의존성 주입 시스템을 활용할 수 있게 해줍니다
<template>
<div>
<h2>반응형 메세지</h2>
<p>{{ reactiveMessage }}</p>
<button v-on:click="addReactiveMessage">Add Message</button>
<h2>일반 메시지</h2>
<p>{{ normalMessage }}</p>
<button v-on:click="addNormalMessage">Add Message</button>
</div>
</template>
<script>
import { isRef, onBeforeMount, onMounted, ref } from 'vue'
export default {
setup () {
console.log('Setup');
const reactiveMessage = ref('Hello Reactive Message');
const addReactiveMessage = () => {
reactiveMessage.value += '!';
}
//console.log(isRef(reactiveMessage)); //반응형 데이터인지 true
let normalMessage = "Hello Normal Message";
const addNormalMessage = () =>{
normalMessage.value += '!';
}
//console.log(isRef(normalMessage)); //반응형 데이터인지 false
onMounted(()=>{
console.log("onMounted");
})
onBeforeMount(()=>{
console.log("onBeforeMounted");
})
return {
reactiveMessage,
normalMessage,
addReactiveMessage,
addNormalMessage
}
}
}
</script>
<style lang="scss" scoped>
</style>
setup()
함수는 Composition API 사용을 위한 진입점
<template>
<div>
{{ counter }}
</div>
<p>
{{message}}
</p>
<button v-on:click="increment">Click</button>
</template>
<script>
import { ref } from 'vue'
export default {
setup () {
const counter = ref(0);
const message = ref('Hello vue3');
const increment = () =>{
counter.value++;
}
return {
counter,
message,
increment
}
}
}
</script>
<style lang="scss" scoped>
</style>
첫 번째 매개변수 props
두 번째 매개변수 context
<template>
<div>
<!--
텍스트 보간법으로 데이터 바인딩
-->
<h2>텍스트 보간법</h2>
<p>{{message}}</p>
<!-- v-once : 데이터가 갱신되어도 반응되지 않도록 -->
<p v-once>{{message}}</p>
<button v-on:click="message = message + '!' ">Click</button>
<br/>
<!-- v-html -->
<h2>v-html</h2>
<p>{{rawHtml}}</p>
<!-- 실제 html 출력 -->
<p v-html="rawHtml"></p>
<br/>
<h2>속성 바인딩</h2>
<!-- v-bind는 :로 단축할 수 있음 -->
<div v-bind:title="dynamicTitle">마우스 올려</div>
<input type="text" value="홍길동" :disabled="isInputDisabled">
<!-- 다중 속성 바인딩 -->
<input v-bind="attrs">
<!-- vue 에서는 모든 데이터 바인딩 내에서 js 표현식 가능 -->
<h2>자바스크립트</h2>
{{ message.split('').reverse().join('')}}
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup () {
const message = ref('안녕하세요');
const rawHtml = ref('<strong>안녕하세요</strong>');
const dynamicTitle = ref("안녕하세요!!!@@");
const isInputDisabled = ref(true);
const attrs = ref({
type : "password",
value : "12345",
disabled : false,
})
return {
message,
rawHtml,
dynamicTitle,
isInputDisabled,
attrs,
}
}
}
</script>
<style lang="scss" scoped>
</style>
reactive()
함수를 사용<template>
<div>
<button v-on:click="increment">click {{state.count}}</button>
<button v-on:click="increment">deepclick {{state.deep.count}}</button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup () {
const state = reactive({
count : 0,
deep : {
count:0
}
});
const increment = ()=>{
state.count++;
state.deep.count++;
}
return {
state,
increment
}
}
}
</script>
<style lang="scss" scoped>
</style>
reactive()
는 객체타입에만 동작 따라서 기본타입 (number,string boolean)을 반응형으로 만들기 위해서는 ref()
사용ref()
메서는 mutable 객체를 반환 이 객체안에는 value라는 하나의 속성만 포함.value
는 필요없음ref
가 반응형 객체의 속성으로 접근할 때, 자동적으로 내부 값으로 벗겨내서, 일반적인 속성과 마찬가지로 동작ref
가 반응형 배열 또는 Map
과 같은 기본 컬렉션 타입의 요소로 접근될 때 수행되는 래핑 해제가 없다<template>
<div>
<p>{{message.value}}</p>
<!-- value 안써줘도됨 -->
<p>{{refMessage}}</p>
<button v-on:click="addMessage">add click</button>
</div>
</template>
<script>
import { reactive, ref } from 'vue'
export default {
setup () {
// 반응형으로 동작하지 않는다.
// 객체나 배열과 같이 레퍼런스 객체여야함
// => 해결 ref함수
//let message = reactive('Hello Vue');
// console.log(message);
// console.log(typeof message); //string
let message = reactive({
value : 'Hello Vue',
});
let refMessage = ref('hello vue3');
const addMessage = () =>{
message.value += '!';
refMessage.value += '!';
}
return {
message,
addMessage,
refMessage
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
</div>
</template>
<script>
import { reactive, ref} from 'vue';
export default {
setup () {
// ref를 객체에서 사용
let count = ref(0);
const state = reactive({
count
});
count.value++;
count.value++;
//언랩핑
// console.log(state.count);
//ref를 array에서사용
//언랩핑 되지않
const message = ref('Hello');
const arr = reactive([message]);
console.log(arr[0].value);
return {}
}
}
</script>
<style lang="scss" scoped>
</style>
toRefs
, toRef
를 사용하면 반응형 객체의 속성과 동기화 됩니다. 그래서 원본 속성을 변경하면 ref 객체가 업데이트되고 그 반대의 경우도 마찬가지<template>
<div>
<p>author : {{author}}</p>
<p>title : {{title}}</p>
</div>
</template>
<script>
import { reactive, toRef, toRefs } from 'vue'
export default {
setup () {
const book = reactive({
author: 'Vue Team',
year: '2020',
title: 'Vue 3 Guide',
description: '당신은 이 책을 지금 바로 읽습니다 ;)',
price: '무료'
});
//구조 분해 할당은 반응성을 읽어버리게됨
// => toRefs
//const {author,title} = book;
//console.log(typeof author);
//반응성을 잃지 않고 가져오기
//toRefs
// const {author,title} = toRefs(book)
// console.log(typeof author);
//toRef
const author = toRef(book,'author');
const title = toRef(book,'title');
return {author,title,book}
}
}
</script>
<style lang="scss" scoped>
</style>
ref
나 reactive
)의 변화를 추적하기 원하지만, 또한 특정 부분에서는 변화를 막기 위해서 사용<template>
<div>
</div>
</template>
<script>
import { reactive, readonly } from 'vue'
export default {
setup () {
const original = reactive({
count : 0,
});
const copy = readonly(original);
original.count++;
copy.count++;
console.log(original.count);
console.log(copy.count);
return {}
}
}
</script>
<style lang="scss" scoped>
</style>