소프트웨어 개발 요소/프레임워크
[Vue] setup()인자 파헤치기
숩니따
2024. 1. 15. 22:55
setup()
반응형 API ref를 사용하여 반응형 상태를 선언하고 setup() 객체를 반환하여 템플릿에 노출할 수 있다. 반환된 객체의 속성은 템플릿 및 기타 옵션 API 훅에 노출 가능
setup에서 반환된 refs는 템플릿에서 접근할 때, .value를 사용할 필요가 없습니다. 또한 옵션 API 방식을 사용하면 this로 해당 객체에 접근하면 자동으로 언래핑이 됨
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
// 템플릿 및 기타 옵션 API 훅에 노출
return {
count
}
},
// option API 방식에는 this 사용해서 접근 가능
mounted() {
console.log(this.count) // 0
}
}
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
Composition API에서 setup 함수 인자
props
- 부모 컴포넌트로부터 자식 컴포넌트로 데이터를 전달하는데 사용
- 컴포넌트에 정의된 props 옵션에 따라 해당 속성을 반응형으로 만들 수 있음
- props를 통해 부모 컴포넌트에서 전달된 데이터를 읽을 수 있으며, 이 데이터는 자식 컴포넌트 내부에서 사용될 수 있음
<-- Compositon API를 사용하면서, Option API 스타일의 스크립트 태그를 사용하는 방식 -->
<-- 배열 문법 -->
<script>
export default {
props: ['foo'],
setup(props) {
console.log(props.foo)
}
}
</script>
<-- 객체 문법 (타입 명시) -->
export default {
props: {
foo: String,
},
setup(props) {
console.log(props.foo)
}
}
<-- Composition API를 더 간결하고 선언적으로 사용하는 방식 -->
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
foo: String
})
console.log(props.foo)
</script>
context
- 컴포넌트에 대한 정보와 기능을 포함한 일반 Javascript 객체
context 객체가 포함한 속성
- attrs
- 부모 컴포넌트에서 전달된 모든 속성(attributes)을 포함하는 것으로 props로 정의되지 않은 추가적인 HTML 속성이나 데이터가 이에 해당됨
- 컴포넌트가 업데이트 될 때 항상 업데이트 되는 스테이트풀(stateful) 객체이므 구조 분해하지 말고 attrs.x로 속성을 참조해야 함
- 반응형이 아니기 때문에 이 변경 사항을 기반으로 하는 효과는 onBeforeUpdate 생명 주기 훅 내에서 구현해야 함
<-- 부모 컴포넌트 -->
<template>
<ChildComponent message="Hello" custom-attribute="value" />
</template>
<-- Compositon API를 사용하면서, Option API 스타일의 스크립트 태그를 사용하는 방식 -->
<-- 자식 컴포넌트 -->
<script>
export default {
props: {
message: String
},
setup(props, { attrs }) {
// `attrs`는 `custom-attribute`를 포함합니다.
console.log(attrs['custom-attribute']); // 'value' 출력
return {
// ...
};
}
};
</script>
<-- Composition API를 더 간결하고 선언적으로 사용하는 방법 -->
<-- 자식 컴포넌트 -->
<script setup>
import { defineProps, useAttrs } from 'vue';
// Props 정의
const props = defineProps({
message: String
});
// attrs 사용
const attrs = useAttrs();
console.log(attrs['custom-attribute']); // 'value' 출력
</script>
- slot
- 부모 컴포넌트에서 제공된 모든 슬롯에 대한 접근을 제공
- 템플릿 조각을 자식 컴포넌트에 전달하고 이 조각을 렌더링할 수 있도록 함
- 템플릿 재사용성을 높일 수 있음
- 컴포넌트가 업데이트 될 때 항상 업데이트 되는 스테이트풀(stateful) 객체이므 구조 분해하지 말고 slots.x로 속성을 참조해야 함
- 반응형이 아니기 때문에 이 변경 사항을 기반으로 하는 효과는 onBeforeUpdate 생명 주기 훅 내에서 구현해야 함
<-- 자식 컴포넌트 -->
<template>
<button class="fancy-btn">
<slot><slot/> <!-- 슬롯 아울렛 -->
</button>
</template>
<style>
.fancy-btn {
color: #fff;
background: linear-gradient(315deg, #42d392 25%, #647eff);
border: none;
padding: 5px 10px;
margin: 5px;
border-radius: 8px;
cursor: pointer;
}
</style>
<-- Compositon API를 사용하면서, Option API 스타일의 스크립트 태그를 사용하는 방식 -->
<-- 부모 컴포넌트 -->
<script>
import { defineComponent } from 'vue';
import FancyButton from './FancyButton.vue';
export default defineComponent({
components: {
FancyButton
}
});
</script>
<template>
<FancyButton>
클릭하기 <!-- 슬롯 컨텐츠 -->
</FancyButton>
</template>
<-- Composition API를 더 간결하고 선언적으로 사용하는 방식 -->
<-- 부모 컴포넌트 -->
<script setup>
import FancyButton from './FancyButton.vue'
</script>
<template>
<FancyButton>
클릭하기 <!-- 슬롯 컨텐츠 -->
</FancyButton>
</template>
- emit
- 이벤트를 발생시키기 위한 함수로 자식 컴포넌트가 부모 컴포넌트로 이벤트를 보낼 때 사용
- 이벤트를 발생(ex. 사용자 입력 처리, 버튼 클릭)시키면, 부모 컴포넌트에서 이에 대한 리스너를 정의하여 자식 컴포넌트 이벤트에 반응 가능
<-- Compositon API를 사용하면서, Option API 스타일의 스크립트 태그를 사용하는 방식 -->
<-- 부모 컴포넌트 -->
<script>
import { defineComponent } from 'vue';
import ChildComponent from './ChildComponent.vue';
export default defineComponent({
components: {
ChildComponent
},
setup() {
// 'update' 이벤트 핸들러
const handleUpdate = (updatedValue) => {
// 'update' 이벤트 처리 로직
};
// 'submit' 이벤트 핸들러
const handleSubmit = () => {
// 'submit' 이벤트 처리 로직
};
// setup 함수에서 반환된 값은 템플릿에서 사용할 수 있습니다.
return {
handleUpdate,
handleSubmit
};
}
});
</script>
<template>
<ChildComponent @update="handleUpdate" @submit="handleSubmit" />
</template>
<-- 자식 컴포넌트 -->
<script>
import { defineEmits } from 'vue';
export default {
setup() {
const emit = defineEmits(['update', 'submit']);
return {
// 필요한 경우 여기에 데이터나 메서드를 반환 가능
}
}
}
</script>
<-- Composition API를 더 간결하고 선언적으로 사용하는 방식 -->
<-- 부모 컴포넌트 -->
<script setup>
import ChildComponent from './ChildComponent.vue';
const handleUpdate = (updatedValue) => {
// 'update' 이벤트 처리 로직
};
const handleSubmit = () => {
// 'submit' 이벤트 처리 로직
};
</script>
<template>
<ChildComponent @update="handleUpdate" @submit="handleSubmit" />
</template>
<-- 자식 컴포넌트 -->
<script setup>
import { defineEmits } from 'vue'
const emit = defineEmits(['update', 'submit'])
</script>
- expose
- 컴포넌트 인스턴스에 메서드나 속성을 노출시키기 위해 사용
- 이는 주로 부모 컴포넌트나 외부 요소들이 자식 컴포넌트의 특정 메서드나 데이터 속성에 직접 접근할 필요가 있을 때 사용
- 부모 컴포넌트가 템플릿 참조를 통해 자식 컴포넌트 인스턴스에 접근할 때, 노출되는 속성을 명시적으로 제한하기 위해 사용
- expose 옵션은 속성의 이름 문자열로 이루어진 배열입니다. expose를 사용하면 명시적으로 나열된 속성만 컴포넌트의 공개 인스턴스에 노출
- 이를 통해 노출된 메서드나 속성은 컴포넌트 인스턴스 통해 직접 호출 가능 ex $refs.특정 컴포넌트.특정 컴포넌트 내 메서드()
<-- Compositon API를 사용하면서, Option API 스타일의 스크립트 태그를 사용하는 방식 -->
<script>
export default {
setup(props, { expose }) {
const someInternalMethod = () => {
// 내부 메서드 로직
};
// someInternalMethod를 컴포넌트의 public 메서드로 노출
expose({
someInternalMethod
});
}
};
</script>
<-- Composition API를 더 간결하고 선언적으로 사용하는 방식 -->
<script setup>
import { defineExpose } from 'vue';
const someInternalMethod = () => {
// 내부 메서드 로직
};
// someInternalMethod를 컴포넌트의 public 메서드로 노출
defineExpose({
someInternalMethod
});
</script>
몰랐던 개념 정리
스테이트 풀 객체란?
- 반응성: Vue의 반응형 시스템에 의해 상태 변화가 추적되고 해당 상태에 의존하는 컴포넌트나 계산된 속성이 자동으로 업데이트
- 변경 가능성: 객체의 상태는 외부 상호작용(사용자 입력, API 호출 등)에 의해 변경 가