Композиционный API — это новый способ организации логики компонентов во Vue.js, представленный в версии 3.0. Он предоставляет более гибкий подход к созданию и переиспользованию компонентной логики
Setup функция
Setup функция является точкой входа для Композиционного API. Она выполняется до создания компонента, когда определяются реактивные свойства и функции
export default {
setup(props, context) {
// Здесь определяется логика компонента
return {
// Возвращаем данные, которые будут доступны в шаблоне
}
}
}
Параметры setup
- props: реактивный объект, содержащий входные параметры компонента
- context: объект, содержащий attrs, slots, emit и expose
export default {
setup(props, { attrs, slots, emit, expose }) {
// Использование контекста
const handleClick = () => {
emit('custom-event', 'Hello!')
}
return { handleClick }
}
}
Реактивные ссылки (ref) и reactive
ref
Ref используется для создания реактивной ссылки на примитивные значения:
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
const increment = () => {
count.value++ // Важно использовать .value для изменения значения
}
return { count, increment }
}
}
reactive
Reactive создает реактивный объект:
import { reactive } from 'vue'
export default {
setup() {
const state = reactive({
user: {
name: 'John',
age: 25
},
posts: []
})
const updateUser = () => {
state.user.name = 'Jane' // Не требуется .value
}
return { state, updateUser }
}
}
Методы жизненного цикла
В Композиционном API хуки жизненного цикла доступны через специальные функции:
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('Компонент смонтирован')
})
onUpdated(() => {
console.log('Компонент обновлен')
})
onUnmounted(() => {
console.log('Компонент размонтирован')
})
}
}
Computed и Watch
Computed свойства
import { ref, computed } from 'vue'
export default {
setup() {
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`
})
return { firstName, lastName, fullName }
}
}
Watch
import { ref, watch } from 'vue'
export default {
setup() {
const searchQuery = ref('')
watch(searchQuery, (newValue, oldValue) => {
console.log('Search query changed:', newValue)
// Выполнить поиск
})
return { searchQuery }
}
}
Provide/Inject
Механизм для передачи данных через несколько уровней компонентов:
// Родительский компонент
import { provide, ref } from 'vue'
export default {
setup() {
const theme = ref('dark')
provide('theme', theme)
}
}
// Дочерний компонент
import { inject } from 'vue'
export default {
setup() {
const theme = inject('theme')
return { theme }
}
}
Создание пользовательских композиционных функций
Композиционные функции позволяют переиспользовать логику между компонентами:
// useCounter.js
import { ref } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
return {
count,
increment,
decrement
}
}
// Использование в компоненте
import { useCounter } from './useCounter'
export default {
setup() {
const { count, increment, decrement } = useCounter(10)
return { count, increment, decrement }
}
}
Практический пример: Создание формы с валидацией
// useForm.js
import { reactive, computed } from 'vue'
export function useForm(initialState = {}) {
const form = reactive(initialState)
const errors = reactive({})
const validate = () => {
errors.name = form.name?.length < 3 ? 'Имя должно быть длиннее 3 символов' : ''
errors.email = !form.email?.includes('@') ? 'Некорректный email' : ''
return Object.values(errors).every(error => !error)
}
const isValid = computed(() => Object.values(errors).every(error => !error))
return {
form,
errors,
validate,
isValid
}
}
// Использование в компоненте
<template>
<form @submit.prevent="handleSubmit">
<input v-model="form.name" placeholder="Name">
<span v-if="errors.name" class="error">{{ errors.name }}</span>
<input v-model="form.email" placeholder="Email">
<span v-if="errors.email" class="error">{{ errors.email }}</span>
<button :disabled="!isValid">Submit</button>
</form>
</template>
<script>
import { useForm } from './useForm'
export default {
setup() {
const { form, errors, validate, isValid } = useForm({
name: '',
email: ''
})
const handleSubmit = () => {
if (validate()) {
// Отправка формы
console.log('Form submitted:', form)
}
}
return {
form,
errors,
isValid,
handleSubmit
}
}
}
</script>
Это базовое руководство по Композиционному API. Каждый раздел можно расширить дополнительными примерами и случаями использования в зависимости от потребностей обучающихся
Еще больше уроков для изучения Vue