Типизация компонентов является важной частью разработки крупных приложений на Vue.js. Она позволяет повысить надёжность кода, снизить количество ошибок и улучшить поддержку автодополнения в IDE. В современных версиях Vue.js типизация достигается как с помощью встроенных возможностей фреймворка, так и с использованием TypeScript.
Props — это входные параметры компонентов. Они могут иметь строгие типы, что помогает избежать передачи некорректных данных.
export default {
props: {
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
},
isActive: Boolean
}
}
Ключевые моменты:
type определяет допустимый тип пропса
(String, Number, Boolean,
Array, Object, Function,
Symbol).required указывает на обязательность пропса.default задаёт значение по умолчанию.validator:props: {
age: {
type: Number,
validator: value => value >= 0 && value <= 120
}
}
В TypeScript можно дополнительно указать тип пропса через интерфейсы:
interface UserProps {
name: string;
age?: number;
}
export default defineComponent({
props: {
name: String,
age: Number
} as PropType<UserProps>
});
События компонентов (emit) также поддаются типизации. В
Vue 3 используется функция defineEmits:
const emit = defineEmits<{
(e: 'update', value: string): void;
(e: 'delete', id: number): void;
}>();
emit('update', 'новое значение');
emit('delete', 123);
Особенности:
emit соответствует
объявленным типам.Слоты в Vue.js позволяют передавать в компонент разметку с пользовательскими данными. Типизация слотов обеспечивает контроль передаваемых свойств:
const slots = defineSlots<{
default: { message: string };
header: {};
}>();
Использование типизированного слота в шаблоне:
<template #default="{ message }">
<p>{{ message }}</p>
</template>
default и header — имена слотов.{ message: string } — набор доступных данных для
слота.Компоненты Vue.js активно используют реактивные состояния. В
TypeScript для типизации реактивных данных применяются ref
и reactive:
import { ref, reactive } from 'vue';
const count = ref<number>(0);
const user = reactive<{
name: string;
age: number;
}>({
name: 'Иван',
age: 25
});
Важные моменты:
ref<Type>(initialValue) создаёт реактивное
примитивное значение.reactive<Type>(initialObject) создаёт реактивный
объект с указанными типами свойств.defineComponent с типамиДля больших компонентов удобно использовать функцию
defineComponent, которая объединяет props, emits, slots и
setup с полной поддержкой TypeScript:
import { defineComponent, PropType } from 'vue';
export default defineComponent({
props: {
title: {
type: String as PropType<string>,
required: true
},
tags: {
type: Array as PropType<string[]>,
default: () => []
}
},
emits: ['save', 'cancel'],
setup(props, { emit }) {
const handleSave = () => emit('save');
const handleCancel = () => emit('cancel');
return { handleSave, handleCancel };
}
});
PropType<T> позволяет точно указывать
сложные типы пропсов.Vue.js поддерживает регистрацию компонентов с типизацией для глобального использования. Это позволяет избежать ошибок при динамическом рендеринге:
declare module '@vue/runtime-core' {
export interface GlobalComponents {
MyButton: typeof import('./components/MyButton.vue').default;
}
}
После объявления TypeScript понимает, что
<MyButton /> доступен во всех шаблонах без явного
импорта.
Компоненты часто используют composables для логики состояния. Типизация таких функций обеспечивает строгий контроль:
function useCounter(initialValue: number) {
const count = ref(initialValue);
const increment = () => count.value++;
return { count, increment };
}
const { count, increment } = useCounter(0);
ref<number> гарантирует, что
count.value всегда число.Типизация компонентов становится особенно важной при работе с глобальными состояниями:
Pinia:
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
name: '' as string,
age: 0 as number
}),
actions: {
setName(name: string) {
this.name = name;
}
}
});
Компонент:
const userStore = useUserStore();
userStore.setName('Иван');
Типизация компонентов во Vue.js существенно повышает стабильность приложений и упрощает разработку крупных проектов. Она охватывает props, события, слоты, реактивные данные, composables и глобальные компоненты, а использование TypeScript делает проверку типов максимально строгой и безопасной.