add template component
This commit is contained in:
parent
200704bf92
commit
365a231ed5
90
src/components/template.vue
Normal file
90
src/components/template.vue
Normal file
@ -0,0 +1,90 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
// Интерфейсы и типы
|
||||
export interface Todo {
|
||||
id: number
|
||||
title: string
|
||||
completed: boolean
|
||||
priority: 'low' | 'medium' | 'high'
|
||||
createdAt: Date
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
// Тип для пропсов
|
||||
interface Props {
|
||||
todo: Todo
|
||||
showPriority?: boolean
|
||||
index?: number
|
||||
}
|
||||
|
||||
// Тип для событий
|
||||
interface Emits {
|
||||
(e: 'update', todo: Todo): void
|
||||
(e: 'delete', id: number): void
|
||||
(e: 'click', index: number): void
|
||||
}
|
||||
|
||||
// Определение пропсов с типами
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
showPriority: true,
|
||||
index: 0
|
||||
})
|
||||
|
||||
// Определение событий с типами
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
// Реактивные данные с типами
|
||||
// const isHovered = ref<boolean>(false)
|
||||
const clickCount = ref<number>(0)
|
||||
|
||||
// Вычисляемые свойства с типами
|
||||
const priorityClass = computed((): string => {
|
||||
const priorityMap = {
|
||||
low: 'priority-low',
|
||||
medium: 'priority-medium',
|
||||
high: 'priority-high'
|
||||
}
|
||||
return priorityMap[props.todo.priority]
|
||||
})
|
||||
|
||||
// Методы с типами
|
||||
const handleClick = (event: MouseEvent): void => {
|
||||
clickCount.value++
|
||||
emit('click', props.index)
|
||||
console.log(`Клик #${clickCount.value}`, event)
|
||||
}
|
||||
|
||||
const toggleComplete = (event: Event): void => {
|
||||
const input = event.target as HTMLInputElement
|
||||
const updatedTodo: Todo = {
|
||||
...props.todo,
|
||||
completed: input.checked
|
||||
}
|
||||
emit('update', updatedTodo)
|
||||
}
|
||||
|
||||
const deleteTodo = (): void => {
|
||||
emit('delete', props.todo.id)
|
||||
}
|
||||
|
||||
// Типизированные watchers
|
||||
watch(() => props.todo.completed, (newValue: boolean, oldValue: boolean) => {
|
||||
console.log(`Статус изменен: ${oldValue} -> ${newValue}`)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="todo-item" :class="{ completed: todo.completed }" @click="handleClick">
|
||||
<input type="checkbox" :checked="todo.completed" @change="toggleComplete" />
|
||||
<span>{{ todo.title }}</span>
|
||||
<span class="priority" :class="priorityClass">
|
||||
{{ todo.priority }}
|
||||
</span>
|
||||
<button @click.stop="deleteTodo">Удалить</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* стили компонента */
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user