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