다음 구성 요소에는 두 개의 소품(표시 및 플래그)이 있습니다. 다른 구성 요소를 통해 이 두 prop을 기반으로 템플릿에 표시되는 조랑말 이미지의 URL을 계산합니다. 또한 구성 요소는 사용자가 클릭할 때 이벤트를 발생시킵니다. 포니포니 모델이 실행되는 동안 선택된 이미지입니다.
Pony.vue
<template> <figure @click="clicked()"> <Image :src="ponyImageUrl" :alt="ponyModel.name" /> <figcaption>{{ ponyModel.name }}</figcaption> </figure> </template> <script lang="ts"> import { computed, defineComponent, PropType } from 'vue'; import Image from './Image.vue'; import { PonyModel } from '@/models/PonyModel'; export default defineComponent({ components: { Image }, props: { ponyModel: { type: Object as PropType<PonyModel>, required: true }, isRunning: { type: Boolean, default: false } }, emits: { selected: () => true }, setup(props, { emit }) { const ponyImageUrl = computed(() => `/pony-${props.ponyModel.color}${props.isRunning ? '-running' : ''}.gif`); function clicked() { emit('selected'); } return { ponyImageUrl, clicked }; } }); </script>
첫 번째 단계는 요소에 속성을 추가하는 것입니다. 그런 다음 함수의 내용만 유지하면 됩니다. 모든 상용구는 사라질 수 있습니다. 다음에서 함수를 제거할 수 있습니다. setupscriptsetupdefineComponentsetupscript
Pony.vue
<script setup lang="ts"> import { computed, PropType } from 'vue'; import Image from './Image.vue'; import { PonyModel } from '@/models/PonyModel'; components: { Image }, props: { ponyModel: { type: Object as PropType<PonyModel>, required: true }, isRunning: { type: Boolean, default: false } }, emits: { selected: () => true }, const ponyImageUrl = computed(() => `/pony-${props.ponyModel.color}${props.isRunning ? '-running' : ''}.gif`); function clicked() { emit('selected'); } return { ponyImageUrl, clicked }; </script>
끝에서 최상위 바인딩 선언과 import 문을 제거하면 자동으로 템플릿에서 사용할 수 있게 됩니다. 따라서 여기에서 사용할 수 있으므로 반환할 필요가 없습니다. 포니 이미지를 클릭하면 스크립트가 반환됩니다.
이 문장은 다음과 같이 다시 작성할 수 있습니다. "컴포넌트를 가져오기만 하면 Vue가 템플릿에서 해당 사용을 자동으로 인식하므로 선언을 생략할 수 있습니다." ComponentsImagecomComponents
Pony.vue
<script setup lang="ts"> import { computed, PropType } from 'vue'; import Image from './Image.vue'; import { PonyModel } from '@/models/PonyModel'; props: { ponyModel: { type: Object as PropType<PonyModel>, required: true }, isRunning: { type: Boolean, default: false } }, emits: { selected: () => true }, const ponyImageUrl = computed(() => `/pony-${props.ponyModel.color}${props.isRunning ? '-running' : ''}.gif`); function clicked() { emit('selected'); } </script>
거의 다 왔습니다. 이제 마이그레이션하고 선언해야 합니다. propsmits
Vue는 소품을 정의하는 데 사용할 수 있는 도우미를 제공합니다. 이는 컴파일 시간 도우미(매크로)이므로 코드에서 가져올 필요가 없습니다. Vue는 컴포넌트를 컴파일할 때 자동으로 인식합니다. DefineProps
defineProps는 props를 반환합니다.
const props = defineProps({ ponyModel: { type: Object as PropType<PonyModel>, required: true }, isRunning: { type: Boolean, default: false } });
defineProps는 이전 선언을 매개변수로 받습니다. 하지만 TypeScript 사용자를 위해 더 나은 서비스를 제공할 수 있습니다! props
defineProps는 일반적으로 유형이 지정됩니다. 매개변수 없이 호출할 수 있지만 인터페이스를 prop의 "모양"으로 지정합니다. 쓰기에 더 끔찍한 것은 없습니다! 올바른 TypeScript 유형을 사용하고 ????를 추가하여 prop을 불필요한 것으로 표시할 수 있습니다. 좀 더 유창한 언어로 다시 작성했습니다. "Object가 Props 유형으로 사용될 때 특정 유형을 지정해야 합니까?"
const props = defineProps<{ ponyModel: PonyModel; isRunning?: boolean; }>();
하지만 일부 정보가 손실되었습니다. 이전 버전에서는 기본값을 . Emits
defineEmits
interface Props { ponyModel: PonyModel; isRunning?: boolean; } const props = withDefaults(defineProps<Props>(), { isRunning: false });
또는 TypeScript를 사용하는 것이 더 좋습니다.
const emit = defineEmits({ selected: () => true });
전체 구성 요소 선언은 10줄 더 짧습니다. 부품 30줄을 줄여도 나쁘지 않네요! 이렇게 하면 가독성이 향상되고 TypeScript에서 더 잘 작동합니다. 모든 것이 템플릿에 자동으로 노출된다는 것이 조금 이상하게 느껴지지만 줄바꿈이 없기 때문에 익숙해질 것입니다.
Pony.vue
const emit = defineEmits<{ (e: 'selected'): void; }>();
Default off 및 DefineExpose
예를 들어, 다음 장에서는 컴포넌트가 (refs를 사용하여) 다른 컴포넌트에 액세스할 수 있음을 살펴보겠습니다. 함수가 XX로 정의되면 함수에서 반환된 모든 콘텐츠가 상위 구성 요소 YY에도 표시됩니다. 로 정의하면 상위 구성요소가 표시되지 않습니다. 헬퍼를 추가하여 노출된 컨텐츠를 선택할 수 있습니다. 그러면 공개 항목에 . PonyImageImagedefineComponentsetupPonyImagescript setupImagedefineExpose({ 키: 값 })valuekey
위 내용은 Vue3에서