3. vue version 3.3
- props destructuring
- defineModel
- better TS support
- ... and more !!
1. props destructuring / default value
props
를 destructuring
하면서 default value
도 세팅할 수 있다.
// version 3.3
const { msg = 'default val', name } = defineProps<{
msg?: string;
name?: string;
}>();
// before
const props = defineProps<{
msg?: string;
name?: string;
}>()
// for default value // before
const props = withDefaults(
defineProps<{
msg?: string;
name?: string
}>(),
{
msg: 'subscribe',
name: 'hyungju-lee',
}
)
// for default value // for destructuring // for reactive // before
const { msg, name } = toRefs(
withDefaults(
defineProps<{
msg?: string;
name?: string
}>(),
{
msg: 'subscribe',
name: 'hyungju-lee',
}
)
)
// version 3.3
const { msg = 'subscribe', name = 'hyungju-lee' } = defineProps<{
msg?: string;
name?: string;
}>();
2. defineModel
defineModel
<script setup lang="ts">
const modelValue = defineModel<string>();
</script>
<template>
<div>
<input type="text" v-model="modelValue">
</div>
</template>
defineModel-principle
<script setup lang="ts">
const props = defineProps<{
modelValue: string;
}>();
const emits = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
const modelValue = computed({
get() {
return props.modelValue;
},
set(value) {
emits('update:modelValue', value);
}
})
</script>
3. export define props
types.d.ts
export type BaseProps = {
testId: string
}
ExternalTypes.vue
<script setup lang="ts">
import type { BaseProps } from "../types";
const { msg, testId } = defineProps<BaseProps & {
msg: string;
}>();
</script>
<template>
{{ msg }}
{{ testId }}
</template>
App.vue
<script setup lang="ts">
import ExternalTypes from './components/ExternalTypes.vue';
</script>
<template>
<div class="w-full max-w-xl mx-auto py-32">
<h2 class="mt-16 text-2xl font-bold mb-4">External Types</h2>
<ExternalTypes msg="hello" testId="imported type!" />
</div>
</template>
4. generic
<script setup lang="ts" generic="T">
defineProps<{
items: T[]
}>();
</script>
GenericList.vue
<script setup lang="ts" generic="T">
defineProps<{
items: T[];
keyField: keyof T;
}>();
defineEmits<{
(e: 'delete', item: T): void
}>();
</script>
<template>
<ul class="flex flex-col">
<li
v-for="item in items"
:key="String(item[keyField as keyof T])"
class="flex items-center"
>
<button @click="$emit('delete', item)" class="text-red-500">
<IconAccountBox />
</button>
<slot :item="item"></slot>
</li>
</ul>
</template>
App.vue
<script setup lang="ts">
const items = ref([
{ _id: '1', name: 'Matt' },
{ _id: '2', name: 'hyungju-lee' },
{ _id: '3', name: 'John' },
])
</script>
<template>
<GenericList
:items="items"
key-field="_id"
@delete="(item) => console.log(`do something with id: ${item._id}`)"
>
<template #default="{ item }">item - {{ item._id }}</template>
</GenericList>
</template>